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
+47
-10
@@ -25,6 +25,16 @@ public class CompilerGeneratedObjectWrapper
|
||||
/// </summary>
|
||||
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>
|
||||
/// Initializes a new instance of the <see cref="CompilerGeneratedObjectWrapper"/> class.
|
||||
/// </summary>
|
||||
@@ -35,6 +45,31 @@ public class CompilerGeneratedObjectWrapper
|
||||
GeneratedType = generatedObject.GetType();
|
||||
|
||||
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>
|
||||
@@ -48,12 +83,12 @@ public class CompilerGeneratedObjectWrapper
|
||||
{
|
||||
if (!PropertyCache.TryGetValue(fieldName, out var propertyInfo))
|
||||
{
|
||||
propertyInfo = AccessTools.Property(GeneratedType, fieldName);
|
||||
if (propertyInfo == null)
|
||||
{
|
||||
throw new MissingMemberException($"Could not find field '{fieldName}' in type '{GeneratedType}'.");
|
||||
propertyInfo = CacheProperty<TField>(fieldName);
|
||||
}
|
||||
PropertyCache[fieldName] = propertyInfo;
|
||||
|
||||
if (GetterCache.TryGetValue(fieldName, out var getter))
|
||||
{
|
||||
return ((Func<TField>) getter)();
|
||||
}
|
||||
|
||||
return (TField) propertyInfo.GetValue(GeneratedObject)!;
|
||||
@@ -70,14 +105,16 @@ public class CompilerGeneratedObjectWrapper
|
||||
{
|
||||
if (!PropertyCache.TryGetValue(fieldName, out var propertyInfo))
|
||||
{
|
||||
propertyInfo = AccessTools.Property(GeneratedType, fieldName);
|
||||
if (propertyInfo == null)
|
||||
{
|
||||
throw new MissingMemberException($"Could not find field '{fieldName}' in type '{GeneratedType}'.");
|
||||
propertyInfo = CacheProperty<TField>(fieldName);
|
||||
}
|
||||
PropertyCache[fieldName] = propertyInfo;
|
||||
|
||||
if (SetterCache.TryGetValue(fieldName, out var setter))
|
||||
{
|
||||
((Action<TField>) setter)(value);
|
||||
return;
|
||||
}
|
||||
|
||||
propertyInfo.SetValue(GeneratedObject, value);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user