mirror of
https://github.com/DCFApixels/DragonECS-AutoInjections.git
synced 2025-09-17 20:34:34 +08:00
update
This commit is contained in:
parent
765373ea4b
commit
0a66736274
@ -3,11 +3,11 @@
|
|||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
||||||
public sealed class AutoInjectAttribute : Attribute
|
public sealed class EcsInjectAttribute : Attribute
|
||||||
{
|
{
|
||||||
public readonly Type notNullDummyType;
|
public readonly Type notNullDummyType;
|
||||||
|
|
||||||
public AutoInjectAttribute(Type notNullDummyType = null)
|
public EcsInjectAttribute(Type notNullDummyType = null)
|
||||||
{
|
{
|
||||||
this.notNullDummyType = notNullDummyType;
|
this.notNullDummyType = notNullDummyType;
|
||||||
}
|
}
|
@ -1,12 +1,56 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
|
public class InjectAttribute : Attribute { }
|
||||||
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
||||||
public sealed class IncAttribute : Attribute { }
|
public sealed class IncAttribute : InjectAttribute { }
|
||||||
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
||||||
public sealed class ExcAttribute : Attribute { }
|
public sealed class ExcAttribute : InjectAttribute { }
|
||||||
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
|
[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<T>");
|
||||||
|
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<T>");
|
||||||
|
this.type = type;
|
||||||
|
isPool = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS
|
|||||||
Type systemType = system.GetType();
|
Type systemType = system.GetType();
|
||||||
foreach (var field in systemType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
foreach (var field in systemType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||||
{
|
{
|
||||||
AutoInjectAttribute autoInjectAttribute = field.GetCustomAttribute<AutoInjectAttribute>();
|
EcsInjectAttribute autoInjectAttribute = field.GetCustomAttribute<EcsInjectAttribute>();
|
||||||
if (autoInjectAttribute != null)
|
if (autoInjectAttribute != null)
|
||||||
{
|
{
|
||||||
Type fieldType = field.FieldType;
|
Type fieldType = field.FieldType;
|
||||||
@ -97,8 +97,8 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
public readonly IEcsSystem target;
|
public readonly IEcsSystem target;
|
||||||
public readonly FieldInfo field;
|
public readonly FieldInfo field;
|
||||||
public readonly AutoInjectAttribute attribute;
|
public readonly EcsInjectAttribute attribute;
|
||||||
public FiledRecord(IEcsSystem target, FieldInfo field, AutoInjectAttribute attribute)
|
public FiledRecord(IEcsSystem target, FieldInfo field, EcsInjectAttribute attribute)
|
||||||
{
|
{
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.field = field;
|
this.field = field;
|
||||||
@ -108,7 +108,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
|
|
||||||
[DebugHide, DebugColor(DebugColor.Gray)]
|
[DebugHide, DebugColor(DebugColor.Gray)]
|
||||||
public class AutoInjectSystem : IEcsPreInitSystem, IEcsPreInject, IEcsPreInitInjectCallbacks
|
public class AutoInjectSystem : IEcsPreInitProcess, IEcsPreInject, IEcsPreInitInjectProcess
|
||||||
{
|
{
|
||||||
private EcsPipeline _pipeline;
|
private EcsPipeline _pipeline;
|
||||||
private List<object> _injectQueue = new List<object>();
|
private List<object> _injectQueue = new List<object>();
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public abstract class EcsJoinAttachQueryDI<TAttachComponent> : EcsJoinAttachQuery<TAttachComponent>
|
|
||||||
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<IncAttribute>() != null)
|
|
||||||
{
|
|
||||||
fieldInfo.SetValue(q, incluedMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (fieldInfo.GetCustomAttribute<ExcAttribute>() != null)
|
|
||||||
{
|
|
||||||
fieldInfo.SetValue(q, excludeMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (fieldInfo.GetCustomAttribute<OptAttribute>() != null)
|
|
||||||
{
|
|
||||||
fieldInfo.SetValue(q, optionalMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
95
src/EcsQuery/EcsSubjectDI.cs
Normal file
95
src/EcsQuery/EcsSubjectDI.cs
Normal file
@ -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<ImplicitInjectAttribute>())//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<ImplicitInjectAttribute>())//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<InjectAttribute>() == null)
|
||||||
|
continue;
|
||||||
|
if (fieldType.IsGenericType == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Type componentType = fieldType.GenericTypeArguments[0];
|
||||||
|
|
||||||
|
if (fieldInfo.GetCustomAttribute<IncAttribute>() != null)
|
||||||
|
{
|
||||||
|
fieldInfo.SetValue(s, incluedMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (fieldInfo.GetCustomAttribute<ExcAttribute>() != null)
|
||||||
|
{
|
||||||
|
fieldInfo.SetValue(s, excludeMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (fieldInfo.GetCustomAttribute<OptAttribute>() != null)
|
||||||
|
{
|
||||||
|
fieldInfo.SetValue(s, optionalMethod.MakeGenericMethod(componentType, fieldType).Invoke(b, null));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user