diff --git a/src/Attributes/AutoInjectAttribute.cs b/src/Attributes/EcsInjectAttribute.cs similarity index 69% rename from src/Attributes/AutoInjectAttribute.cs rename to src/Attributes/EcsInjectAttribute.cs index 39f92b2..cf6f3b2 100644 --- a/src/Attributes/AutoInjectAttribute.cs +++ b/src/Attributes/EcsInjectAttribute.cs @@ -3,11 +3,11 @@ namespace DCFApixels.DragonECS { [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] - public sealed class AutoInjectAttribute : Attribute + public sealed class EcsInjectAttribute : Attribute { public readonly Type notNullDummyType; - public AutoInjectAttribute(Type notNullDummyType = null) + public EcsInjectAttribute(Type notNullDummyType = null) { this.notNullDummyType = notNullDummyType; } diff --git a/src/Attributes/QueryAttributes.cs b/src/Attributes/QueryAttributes.cs index c68b491..e8122e8 100644 --- a/src/Attributes/QueryAttributes.cs +++ b/src/Attributes/QueryAttributes.cs @@ -1,12 +1,56 @@ using System; +using System.Linq; namespace DCFApixels.DragonECS { + public class InjectAttribute : Attribute { } [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] - public sealed class IncAttribute : Attribute { } + public sealed class IncAttribute : InjectAttribute { } [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] - public sealed class ExcAttribute : Attribute { } + public sealed class ExcAttribute : InjectAttribute { } [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)] - public sealed class OptAttribute : Attribute { } + public sealed class OptAttribute : InjectAttribute { } + + + public abstract class ImplicitInjectAttribute : Attribute { } + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, Inherited = false, AllowMultiple = true)] + public sealed class IncImplicitAttribute : ImplicitInjectAttribute + { + public readonly Type type; + public readonly bool isPool; + + public IncImplicitAttribute(Type type) + { + if (type.IsValueType && !type.IsPrimitive) + { + isPool = false; + this.type = type; + return; + } + if (!type.GetInterfaces().Any(o => o == typeof(IEcsPoolImplementation))) + throw new ArgumentException("Можно использовать только пулы наследованные от IEcsPoolImplementation"); + this.type = type; + isPool = true; + } + } + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, Inherited = false, AllowMultiple = true)] + public sealed class ExcImplicitAttribute : ImplicitInjectAttribute + { + public readonly Type type; + public readonly bool isPool; + public ExcImplicitAttribute(Type type) + { + if (type.IsValueType && !type.IsPrimitive) + { + isPool = false; + this.type = type; + return; + } + if (!type.GetInterfaces().Any(o => o == typeof(IEcsPoolImplementation))) + throw new ArgumentException("Можно использовать только пулы наследованные от IEcsPoolImplementation"); + this.type = type; + isPool = true; + } + } } diff --git a/src/AutoInjectSystem.cs b/src/AutoInjectSystem.cs index b954b34..114cfd7 100644 --- a/src/AutoInjectSystem.cs +++ b/src/AutoInjectSystem.cs @@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS Type systemType = system.GetType(); foreach (var field in systemType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { - AutoInjectAttribute autoInjectAttribute = field.GetCustomAttribute(); + EcsInjectAttribute autoInjectAttribute = field.GetCustomAttribute(); if (autoInjectAttribute != null) { Type fieldType = field.FieldType; @@ -97,8 +97,8 @@ namespace DCFApixels.DragonECS { public readonly IEcsSystem target; public readonly FieldInfo field; - public readonly AutoInjectAttribute attribute; - public FiledRecord(IEcsSystem target, FieldInfo field, AutoInjectAttribute attribute) + public readonly EcsInjectAttribute attribute; + public FiledRecord(IEcsSystem target, FieldInfo field, EcsInjectAttribute attribute) { this.target = target; this.field = field; @@ -108,7 +108,7 @@ namespace DCFApixels.DragonECS } [DebugHide, DebugColor(DebugColor.Gray)] - public class AutoInjectSystem : IEcsPreInitSystem, IEcsPreInject, IEcsPreInitInjectCallbacks + public class AutoInjectSystem : IEcsPreInitProcess, IEcsPreInject, IEcsPreInitInjectProcess { private EcsPipeline _pipeline; private List _injectQueue = new List(); diff --git a/src/EcsQuery/EcsQueryDI.cs b/src/EcsQuery/EcsQueryDI.cs deleted file mode 100644 index 23c7f53..0000000 --- a/src/EcsQuery/EcsQueryDI.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Reflection; - -namespace DCFApixels.DragonECS -{ - public abstract class EcsJoinAttachQueryDI : EcsJoinAttachQuery - where TAttachComponent : struct, IEcsAttachComponent - { - protected override void Init(Builder b) => EcsQueryDIHelper.Fill(this, b); - } - public abstract class EcsQueryDI : EcsQuery - { - protected override void Init(Builder b) => EcsQueryDIHelper.Fill(this, b); - } - - internal static class EcsQueryDIHelper - { - public static void Fill(EcsQueryBase q, EcsQueryBase.Builder b) - { - Type builderType = b.GetType(); - MethodInfo incluedMethod = builderType.GetMethod("Include", BindingFlags.Instance | BindingFlags.Public); - MethodInfo excludeMethod = builderType.GetMethod("Exclude", BindingFlags.Instance | BindingFlags.Public); - MethodInfo optionalMethod = builderType.GetMethod("Optional", BindingFlags.Instance | BindingFlags.Public); - - Type thisType = q.GetType(); - FieldInfo[] fieldInfos = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - foreach (FieldInfo fieldInfo in fieldInfos) - { - Type fieldType = fieldInfo.FieldType; - if (fieldType.IsSubclassOf(typeof(EcsPoolBase)) == false) - continue; - if (fieldType.IsGenericType == false) - continue; - - Type componentType = fieldType.GenericTypeArguments[0]; - - if (fieldInfo.GetCustomAttribute() != null) - { - fieldInfo.SetValue(q, incluedMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null)); - continue; - } - if (fieldInfo.GetCustomAttribute() != null) - { - fieldInfo.SetValue(q, excludeMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null)); - continue; - } - if (fieldInfo.GetCustomAttribute() != null) - { - fieldInfo.SetValue(q, optionalMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null)); - continue; - } - } - } - } -} diff --git a/src/EcsQuery/EcsSubjectDI.cs b/src/EcsQuery/EcsSubjectDI.cs new file mode 100644 index 0000000..65ee6ca --- /dev/null +++ b/src/EcsQuery/EcsSubjectDI.cs @@ -0,0 +1,95 @@ +using System; +using System.Reflection; + +namespace DCFApixels.DragonECS +{ + public abstract class EcsSubjectDI : EcsSubject + { + protected sealed override void Init(Builder b) => EcsQueryDIHelper.Fill(this, b); + } + + internal static class EcsQueryDIHelper + { + public static void Fill(EcsSubject s, EcsSubject.Builder b) + { + Type builderType = b.GetType(); + MethodInfo incluedMethod = builderType.GetMethod("Include", BindingFlags.Instance | BindingFlags.Public); + MethodInfo excludeMethod = builderType.GetMethod("Exclude", BindingFlags.Instance | BindingFlags.Public); + MethodInfo includeImplicitMethod = builderType.GetMethod("IncludeImplicit", BindingFlags.Instance | BindingFlags.Public); + MethodInfo excludeImplicitMethod = builderType.GetMethod("ExcludeImplicit", BindingFlags.Instance | BindingFlags.Public); + MethodInfo optionalMethod = builderType.GetMethod("Optional", BindingFlags.Instance | BindingFlags.Public); + + Type subjectType = s.GetType(); + + foreach (var attribute in subjectType.GetCustomAttributes())//TODO убрать дублирование кода - вынести в отедльный метод + { + if (attribute is IncImplicitAttribute incImplicit) + { + if (incImplicit.isPool) + incluedMethod.MakeGenericMethod(incImplicit.type.GenericTypeArguments[0], incImplicit.type).Invoke(b, null); + else + includeImplicitMethod.MakeGenericMethod(incImplicit.type).Invoke(b, null); + continue; + } + if (attribute is ExcImplicitAttribute excImplicit) + { + if (excImplicit.isPool) + excludeMethod.MakeGenericMethod(excImplicit.type.GenericTypeArguments[0], excImplicit.type).Invoke(b, null); + else + excludeImplicitMethod.MakeGenericMethod(excImplicit.type).Invoke(b, null); + continue; + } + }//TODO КОНЕЦ убрать дублирование кода - вынести в отедльный метод + + + FieldInfo[] fieldInfos = subjectType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + foreach (FieldInfo fieldInfo in fieldInfos) + { + Type fieldType = fieldInfo.FieldType; + + foreach (var attribute in fieldInfo.GetCustomAttributes())//TODO убрать дублирование кода - вынести в отедльный метод + { + if(attribute is IncImplicitAttribute incImplicit) + { + if(incImplicit.isPool) + incluedMethod.MakeGenericMethod(incImplicit.type.GenericTypeArguments[0], incImplicit.type).Invoke(b, null); + else + includeImplicitMethod.MakeGenericMethod(incImplicit.type).Invoke(b, null); + continue; + } + if (attribute is ExcImplicitAttribute excImplicit) + { + if (excImplicit.isPool) + excludeMethod.MakeGenericMethod(excImplicit.type.GenericTypeArguments[0], excImplicit.type).Invoke(b, null); + else + excludeImplicitMethod.MakeGenericMethod(excImplicit.type).Invoke(b, null); + continue; + } + }//TODO КОНЕЦ убрать дублирование кода - вынести в отедльный метод + + if (fieldInfo.GetCustomAttribute() == null) + continue; + if (fieldType.IsGenericType == false) + continue; + + Type componentType = fieldType.GenericTypeArguments[0]; + + if (fieldInfo.GetCustomAttribute() != null) + { + fieldInfo.SetValue(s, incluedMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null)); + continue; + } + if (fieldInfo.GetCustomAttribute() != null) + { + fieldInfo.SetValue(s, excludeMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null)); + continue; + } + if (fieldInfo.GetCustomAttribute() != null) + { + fieldInfo.SetValue(s, optionalMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null)); + continue; + } + } + } + } +}