mirror of
https://github.com/NuclearPowered/Reactor.git
synced 2026-10-19 15:51:54 +00:00
Use typed delegates for faster invoke
This commit is contained in:
1 parent
6381d79a18
commit
c3775ff33f
1 file changed
+49
-12
@@ -25,6 +25,16 @@ public class CompilerGeneratedObjectWrapper
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected Dictionary<string, PropertyInfo> PropertyCache { get; }
|
protected Dictionary<string, PropertyInfo> PropertyCache { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the getter cache for faster property access.
|
||||||
|
/// </summary>
|
||||||
|
protected Dictionary<string, Delegate> GetterCache { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the setter cache for faster property access.
|
||||||
|
/// </summary>
|
||||||
|
protected Dictionary<string, Delegate> SetterCache { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="CompilerGeneratedObjectWrapper"/> class.
|
/// Initializes a new instance of the <see cref="CompilerGeneratedObjectWrapper"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -35,6 +45,31 @@ public class CompilerGeneratedObjectWrapper
|
|||||||
GeneratedType = generatedObject.GetType();
|
GeneratedType = generatedObject.GetType();
|
||||||
|
|
||||||
PropertyCache = [];
|
PropertyCache = [];
|
||||||
|
GetterCache = [];
|
||||||
|
SetterCache = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyInfo CacheProperty<T>(string fieldName)
|
||||||
|
{
|
||||||
|
var propertyInfo = AccessTools.Property(GeneratedType, fieldName)
|
||||||
|
?? throw new MissingMemberException(
|
||||||
|
$"Could not find field '{fieldName}' in type '{GeneratedType}'.");
|
||||||
|
|
||||||
|
if (propertyInfo.PropertyType != typeof(T))
|
||||||
|
{
|
||||||
|
throw new InvalidCastException(
|
||||||
|
$"Field '{fieldName}' is of type '{propertyInfo.PropertyType}', not '{typeof(T)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyCache[fieldName] = propertyInfo;
|
||||||
|
|
||||||
|
var funcType = typeof(Func<T>);
|
||||||
|
GetterCache[fieldName] = propertyInfo.GetMethod!.CreateDelegate(funcType, GeneratedObject);
|
||||||
|
|
||||||
|
var actionType = typeof(Action<T>);
|
||||||
|
SetterCache[fieldName] = propertyInfo.SetMethod!.CreateDelegate(actionType, GeneratedObject);
|
||||||
|
|
||||||
|
return propertyInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -48,12 +83,12 @@ public class CompilerGeneratedObjectWrapper
|
|||||||
{
|
{
|
||||||
if (!PropertyCache.TryGetValue(fieldName, out var propertyInfo))
|
if (!PropertyCache.TryGetValue(fieldName, out var propertyInfo))
|
||||||
{
|
{
|
||||||
propertyInfo = AccessTools.Property(GeneratedType, fieldName);
|
propertyInfo = CacheProperty<TField>(fieldName);
|
||||||
if (propertyInfo == null)
|
}
|
||||||
{
|
|
||||||
throw new MissingMemberException($"Could not find field '{fieldName}' in type '{GeneratedType}'.");
|
if (GetterCache.TryGetValue(fieldName, out var getter))
|
||||||
}
|
{
|
||||||
PropertyCache[fieldName] = propertyInfo;
|
return ((Func<TField>) getter)();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (TField) propertyInfo.GetValue(GeneratedObject)!;
|
return (TField) propertyInfo.GetValue(GeneratedObject)!;
|
||||||
@@ -70,14 +105,16 @@ public class CompilerGeneratedObjectWrapper
|
|||||||
{
|
{
|
||||||
if (!PropertyCache.TryGetValue(fieldName, out var propertyInfo))
|
if (!PropertyCache.TryGetValue(fieldName, out var propertyInfo))
|
||||||
{
|
{
|
||||||
propertyInfo = AccessTools.Property(GeneratedType, fieldName);
|
propertyInfo = CacheProperty<TField>(fieldName);
|
||||||
if (propertyInfo == null)
|
}
|
||||||
{
|
|
||||||
throw new MissingMemberException($"Could not find field '{fieldName}' in type '{GeneratedType}'.");
|
if (SetterCache.TryGetValue(fieldName, out var setter))
|
||||||
}
|
{
|
||||||
PropertyCache[fieldName] = propertyInfo;
|
((Action<TField>) setter)(value);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
propertyInfo.SetValue(GeneratedObject, value);
|
propertyInfo.SetValue(GeneratedObject, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user