diff --git a/Torch/Managers/ReflectionManager.cs b/Torch/Managers/ReflectionManager.cs
index 9c2701d..1886fb6 100644
--- a/Torch/Managers/ReflectionManager.cs
+++ b/Torch/Managers/ReflectionManager.cs
@@ -15,44 +15,144 @@ namespace Torch.Managers
string Name { get; set; }
Type Type { get; set; }
}
+
+ ///
+ /// Indicates that this field should contain a delegate capable of retrieving the value of a field.
+ ///
+ ///
+ ///
+ /// _instanceGetter;
+ ///
+ /// [ReflectedGetterAttribute(Name="_staticField", Type=typeof(Example))]
+ /// private static Func _staticGetter;
+ ///
+ /// private class Example {
+ /// private int _instanceField;
+ /// private static int _staticField;
+ /// }
+ /// ]]>
+ ///
+ ///
[AttributeUsage(AttributeTargets.Field)]
public class ReflectedGetterAttribute : Attribute, IReflectedFieldAttribute
{
+ ///
+ /// Name of the field to get. If null, the tagged field's name.
+ ///
public string Name { get; set; } = null;
+ ///
+ /// Declaring type of the field to get. If null, inferred from the instance argument type.
+ ///
public Type Type { get; set; } = null;
}
+ ///
+ /// Indicates that this field should contain a delegate capable of setting the value of a field.
+ ///
+ ///
+ ///
+ /// _instanceSetter;
+ ///
+ /// [ReflectedSetterAttribute(Name="_staticField", Type=typeof(Example))]
+ /// private static Action _staticSetter;
+ ///
+ /// private class Example {
+ /// private int _instanceField;
+ /// private static int _staticField;
+ /// }
+ /// ]]>
+ ///
+ ///
[AttributeUsage(AttributeTargets.Field)]
public class ReflectedSetterAttribute : Attribute, IReflectedFieldAttribute
{
+ ///
+ /// Name of the field to get. If null, the tagged field's name.
+ ///
public string Name { get; set; } = null;
+ ///
+ /// Declaring type of the field to get. If null, inferred from the instance argument type.
+ ///
public Type Type { get; set; } = null;
}
+ ///
+ /// Indicates that this field should contain a delegate capable of invoking an instance method.
+ ///
+ ///
+ ///
+ /// ExampleInstance;
+ ///
+ /// private class Example {
+ /// private int ExampleInstance(int a, float b) {
+ /// return a + ", " + b;
+ /// }
+ /// }
+ /// ]]>
+ ///
+ ///
[AttributeUsage(AttributeTargets.Field)]
public class ReflectedMethodAttribute : Attribute
{
+ ///
+ /// Name of the method to invoke. If null, the tagged field's name.
+ ///
public string Name { get; set; } = null;
+ ///
+ /// Declaring type of the method to invoke. If null, inferred from the instance argument type.
+ ///
+ public Type Type { get; set; } = null;
}
+ ///
+ /// Indicates that this field should contain a delegate capable of invoking a static method.
+ ///
+ ///
+ ///
+ /// ExampleStatic;
+ ///
+ /// private class Example {
+ /// private static int ExampleStatic(int a, float b) {
+ /// return a + ", " + b;
+ /// }
+ /// }
+ /// ]]>
+ ///
+ ///
[AttributeUsage(AttributeTargets.Field)]
public class ReflectedStaticMethodAttribute : ReflectedMethodAttribute
{
- public Type Type { get; set; }
}
+ ///
+ /// Automatically calls for every assembly already loaded, and every assembly that is loaded in the future.
+ ///
public class ReflectionManager : Manager
{
+ private static readonly string[] _namespaceBlacklist = new[] {
+ "System", "VRage", "Sandbox", "SpaceEngineers"
+ };
+
///
public ReflectionManager(ITorchBase torchInstance) : base(torchInstance) { }
+ ///
public override void Attach()
{
- foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
+ foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
Process(asm);
AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad;
}
+ ///
public override void Detach()
{
AppDomain.CurrentDomain.AssemblyLoad -= CurrentDomain_AssemblyLoad;
@@ -72,7 +172,13 @@ namespace Torch.Managers
public static void Process(Type t)
{
if (_processedTypes.Add(t))
- ProcessInternal(t);
+ {
+ foreach (string ns in _namespaceBlacklist)
+ if (t.FullName.StartsWith(ns))
+ return;
+ foreach (FieldInfo field in t.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
+ Process(field);
+ }
}
///
@@ -85,20 +191,49 @@ namespace Torch.Managers
Process(type);
}
+ ///
+ /// Processes the given field, determines if it's reflected, and initializes it if it is.
+ ///
+ /// Field to process
+ /// true if it was reflected, false if it wasn't reflectable
+ /// If the field failed to process
+ public static bool Process(FieldInfo field)
+ {
+ var attr = field.GetCustomAttribute();
+ if (attr != null)
+ {
+ ProcessReflectedMethod(field, attr);
+ return true;
+ }
+ var attr2 = field.GetCustomAttribute();
+ if (attr2 != null)
+ {
+ ProcessReflectedField(field, attr2);
+ return true;
+ }
+ var attr3 = field.GetCustomAttribute();
+ if (attr3 != null)
+ {
+ ProcessReflectedField(field, attr3);
+ return true;
+ }
+
+ return false;
+ }
+
private static void ProcessReflectedMethod(FieldInfo field, ReflectedMethodAttribute attr)
{
MethodInfo delegateMethod = field.FieldType.GetMethod("Invoke");
ParameterInfo[] parameters = delegateMethod.GetParameters();
- Type trueType;
+ Type trueType = attr.Type;
Type[] trueParameterTypes;
- if (attr is ReflectedStaticMethodAttribute staticMethod)
+ if (attr is ReflectedStaticMethodAttribute)
{
- trueType = staticMethod.Type;
trueParameterTypes = parameters.Select(x => x.ParameterType).ToArray();
}
else
{
- trueType = parameters[0].ParameterType;
+ trueType = trueType ?? parameters[0].ParameterType;
trueParameterTypes = parameters.Skip(1).Select(x => x.ParameterType).ToArray();
}
@@ -196,23 +331,5 @@ namespace Torch.Managers
field.SetValue(null, Expression.Lambda(impl, paramExp).Compile());
}
-
- private static void ProcessInternal(Type t)
- {
- foreach (FieldInfo field in t.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
- {
- var attr = field.GetCustomAttribute();
- if (attr != null)
- ProcessReflectedMethod(field, attr);
- var attr2 = field.GetCustomAttribute();
- if (attr2 != null)
- ProcessReflectedField(field, attr2);
- var attr3 = field.GetCustomAttribute();
- if (attr3 != null)
- ProcessReflectedField(field, attr3);
-
- }
- }
-
}
}