From a7aa8b01136c72b44141352f84d8e16ce25524c4 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 25 Feb 2024 17:36:33 +0800 Subject: [PATCH] add BindWithRunner --- src/AutoRunners/BindWithRunnerAttribute.cs | 10 ++++++ src/AutoRunners/ProcessRunnerBinder.cs | 37 ++++++++++++++++++++++ src/Utils/Exceptions.cs | 6 ++++ src/Utils/ReflectionExtenions.cs | 22 +++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 src/AutoRunners/BindWithRunnerAttribute.cs create mode 100644 src/AutoRunners/ProcessRunnerBinder.cs create mode 100644 src/Utils/ReflectionExtenions.cs diff --git a/src/AutoRunners/BindWithRunnerAttribute.cs b/src/AutoRunners/BindWithRunnerAttribute.cs new file mode 100644 index 0000000..978c41a --- /dev/null +++ b/src/AutoRunners/BindWithRunnerAttribute.cs @@ -0,0 +1,10 @@ +using System; +[AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] +sealed class BindWithRunnerAttribute : Attribute +{ + public readonly Type runnerType; + public BindWithRunnerAttribute(Type runnerType) + { + this.runnerType = runnerType; + } +} \ No newline at end of file diff --git a/src/AutoRunners/ProcessRunnerBinder.cs b/src/AutoRunners/ProcessRunnerBinder.cs new file mode 100644 index 0000000..3361905 --- /dev/null +++ b/src/AutoRunners/ProcessRunnerBinder.cs @@ -0,0 +1,37 @@ +using DCFApixels.DragonECS.AutoInjections.Internal; +using System; +using System.Reflection; + +namespace DCFApixels.DragonECS +{ + public static class ProcessRunnerBinder + { + private static MethodInfo _declareRunnerMethod = typeof(EcsPipeline).GetMethod(nameof(EcsPipeline.DeclareRunner)); + public static T GetRunnerAuto(this EcsPipeline self) where T : IEcsProcess + { + if(self.TryGetRunner(out T process)) + { + return process; + } + Type type = typeof(T); + if (type.TryGetCustomAttribute(out BindWithRunnerAttribute atr)) + { + Type runnerType = atr.runnerType; + if (type.IsGenericType) + { + if(runnerType.IsGenericType == false || + runnerType.IsGenericTypeDefinition == false) + { + Throw.UndefinedException(); + } + + Type[] genericArguments = type.GetGenericArguments(); + runnerType = runnerType.MakeGenericType(genericArguments); + } + return (T)_declareRunnerMethod.MakeGenericMethod(runnerType).Invoke(self, null); + } + Throw.UndefinedException(); + return default; + } + } +} diff --git a/src/Utils/Exceptions.cs b/src/Utils/Exceptions.cs index 8886430..8e0ddc6 100644 --- a/src/Utils/Exceptions.cs +++ b/src/Utils/Exceptions.cs @@ -1,6 +1,7 @@ using System; using System.Reflection; using System.Runtime.CompilerServices; +using System.Security; namespace DCFApixels.DragonECS { @@ -24,6 +25,11 @@ namespace DCFApixels.DragonECS //method X has arguments greater than 1. throw new EcsAutoInjectionException($"{obj.Name} method Arguments != 1"); } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void UndefinedException() + { + throw new Exception(); + } } } diff --git a/src/Utils/ReflectionExtenions.cs b/src/Utils/ReflectionExtenions.cs new file mode 100644 index 0000000..c66f155 --- /dev/null +++ b/src/Utils/ReflectionExtenions.cs @@ -0,0 +1,22 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace DCFApixels.DragonECS.AutoInjections.Internal +{ + internal static class ReflectionExtenions + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool TryGetCustomAttribute(this Type self, out T attribute) where T : Attribute + { + attribute = self.GetCustomAttribute(); + return attribute != null; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool TryGetCustomAttribute(this MemberInfo self, out T attribute) where T : Attribute + { + attribute = self.GetCustomAttribute(); + return attribute != null; + } + } +}