Skip to content

Commit

Permalink
Undo perf improvements for customs access.
Browse files Browse the repository at this point in the history
  • Loading branch information
CptMoore committed Feb 28, 2025
1 parent 8a5b0dd commit 1f14464
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 85 deletions.
96 changes: 39 additions & 57 deletions source/CustomComponents/CCLight/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,56 +8,42 @@ namespace CustomComponents;

public class Database
{
internal static bool AddCustom(string identifier, object target, ICustom cc)
internal static T GetCustom<T>(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<T> GetCustoms<T>(object[] customs)
{
return GetCustomsInternal<T>(customs);
}
for (var index = 0; index < customs.Length; index++)
{
if (customs[index] is T csT)
{
return csT;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T GetCustom<T>(object[] customs)
{
return GetCustomInternalFast<T>(customs);
return default;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool Is<T>(object[] customs, out T value)
internal static bool Is<T>(object target, out T value)
{
value = GetCustom<T>(customs);
value = GetCustom<T>(target);
return value != null;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool Is<T>(object[] customs)
internal static bool Is<T>(object target)
{
return GetCustom<T>(customs) != null;
return GetCustom<T>(target) != null;
}

internal static string Identifier(object target)
Expand All @@ -77,10 +63,16 @@ internal static string Identifier(object target)
};
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static IEnumerable<T> GetCustomsInternal<T>(object[] customs)
internal static IEnumerable<T> GetCustoms<T>(object target)
{
if (customs == null)
var identifier = Identifier(target);

if (identifier == null)
{
yield break;
}

if (!Customs.TryGetValue(identifier, out var customs))
{
yield break;
}
Expand All @@ -94,28 +86,18 @@ private static IEnumerable<T> GetCustomsInternal<T>(object[] customs)
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static T GetCustomInternalFast<T>(object[] customs)
private static readonly Dictionary<string, object[]> 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}");
Expand All @@ -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;
}
Expand Down
45 changes: 18 additions & 27 deletions source/CustomComponents/CCLight/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,25 @@ public static class MechComponentDefExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T GetComponent<T>(this MechComponentDef target)
{
return Database.GetCustom<T>(target.ccCustoms);
return Database.GetCustom<T>(target);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IEnumerable<T> GetComponents<T>(this MechComponentDef target)
{
return Database.GetCustoms<T>(target.ccCustoms);
return Database.GetCustoms<T>(target);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Is<T>(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<T>(this MechComponentDef target)
{
return Database.Is<T>(target.ccCustoms);
return Database.Is<T>(target);
}

public static T AddComponent<T>(this MechComponentDef target, T component) where T : ICustom
Expand All @@ -50,7 +41,7 @@ public static T AddComponent<T>(this MechComponentDef target, T component) where
{
simple.Def = target;
}
Database.AddCustom(target.Description.Id, ref target.ccCustoms, component);
Database.AddCustom(target, component);
return component;
}

Expand All @@ -70,25 +61,25 @@ public static class VehicleExtentions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T GetComponent<T>(this VehicleChassisDef target)
{
return Database.GetCustom<T>(target.ccCustoms);
return Database.GetCustom<T>(target);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IEnumerable<T> GetComponents<T>(this VehicleChassisDef target)
{
return Database.GetCustoms<T>(target.ccCustoms);
return Database.GetCustoms<T>(target);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Is<T>(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<T>(this VehicleChassisDef target)
{
return Database.Is<T>(target.ccCustoms);
return Database.Is<T>(target);
}
}

Expand All @@ -97,25 +88,25 @@ public static class MechDefExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T GetComponent<T>(this MechDef target)
{
return Database.GetCustom<T>(target.ccCustoms);
return Database.GetCustom<T>(target);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IEnumerable<T> GetComponents<T>(this MechDef target)
{
return Database.GetCustoms<T>(target.ccCustoms);
return Database.GetCustoms<T>(target);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Is<T>(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<T>(this MechDef target)
{
return Database.Is<T>(target.ccCustoms);
return Database.Is<T>(target);
}

public static bool IsBroken(this MechDef def)
Expand Down Expand Up @@ -159,25 +150,25 @@ public static class ChassisDefExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T GetComponent<T>(this ChassisDef target)
{
return Database.GetCustom<T>(target.ccCustoms);
return Database.GetCustom<T>(target);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IEnumerable<T> GetComponents<T>(this ChassisDef target)
{
return Database.GetCustoms<T>(target.ccCustoms);
return Database.GetCustoms<T>(target);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Is<T>(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<T>(this ChassisDef target)
{
return Database.Is<T>(target.ccCustoms);
return Database.Is<T>(target);
}

public static T AddComponent<T>(this ChassisDef target, T component) where T : ICustom
Expand All @@ -186,7 +177,7 @@ public static T AddComponent<T>(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;
}

Expand Down
2 changes: 1 addition & 1 deletion source/CustomComponents/CCLight/Registry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Check warning on line 194 in source/CustomComponents/CCLight/Registry.cs

View workflow job for this annotation

GitHub Actions / build / mod-builder

'IAfterLoad' is obsolete: 'Use IOnLoaded'

Check warning on line 194 in source/CustomComponents/CCLight/Registry.cs

View workflow job for this annotation

GitHub Actions / build / mod-builder

'IAfterLoad' is obsolete: 'Use IOnLoaded'

Check warning on line 194 in source/CustomComponents/CCLight/Registry.cs

View workflow job for this annotation

GitHub Actions / build / mod-builder

'IAfterLoad' is obsolete: 'Use IOnLoaded'

Check warning on line 194 in source/CustomComponents/CCLight/Registry.cs

View workflow job for this annotation

GitHub Actions / build / mod-builder

'IAfterLoad' is obsolete: 'Use IOnLoaded'
{
Expand Down

0 comments on commit 1f14464

Please sign in to comment.