Added gas grid optimization, various despawn optimizations, new hauling optimizations utilizing events and regions, bugfixes for old patches and for vanilla functions too, as well as smaller additions. 1.3 files removed.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
// Copyright (c) 2023 bradson
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using Mono.Cecil.Rocks;
|
||||
using PerformanceFish.Prepatching;
|
||||
using FieldAttributes = Mono.Cecil.FieldAttributes;
|
||||
using MethodImplAttributes = Mono.Cecil.MethodImplAttributes;
|
||||
|
||||
namespace PerformanceFish.Defs;
|
||||
|
||||
public sealed class ThingDefPatches : ClassWithFishPrepatches
|
||||
{
|
||||
public const string FISH_HASH_FIELD_NAME = "FishHash";
|
||||
|
||||
public sealed class GetHashCodePatch : FishClassPrepatch
|
||||
{
|
||||
public override string? Description { get; }
|
||||
= "Def.GetHashCode is overridden to return defName.GetHashCode, which is rather slow as that's a string. "
|
||||
+ "This patch caches the hashcode in a field added through prepatcher and simply returns that instead.";
|
||||
|
||||
public override Type Type { get; } = typeof(BuildableDef);
|
||||
|
||||
public override void FreePatch(TypeDefinition typeDefinition)
|
||||
{
|
||||
var module = typeDefinition.Module;
|
||||
|
||||
var fishHashField = new FieldDefinition(FISH_HASH_FIELD_NAME, FieldAttributes.Private,
|
||||
module.TypeSystem.Int32);
|
||||
|
||||
typeDefinition.Fields.Insert(0, fishHashField);
|
||||
|
||||
var constructorBody = typeDefinition.GetConstructors().First().Body;
|
||||
|
||||
constructorBody.GetILProcessor().InsertRange(constructorBody.Instructions.Count - 2,
|
||||
OpCodes.Ldarg_0,
|
||||
(OpCodes.Ldc_I4, -42),
|
||||
(OpCodes.Stfld, fishHashField));
|
||||
|
||||
constructorBody.OptimizeMacros();
|
||||
|
||||
var getHashCodeBody = typeDefinition.GetMethod(nameof(BuildableDef.GetHashCode))!.Body;
|
||||
|
||||
var variables = getHashCodeBody.Variables;
|
||||
variables.Clear();
|
||||
|
||||
var hashVariable = new VariableDefinition(module.TypeSystem.Int32);
|
||||
variables.Add(hashVariable);
|
||||
|
||||
var instructions = getHashCodeBody.Instructions;
|
||||
instructions.Clear();
|
||||
|
||||
var ilProcessor = getHashCodeBody.GetILProcessor();
|
||||
ilProcessor.InsertRange(0,
|
||||
OpCodes.Ldarg_0,
|
||||
(OpCodes.Ldfld, fishHashField),
|
||||
(OpCodes.Stloc, hashVariable),
|
||||
(OpCodes.Ldloc, hashVariable),
|
||||
(OpCodes.Ldc_I4, -42),
|
||||
// 5 bne_un_s ^2
|
||||
OpCodes.Ldarg_0,
|
||||
(OpCodes.Call, methodof(CreateLongHash)),
|
||||
OpCodes.Ret,
|
||||
(OpCodes.Ldloc, hashVariable),
|
||||
OpCodes.Ret);
|
||||
|
||||
ilProcessor.InsertAt(5, OpCodes.Bne_Un_S, instructions[^2]);
|
||||
|
||||
getHashCodeBody.MaxStackSize = 2;
|
||||
getHashCodeBody.Method.ImplAttributes |= MethodImplAttributes.AggressiveInlining;
|
||||
getHashCodeBody.OptimizeMacros();
|
||||
}
|
||||
|
||||
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
// public static int ReplacementBody(BuildableDef instance)
|
||||
// {
|
||||
// var hash = instance.FishHash;
|
||||
// return hash != -42 ? hash : CreateLongHash(instance);
|
||||
// }
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static int CreateLongHash(BuildableDef instance)
|
||||
{
|
||||
var defName = instance.defName;
|
||||
if (defName is null)
|
||||
return 0;
|
||||
|
||||
var defHash = defName.GetHashCode();
|
||||
if (defName is "" or Def.DefaultDefName)
|
||||
return defHash;
|
||||
|
||||
ref var cacheHash = ref Lazy.FishHashField(instance);
|
||||
cacheHash = defHash != -42 ? defHash : defHash + 1;
|
||||
return cacheHash;
|
||||
}
|
||||
|
||||
private static class Lazy
|
||||
{
|
||||
internal static readonly AccessTools.FieldRef<BuildableDef, int> FishHashField
|
||||
= AccessTools.FieldRefAccess<BuildableDef, int>(FISH_HASH_FIELD_NAME);
|
||||
|
||||
static Lazy()
|
||||
{
|
||||
// prevent beforefieldinit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user