diff --git a/src/Builtin/BaseRunners.cs b/src/Builtin/BaseRunners.cs index be952f7..9f2168b 100644 --- a/src/Builtin/BaseRunners.cs +++ b/src/Builtin/BaseRunners.cs @@ -1,6 +1,7 @@ -namespace DCFApixels.DragonECS -{ +using DCFApixels.DragonECS.RunnersCore; +namespace DCFApixels.DragonECS +{ public interface IEcsPreInitSystem : IEcsSystem { public void PreInit(EcsPipeline pipeline); diff --git a/src/Builtin/InjectSystem.cs b/src/Builtin/InjectSystem.cs index 5615de9..99f9656 100644 --- a/src/Builtin/InjectSystem.cs +++ b/src/Builtin/InjectSystem.cs @@ -1,4 +1,5 @@ using DCFApixels.DragonECS.Internal; +using DCFApixels.DragonECS.RunnersCore; using System.Linq; namespace DCFApixels.DragonECS diff --git a/src/Builtin/WorldRunners.cs b/src/Builtin/WorldRunners.cs index 750f6a4..72d66c8 100644 --- a/src/Builtin/WorldRunners.cs +++ b/src/Builtin/WorldRunners.cs @@ -1,4 +1,6 @@ -namespace DCFApixels.DragonECS +using DCFApixels.DragonECS.RunnersCore; + +namespace DCFApixels.DragonECS { public interface IEcsComponentAdd : IEcsSystem { diff --git a/src/EcsPipeline.cs b/src/EcsPipeline.cs index ef54783..e0335b0 100644 --- a/src/EcsPipeline.cs +++ b/src/EcsPipeline.cs @@ -1,4 +1,5 @@ -using System; +using DCFApixels.DragonECS.RunnersCore; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Runtime.CompilerServices; diff --git a/src/EcsRunner.cs b/src/EcsRunner.cs index fb13b51..a6e6f16 100644 --- a/src/EcsRunner.cs +++ b/src/EcsRunner.cs @@ -1,4 +1,5 @@ -using System; +using DCFApixels.DragonECS.RunnersCore; +using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -22,34 +23,37 @@ namespace DCFApixels.DragonECS } public interface IEcsSystem { } - public interface IEcsRunner + + namespace RunnersCore { - public EcsPipeline Source { get; } - public Type Interface { get; } - public IList Targets { get; } - public object Filter { get; } - public bool IsHasFilter { get; } - public bool IsDestroyed { get; } - public bool IsEmpty { get; } - - public void Destroy(); - } - - internal static class EcsRunnerActivator - { - private static Dictionary _runnerHandlerTypes; //interface guid/Runner handler type pairs; - - static EcsRunnerActivator() + public interface IEcsRunner { - List delayedExceptions = new List(); - Type runnerBaseType = typeof(EcsRunner<>); - List runnerHandlerTypes = new List(); + public EcsPipeline Source { get; } + public Type Interface { get; } + public IList Targets { get; } + public object Filter { get; } + public bool IsHasFilter { get; } + public bool IsDestroyed { get; } + public bool IsEmpty { get; } - foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + public void Destroy(); + } + + internal static class EcsRunnerActivator + { + private static Dictionary _runnerHandlerTypes; //interface guid/Runner handler type pairs; + + static EcsRunnerActivator() { - runnerHandlerTypes.AddRange(assembly.GetTypes() - .Where(type => type.BaseType != null && type.BaseType.IsGenericType && runnerBaseType == type.BaseType.GetGenericTypeDefinition())); - } + List delayedExceptions = new List(); + Type runnerBaseType = typeof(EcsRunner<>); + List runnerHandlerTypes = new List(); + + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + runnerHandlerTypes.AddRange(assembly.GetTypes() + .Where(type => type.BaseType != null && type.BaseType.IsGenericType && runnerBaseType == type.BaseType.GetGenericTypeDefinition())); + } #if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS for (int i = 0; i < runnerHandlerTypes.Count; i++) @@ -62,80 +66,75 @@ namespace DCFApixels.DragonECS } } #endif - _runnerHandlerTypes = new Dictionary(); - foreach (var item in runnerHandlerTypes) - { - Type interfaceType = item.BaseType.GenericTypeArguments[0]; - _runnerHandlerTypes.Add(interfaceType.GUID, item); + _runnerHandlerTypes = new Dictionary(); + foreach (var item in runnerHandlerTypes) + { + Type interfaceType = item.BaseType.GenericTypeArguments[0]; + _runnerHandlerTypes.Add(interfaceType.GUID, item); + } + + if (delayedExceptions.Count > 0) + { + foreach (var item in delayedExceptions) EcsDebug.Print(EcsConsts.DEBUG_ERROR_TAG, item.Message); + throw delayedExceptions[0]; + } } - if (delayedExceptions.Count > 0) + private static Exception CheckRunnerValide(Type type) //TODO доработать проверку валидности реалиазации ранера { - foreach (var item in delayedExceptions) EcsDebug.Print(EcsConsts.DEBUG_ERROR_TAG, item.Message); - throw delayedExceptions[0]; + Type baseType = type.BaseType; + Type baseTypeArgument = baseType.GenericTypeArguments[0]; + + if (type.ReflectedType != null) + { + return new EcsRunnerImplementationException($"{type.FullName}.ReflectedType must be Null, but equal to {type.ReflectedType.FullName}."); + } + if (!baseTypeArgument.IsInterface) + { + return new EcsRunnerImplementationException($"Argument T of class EcsRunner, can only be an inetrface.The {baseTypeArgument.FullName} type is not an interface."); + } + + var interfaces = type.GetInterfaces(); + + if (!interfaces.Any(o => o == baseTypeArgument)) + { + return new EcsRunnerImplementationException($"Runner {type.FullName} does not implement interface {baseTypeArgument.FullName}."); + } + + return null; + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void InitFor() where TInterface : IEcsSystem + { + Type interfaceType = typeof(TInterface); + Type nonGenericInterfaceType = interfaceType; + if (nonGenericInterfaceType.IsGenericType) + { + nonGenericInterfaceType = nonGenericInterfaceType.GetGenericTypeDefinition(); + } + Guid interfaceGuid = nonGenericInterfaceType.GUID; + + if (!_runnerHandlerTypes.TryGetValue(interfaceGuid, out Type runnerType)) + { + throw new Exception(); + } + if (interfaceType.IsGenericType) + { + Type[] genericTypes = interfaceType.GetGenericArguments(); + runnerType = runnerType.MakeGenericType(genericTypes); + } + EcsRunner.Register(runnerType); } } - - private static Exception CheckRunnerValide(Type type) //TODO доработать проверку валидности реалиазации ранера + public abstract class EcsRunner : IEcsSystem, IEcsRunner + where TInterface : IEcsSystem { - Type baseType = type.BaseType; - Type baseTypeArgument = baseType.GenericTypeArguments[0]; - - if (type.ReflectedType != null) + #region Register + private static Type _subclass; + internal static void Register(Type subclass) { - return new EcsRunnerImplementationException($"{type.FullName}.ReflectedType must be Null, but equal to {type.ReflectedType.FullName}."); - } - if (!baseTypeArgument.IsInterface) - { - return new EcsRunnerImplementationException($"Argument T of class EcsRunner, can only be an inetrface.The {baseTypeArgument.FullName} type is not an interface."); - } - - var interfaces = type.GetInterfaces(); - - if (!interfaces.Any(o => o == baseTypeArgument)) - { - return new EcsRunnerImplementationException($"Runner {type.FullName} does not implement interface {baseTypeArgument.FullName}."); - } - - return null; - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void InitFor() where TInterface : IEcsSystem - { - Type interfaceType = typeof(TInterface); - Type nonGenericInterfaceType = interfaceType; - if (nonGenericInterfaceType.IsGenericType) - { - nonGenericInterfaceType = nonGenericInterfaceType.GetGenericTypeDefinition(); - } - Guid interfaceGuid = nonGenericInterfaceType.GUID; - - if (!_runnerHandlerTypes.TryGetValue(interfaceGuid, out Type runnerType)) - { - throw new Exception(); - } - if (interfaceType.IsGenericType) - { - Type[] genericTypes = interfaceType.GetGenericArguments(); - runnerType = runnerType.MakeGenericType(genericTypes); - } - EcsRunner.Register(runnerType); - } - } - - public static class EcsRunner - { - public static void Destroy(object runner) => ((IEcsRunner)runner).Destroy(); - } - public abstract class EcsRunner : IEcsSystem, IEcsRunner - where TInterface : IEcsSystem - { - #region Register - private static Type _subclass; - internal static void Register(Type subclass) - { #if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS if (_subclass != null) { @@ -154,114 +153,118 @@ namespace DCFApixels.DragonECS throw new ArgumentException($"{typeof(TInterface).FullName} does not directly inherit the {nameof(IEcsSystem)} interface"); } #endif - _subclass = subclass; - } - #endregion - - #region FilterSystems - private static TInterface[] FilterSystems(IEnumerable targets) - { - return targets.Where(o => o is TInterface).Select(o => (TInterface)o).ToArray(); - } - private static TInterface[] FilterSystems(IEnumerable targets, object filter) - { - Type interfaceType = typeof(TInterface); - - IEnumerable newTargets; - - if (filter != null) - { - newTargets = targets.Where(o => - { - if (o is TInterface == false) return false; - var atr = o.GetType().GetCustomAttribute(); - return atr != null && atr.interfaceType == interfaceType && atr.filter.Equals(filter); - }); + _subclass = subclass; } - else + #endregion + + #region FilterSystems + private static TInterface[] FilterSystems(IEnumerable targets) { - newTargets = targets.Where(o => - { - if (o is TInterface == false) return false; - var atr = o.GetType().GetCustomAttribute(); - return atr == null || atr.interfaceType == interfaceType && atr.filter == null; - }); + return targets.Where(o => o is TInterface).Select(o => (TInterface)o).ToArray(); } - return newTargets.Select(o => (TInterface)o).ToArray(); + private static TInterface[] FilterSystems(IEnumerable targets, object filter) + { + Type interfaceType = typeof(TInterface); + + IEnumerable newTargets; + + if (filter != null) + { + newTargets = targets.Where(o => + { + if (o is TInterface == false) return false; + var atr = o.GetType().GetCustomAttribute(); + return atr != null && atr.interfaceType == interfaceType && atr.filter.Equals(filter); + }); + } + else + { + newTargets = targets.Where(o => + { + if (o is TInterface == false) return false; + var atr = o.GetType().GetCustomAttribute(); + return atr == null || atr.interfaceType == interfaceType && atr.filter == null; + }); + } + return newTargets.Select(o => (TInterface)o).ToArray(); + } + #endregion + + #region Instantiate + private static TInterface Instantiate(EcsPipeline source, TInterface[] targets, bool isHasFilter, object filter) + { + if (_subclass == null) + EcsRunnerActivator.InitFor(); + + var instance = (EcsRunner)Activator.CreateInstance(_subclass); + return (TInterface)(IEcsSystem)instance.Set(source, targets, isHasFilter, filter); + } + public static TInterface Instantiate(EcsPipeline source) + { + return Instantiate(source, FilterSystems(source.AllSystems), false, null); + } + public static TInterface Instantiate(EcsPipeline source, object filter) + { + return Instantiate(source, FilterSystems(source.AllSystems, filter), true, filter); + } + #endregion + + private EcsPipeline _source; + protected TInterface[] targets; + private ReadOnlyCollection _targetsSealed; + private object _filter; + private bool _isHasFilter; + private bool _isDestroyed; + + #region Properties + public EcsPipeline Source => _source; + public Type Interface => typeof(TInterface); + public IList Targets => _targetsSealed; + public object Filter => _filter; + public bool IsHasFilter => _isHasFilter; + public bool IsDestroyed => _isDestroyed; + public bool IsEmpty => targets == null || targets.Length <= 0; + #endregion + + private EcsRunner Set(EcsPipeline source, TInterface[] targets, bool isHasFilter, object filter) + { + _source = source; + this.targets = targets; + _targetsSealed = new ReadOnlyCollection(targets); + _filter = filter; + _isHasFilter = isHasFilter; + OnSetup(); + return this; + } + + internal void Rebuild() + { + if (_isHasFilter) + Set(_source, FilterSystems(_source.AllSystems), _isHasFilter, _filter); + else + Set(_source, FilterSystems(_source.AllSystems, _filter), _isHasFilter, _filter); + } + + public void Destroy() + { + _isDestroyed = true; + _source.OnRunnerDestroy(this); + _source = null; + targets = null; + _targetsSealed = null; + _filter = null; + OnDestroy(); + } + + protected virtual void OnSetup() { } + protected virtual void OnDestroy() { } } - #endregion - - #region Instantiate - private static TInterface Instantiate(EcsPipeline source, TInterface[] targets, bool isHasFilter, object filter) - { - if (_subclass == null) - EcsRunnerActivator.InitFor(); - - var instance = (EcsRunner)Activator.CreateInstance(_subclass); - return (TInterface)(IEcsSystem)instance.Set(source, targets, isHasFilter, filter); - } - public static TInterface Instantiate(EcsPipeline source) - { - return Instantiate(source, FilterSystems(source.AllSystems), false, null); - } - public static TInterface Instantiate(EcsPipeline source, object filter) - { - return Instantiate(source, FilterSystems(source.AllSystems, filter), true, filter); - } - #endregion - - private EcsPipeline _source; - protected TInterface[] targets; - private ReadOnlyCollection _targetsSealed; - private object _filter; - private bool _isHasFilter; - private bool _isDestroyed; - - #region Properties - public EcsPipeline Source => _source; - public Type Interface => typeof(TInterface); - public IList Targets => _targetsSealed; - public object Filter => _filter; - public bool IsHasFilter => _isHasFilter; - public bool IsDestroyed => _isDestroyed; - public bool IsEmpty => targets == null || targets.Length <= 0; - #endregion - - private EcsRunner Set(EcsPipeline source, TInterface[] targets, bool isHasFilter, object filter) - { - _source = source; - this.targets = targets; - _targetsSealed = new ReadOnlyCollection(targets); - _filter = filter; - _isHasFilter = isHasFilter; - OnSetup(); - return this; - } - - internal void Rebuild() - { - if(_isHasFilter) - Set(_source, FilterSystems(_source.AllSystems), _isHasFilter, _filter); - else - Set(_source, FilterSystems(_source.AllSystems, _filter), _isHasFilter, _filter); - } - - public void Destroy() - { - _isDestroyed = true; - _source.OnRunnerDestroy(this); - _source = null; - targets = null; - _targetsSealed = null; - _filter = null; - OnDestroy(); - } - - protected virtual void OnSetup() { } - protected virtual void OnDestroy() { } } - #region Extensions + public static class EcsRunner + { + public static void Destroy(IEcsSystem runner) => ((IEcsRunner)runner).Destroy(); + } public static class IEcsSystemExtensions { public static bool IsRunner(this IEcsSystem self)