From 1f144644d77e53b007fc5dc2fb39a2a42fe2be1b Mon Sep 17 00:00:00 2001 From: CptMoore <39010654+cptmoore@users.noreply.github.com> Date: Fri, 28 Feb 2025 22:29:16 +0100 Subject: [PATCH] Undo perf improvements for customs access. --- source/CustomComponents/CCLight/Database.cs | 96 ++++++++----------- source/CustomComponents/CCLight/Extensions.cs | 45 ++++----- source/CustomComponents/CCLight/Registry.cs | 2 +- 3 files changed, 58 insertions(+), 85 deletions(-) diff --git a/source/CustomComponents/CCLight/Database.cs b/source/CustomComponents/CCLight/Database.cs index b9bc7a2..71f6963 100644 --- a/source/CustomComponents/CCLight/Database.cs +++ b/source/CustomComponents/CCLight/Database.cs @@ -8,56 +8,42 @@ namespace CustomComponents; public class Database { - internal static bool AddCustom(string identifier, object target, ICustom cc) + internal static T GetCustom(object target) { - ref var customs = ref DefToCustoms(target); - return AddCustomInternal(identifier, ref customs, cc); - } - private static ref object[] DefToCustoms(object target) - { - switch (target) + var identifier = Identifier(target); + + if (identifier == null) { - case MechComponentDef def1: - return ref def1.ccCustoms; - case MechDef def2: - return ref def2.ccCustoms; - case ChassisDef def3: - return ref def3.ccCustoms; - case VehicleChassisDef def4: - return ref def4.ccCustoms; - default: - throw new ArgumentException(); + return default; } - } - internal static bool AddCustom(string identifier, ref object[] customs, ICustom cc) - { - return AddCustomInternal(identifier, ref customs, cc); - } + if (!Customs.TryGetValue(identifier, out var customs)) + { + return default; + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static IEnumerable GetCustoms(object[] customs) - { - return GetCustomsInternal(customs); - } + for (var index = 0; index < customs.Length; index++) + { + if (customs[index] is T csT) + { + return csT; + } + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static T GetCustom(object[] customs) - { - return GetCustomInternalFast(customs); + return default; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool Is(object[] customs, out T value) + internal static bool Is(object target, out T value) { - value = GetCustom(customs); + value = GetCustom(target); return value != null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool Is(object[] customs) + internal static bool Is(object target) { - return GetCustom(customs) != null; + return GetCustom(target) != null; } internal static string Identifier(object target) @@ -77,10 +63,16 @@ internal static string Identifier(object target) }; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static IEnumerable GetCustomsInternal(object[] customs) + internal static IEnumerable GetCustoms(object target) { - if (customs == null) + var identifier = Identifier(target); + + if (identifier == null) + { + yield break; + } + + if (!Customs.TryGetValue(identifier, out var customs)) { yield break; } @@ -94,28 +86,18 @@ private static IEnumerable GetCustomsInternal(object[] customs) } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static T GetCustomInternalFast(object[] customs) + private static readonly Dictionary Customs = new(StringComparer.Ordinal); + internal static bool AddCustom(object target, ICustom cc) { - if (customs == null) - { - return default; - } - - for (var index = 0; index < customs.Length; index++) + var identifier = Identifier(target); + if (identifier == null) { - if (customs[index] is T csT) - { - return csT; - } + return false; } - return default; - } + Customs.TryGetValue(identifier, out var customs); - private static bool AddCustomInternal(string identifier, ref object[] customs, ICustom cc) - { - Log.CCLoading.Trace?.Log($"{nameof(AddCustomInternal)} identifier={identifier} cc={cc} cc.type={cc.GetType()}"); + Log.CCLoading.Trace?.Log($"{nameof(AddCustom)} identifier={identifier} cc={cc} cc.type={cc.GetType()}"); var attribute = GetAttributeByType(cc.GetType()); Log.CCLoading.Trace?.Log($"--{nameof(CustomComponentAttribute)} {nameof(attribute.Name)}={attribute.Name} {nameof(attribute.AllowArray)}={attribute.AllowArray}"); @@ -137,14 +119,14 @@ private static bool AddCustomInternal(string identifier, ref object[] customs, I Log.CCLoading.Trace?.Log("--added"); if (customs == null) { - customs = [cc]; + Customs[identifier] = [cc]; } else { var newCustoms = new object[customs.Length + 1]; Array.Copy(customs, newCustoms, customs.Length); newCustoms[customs.Length] = cc; - customs = newCustoms; + Customs[identifier] = newCustoms; } return true; } diff --git a/source/CustomComponents/CCLight/Extensions.cs b/source/CustomComponents/CCLight/Extensions.cs index 0f1eb9d..3660091 100644 --- a/source/CustomComponents/CCLight/Extensions.cs +++ b/source/CustomComponents/CCLight/Extensions.cs @@ -14,34 +14,25 @@ public static class MechComponentDefExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T GetComponent(this MechComponentDef target) { - return Database.GetCustom(target.ccCustoms); + return Database.GetCustom(target); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable GetComponents(this MechComponentDef target) { - return Database.GetCustoms(target.ccCustoms); + return Database.GetCustoms(target); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this MechComponentDef target, out T res) { - // strongly used during combat/ai due to ME ignore_damage - // TODO migrate combat related flags to dedicated SimpleInjector fields - // requires changes in calling mods! - if (typeof(T) == typeof(Flags)) - { - res = (T)target.ccFlags; - return res != null; - } - - return Database.Is(target.ccCustoms, out res); + return Database.Is(target, out res); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this MechComponentDef target) { - return Database.Is(target.ccCustoms); + return Database.Is(target); } public static T AddComponent(this MechComponentDef target, T component) where T : ICustom @@ -50,7 +41,7 @@ public static T AddComponent(this MechComponentDef target, T component) where { simple.Def = target; } - Database.AddCustom(target.Description.Id, ref target.ccCustoms, component); + Database.AddCustom(target, component); return component; } @@ -70,25 +61,25 @@ public static class VehicleExtentions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T GetComponent(this VehicleChassisDef target) { - return Database.GetCustom(target.ccCustoms); + return Database.GetCustom(target); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable GetComponents(this VehicleChassisDef target) { - return Database.GetCustoms(target.ccCustoms); + return Database.GetCustoms(target); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this VehicleChassisDef target, out T res) { - return Database.Is(target.ccCustoms, out res); + return Database.Is(target, out res); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this VehicleChassisDef target) { - return Database.Is(target.ccCustoms); + return Database.Is(target); } } @@ -97,25 +88,25 @@ public static class MechDefExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T GetComponent(this MechDef target) { - return Database.GetCustom(target.ccCustoms); + return Database.GetCustom(target); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable GetComponents(this MechDef target) { - return Database.GetCustoms(target.ccCustoms); + return Database.GetCustoms(target); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this MechDef target, out T res) { - return Database.Is(target.ccCustoms, out res); + return Database.Is(target, out res); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this MechDef target) { - return Database.Is(target.ccCustoms); + return Database.Is(target); } public static bool IsBroken(this MechDef def) @@ -159,25 +150,25 @@ public static class ChassisDefExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T GetComponent(this ChassisDef target) { - return Database.GetCustom(target.ccCustoms); + return Database.GetCustom(target); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable GetComponents(this ChassisDef target) { - return Database.GetCustoms(target.ccCustoms); + return Database.GetCustoms(target); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this ChassisDef target, out T res) { - return Database.Is(target.ccCustoms, out res); + return Database.Is(target, out res); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Is(this ChassisDef target) { - return Database.Is(target.ccCustoms); + return Database.Is(target); } public static T AddComponent(this ChassisDef target, T component) where T : ICustom @@ -186,7 +177,7 @@ public static T AddComponent(this ChassisDef target, T component) where T : I { simple.Def = target; } - Database.AddCustom(target.Description.Id, ref target.ccCustoms, component); + Database.AddCustom(target, component); return component; } diff --git a/source/CustomComponents/CCLight/Registry.cs b/source/CustomComponents/CCLight/Registry.cs index 39859d7..e941387 100644 --- a/source/CustomComponents/CCLight/Registry.cs +++ b/source/CustomComponents/CCLight/Registry.cs @@ -189,7 +189,7 @@ private static void ProcessCustomFactory( Log.CCLoading.Trace?.Log($"Created {component} for {identifier}"); - if (Database.AddCustom(identifier, target, component)) + if (Database.AddCustom(target, component)) { if (component is IAfterLoad load) {