From 25fc3318d0a21397b5553d06bdb8edacd2a325cd Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 12 Mar 2023 02:02:39 +0800 Subject: [PATCH] Updtae runners --- src/Builtin/DestroyProcessor.cs | 5 +- src/Builtin/InjectProcessor.cs | 21 +++-- src/Builtin/Runners.cs | 54 +++++++++++ .../Runners.cs.meta} | 2 +- src/EcsSession.cs | 64 ++++--------- src/Interfaces/IEcsProcessor.cs | 53 ----------- src/Interfaces/IEcsProcessor.cs.meta | 11 --- src/React/EcsProcessorsMessenger.cs.meta | 11 --- src/React/EcsProcessorsRunner.cs.meta | 11 --- src/React/EcsRunner.cs | 93 +++++++++++++++---- test/TestSystem.cs | 23 ++--- 11 files changed, 179 insertions(+), 169 deletions(-) create mode 100644 src/Builtin/Runners.cs rename src/{React/WorldFilterAttribute.cs.meta => Builtin/Runners.cs.meta} (83%) delete mode 100644 src/Interfaces/IEcsProcessor.cs delete mode 100644 src/Interfaces/IEcsProcessor.cs.meta delete mode 100644 src/React/EcsProcessorsMessenger.cs.meta delete mode 100644 src/React/EcsProcessorsRunner.cs.meta diff --git a/src/Builtin/DestroyProcessor.cs b/src/Builtin/DestroyProcessor.cs index f3eb0e9..15ceb95 100644 --- a/src/Builtin/DestroyProcessor.cs +++ b/src/Builtin/DestroyProcessor.cs @@ -1,10 +1,9 @@ namespace DCFApixels.DragonECS { - public class DestroyProcessor : IDo<_Run> + public class DestroyProcessor : IEcsRunSystem { - void IDo<_Run>.Do(EcsSession session) + public void Run(EcsSession session) { - } } diff --git a/src/Builtin/InjectProcessor.cs b/src/Builtin/InjectProcessor.cs index 0145497..7137658 100644 --- a/src/Builtin/InjectProcessor.cs +++ b/src/Builtin/InjectProcessor.cs @@ -6,13 +6,23 @@ using System.Threading.Tasks; namespace DCFApixels.DragonECS { - public interface IEcsInject + public interface IEcsInject : IEcsProcessor { public void Inject(T obj); } - public class InjectProcessor : IDo<_PreInit> + public class InjectRunner : EcsRunner>, IEcsInject { + void IEcsInject.Inject(T obj) + { + foreach (var item in targets) + { + item.Inject(obj); + } + } + } + public class InjectProcessor : IEcsPreInitSystem + { private T _injectedData; public InjectProcessor(T injectedData) @@ -20,11 +30,10 @@ namespace DCFApixels.DragonECS _injectedData = injectedData; } - void IDo<_PreInit>.Do(EcsSession session) + public void PreInit(EcsSession session) { - var messenger = session.GetMessenger<_OnInject>(); - messenger.Send(new _OnInject(_injectedData)); - messenger.Destroy(); + var injector = session.GetRunner>(); + injector.Inject(_injectedData); } } diff --git a/src/Builtin/Runners.cs b/src/Builtin/Runners.cs new file mode 100644 index 0000000..53b25cf --- /dev/null +++ b/src/Builtin/Runners.cs @@ -0,0 +1,54 @@ +namespace DCFApixels.DragonECS +{ + public interface IEcsPreInitSystem : IEcsProcessor + { + public void PreInit(EcsSession session); + } + public interface IEcsInitSystem : IEcsProcessor + { + public void Init(EcsSession session); + } + public interface IEcsRunSystem : IEcsProcessor + { + public void Run(EcsSession session); + } + public interface IEcsDestroySystem : IEcsProcessor + { + public void Destroy(EcsSession session); + } + + public interface IEcsSimpleCycleSystem : + IEcsInitSystem, + IEcsRunSystem, + IEcsDestroySystem + { } + + public sealed class EcsPreInitRunner : EcsRunner, IEcsPreInitSystem + { + void IEcsPreInitSystem.PreInit(EcsSession session) + { + foreach (var item in targets) item.PreInit(session); + } + } + public sealed class EcsInitRunner : EcsRunner, IEcsInitSystem + { + void IEcsInitSystem.Init(EcsSession session) + { + foreach (var item in targets) item.Init(session); + } + } + public sealed class EcsRunRunner : EcsRunner, IEcsRunSystem + { + void IEcsRunSystem.Run(EcsSession session) + { + foreach (var item in targets) item.Run(session); + } + } + public sealed class EcsDestroyRunner : EcsRunner, IEcsDestroySystem + { + void IEcsDestroySystem.Destroy(EcsSession session) + { + foreach (var item in targets) item.Destroy(session); + } + } +} diff --git a/src/React/WorldFilterAttribute.cs.meta b/src/Builtin/Runners.cs.meta similarity index 83% rename from src/React/WorldFilterAttribute.cs.meta rename to src/Builtin/Runners.cs.meta index 863b196..bcdcbb8 100644 --- a/src/React/WorldFilterAttribute.cs.meta +++ b/src/Builtin/Runners.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 473f26450295507498d518fb452be90f +guid: 074bd83936df7c84daf6e295b2f21a9a MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/EcsSession.cs b/src/EcsSession.cs index 0731e3b..253d2b6 100644 --- a/src/EcsSession.cs +++ b/src/EcsSession.cs @@ -40,57 +40,34 @@ namespace DCFApixels.DragonECS private int _id; - private List _allProcessors; - private ReadOnlyCollection _allProcessorsSealed; + private List _allSystems; + private ReadOnlyCollection _allSystemsSealed; private bool _isInit = false; private bool _isDestoryed = false; - private Dictionary _runners; - private Dictionary _messengers; - private EcsProcessorsRunner<_Run> _runRunnerCache; + private Dictionary _runners; + private IEcsRunSystem _runRunnerCache; private EcsWorldMap _worldMap = new EcsWorldMap(); #region Properties - public ReadOnlyCollection AllProcessors => _allProcessorsSealed; + public ReadOnlyCollection AllProcessors => _allSystemsSealed; #endregion #region React Runners/Messengers - public EcsProcessorsRunner GetRunner() + public T GetRunner() where T : IEcsProcessor { - Type type = typeof(TDoTag); - if (_runners.TryGetValue(type, out IEcsProcessorsRunner result)) + Type type = typeof(T); + if (_runners.TryGetValue(type, out IEcsRunner result)) { - return (EcsProcessorsRunner)result; + return (T)result; } - result = new EcsProcessorsRunner(this); + result = (IEcsRunner)EcsRunner.Instantiate(_allSystems); _runners.Add(type, result); - return (EcsProcessorsRunner)result; - } - internal void OnRunnerDetroyed(EcsProcessorsRunner target) - { - _runners.Remove(typeof(TDoTag)); - } - - public EcsProcessorsMessenger GetMessenger() - where TMessege : IEcsMessage - { - Type type = typeof(EcsProcessorsMessenger); - if (_messengers.TryGetValue(type, out IEcsProcessorsMessenger result)) - { - return (EcsProcessorsMessenger)result; - } - result = new EcsProcessorsMessenger(this); - _messengers.Add(type, result); - return (EcsProcessorsMessenger)result; - } - internal void OnMessengerDetroyed(IEcsProcessorsMessenger target) - where TMessege : IEcsMessage - { - _messengers.Remove(typeof(TMessege)); + return (T)result; } #endregion @@ -98,7 +75,7 @@ namespace DCFApixels.DragonECS public EcsSession Add(IEcsProcessor system) { CheckInitForMethod(nameof(AddWorld)); - _allProcessors.Add(system); + _allSystems.Add(system); return this; } public EcsSession AddWorld(EcsWorld world, string name = "") @@ -116,29 +93,28 @@ namespace DCFApixels.DragonECS { CheckInitForMethod(nameof(Init)); _worldMap.Build(); - _allProcessorsSealed = _allProcessors.AsReadOnly(); + _allSystemsSealed = _allSystems.AsReadOnly(); _isInit = true; - GetMessenger<_OnInject>().Send(new _OnInject(_worldMap)); + GetRunner>().Inject(_worldMap); - GetRunner<_PreInit>().Run(); - GetRunner<_Init>().Run(); + GetRunner().PreInit(this); + GetRunner().Init(this); - _runRunnerCache = GetRunner<_Run>(); + _runRunnerCache = GetRunner(); } public void Run() { CheckDestroyForMethod(nameof(Run)); - - _runRunnerCache.Run(); + _runRunnerCache.Run(this); } public void Destroy() { CheckDestroyForMethod(nameof(Run)); _isDestoryed = true; - GetRunner<_Destroy>().Run(); - GetRunner<_PostDestroy>().Run(); + + GetRunner().Destroy(this); } #endregion diff --git a/src/Interfaces/IEcsProcessor.cs b/src/Interfaces/IEcsProcessor.cs deleted file mode 100644 index b3db294..0000000 --- a/src/Interfaces/IEcsProcessor.cs +++ /dev/null @@ -1,53 +0,0 @@ -namespace DCFApixels.DragonECS -{ - - public struct _PreInit { } - public struct _Init { } - public struct _Run { } - public struct _Destroy { } - public struct _PostDestroy { } - public interface IDo : IEcsProcessor - { - public void Do(EcsSession session); - } - public interface IEcsSimpleCycleProcessor : - IDo<_Init>, - IDo<_Run>, - IDo<_Destroy> - { } - - - - public interface IEcsMessage { } - public readonly struct _OnNewEntityCreated : IEcsMessage - { - public readonly ent entity; - - public _OnNewEntityCreated(ent entity) - { - this.entity = entity; - } - } - public readonly struct _OnNewEntityGenRecycled : IEcsMessage - { - public readonly ent entity; - public _OnNewEntityGenRecycled(ent entity) - { - this.entity = entity; - } - } - - public readonly struct _OnInject : IEcsMessage - { - public readonly T data; - public _OnInject(T data) - { - this.data = data; - } - } - public interface IReceive : IEcsProcessor - where TMessage : IEcsMessage - { - public void Do(EcsSession session, in TMessage m); - } -} diff --git a/src/Interfaces/IEcsProcessor.cs.meta b/src/Interfaces/IEcsProcessor.cs.meta deleted file mode 100644 index 3d46598..0000000 --- a/src/Interfaces/IEcsProcessor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c440e40c9802ce54fb7a84fda930b22d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/React/EcsProcessorsMessenger.cs.meta b/src/React/EcsProcessorsMessenger.cs.meta deleted file mode 100644 index 80d90cd..0000000 --- a/src/React/EcsProcessorsMessenger.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5fb1c6ecbb7c4fd4692f54a92b7d198e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/React/EcsProcessorsRunner.cs.meta b/src/React/EcsProcessorsRunner.cs.meta deleted file mode 100644 index 42ddcdd..0000000 --- a/src/React/EcsProcessorsRunner.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c8311d8200e99504693251ecdb1877c8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/React/EcsRunner.cs b/src/React/EcsRunner.cs index 6bf50be..c986a6d 100644 --- a/src/React/EcsRunner.cs +++ b/src/React/EcsRunner.cs @@ -28,24 +28,80 @@ namespace DCFApixels.DragonECS } } + internal static class EcsRunnerActivator { - private static bool _isInit = false; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Init() + private static Dictionary _runnerTypes; //interface guid/ Runner type pairs; + + static EcsRunnerActivator() { - if (_isInit) return; - Type targetType = typeof(EcsRunner<>); - var subclasses = Assembly.GetAssembly(targetType).GetTypes().Where(type => type.BaseType != null && type.BaseType.IsGenericType && targetType == type.BaseType.GetGenericTypeDefinition()); - foreach (var item in subclasses) + List exceptions = new List(); + + Type runnerBaseType = typeof(EcsRunner<>); + + List newRunnerTypes = new List(); + newRunnerTypes = Assembly.GetAssembly(runnerBaseType) + .GetTypes() + .Where(type => type.BaseType != null && type.BaseType.IsGenericType && runnerBaseType == type.BaseType.GetGenericTypeDefinition()) + .ToList(); + +#if DEBUG + for (int i = 0; i < newRunnerTypes.Count; i++) { - item.BaseType.GetMethod("Init", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { item }); + var e = CheckRunnerValide(newRunnerTypes[i]); + if (e != null) + { + newRunnerTypes.RemoveAt(i--); + exceptions.Add(e); + } } - _isInit = true; +#endif + _runnerTypes = new Dictionary(); + foreach (var item in newRunnerTypes) + { + Type intrf = item.GetInterfaces()[2]; //TODO доработать это место. Во-первых убрать магическое число 2, во-вторых сделать так чтоб брался только наследованный интерфейс, а не все + _runnerTypes.Add(intrf.GUID, item); + } + + if (exceptions.Count > 0) + { + foreach (var item in exceptions) throw item; + } + } + + private static Exception CheckRunnerValide(Type type) //TODO доработать проверку валидности реалиазации ранера + { + if (type.ReflectedType != null) + return new Exception($"{type.FullName}.ReflectedType must be Null, but equal to {type.ReflectedType.FullName}"); + + //var interfaces = type.GetInterfaces(); + //if (interfaces.Length != 1 || interfaces[0].GUID != typeof()) + //{ + //} + + return null; + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InitFor() where TInterface : IEcsProcessor + { + Type interfaceType = typeof(TInterface); + Guid interfaceGuid = interfaceType.GUID; + + if (!_runnerTypes.TryGetValue(interfaceGuid, out Type runnerType)) + { + throw new Exception(); + } + if (interfaceType.IsGenericType) + { + Type[] genericTypes = interfaceType.GetGenericArguments(); + runnerType = runnerType.MakeGenericType(genericTypes); + } + EcsRunner.Init(runnerType); } } - public interface IEcsRunner { } public abstract class EcsRunner : IEcsProcessor, IEcsRunner @@ -79,11 +135,11 @@ namespace DCFApixels.DragonECS { Type interfaceType = typeof(TInterface); - IEnumerable newTargets = targets.OfType(); + IEnumerable newTargets; if (filter != null) { - newTargets = newTargets.Where(o => + newTargets = targets.Where(o => { if (o is TInterface == false) return false; var atr = o.GetType().GetCustomAttribute(); @@ -92,7 +148,7 @@ namespace DCFApixels.DragonECS } else { - newTargets = newTargets.Where(o => + newTargets = targets.Where(o => { if (o is TInterface == false) return false; var atr = o.GetType().GetCustomAttribute(); @@ -100,20 +156,25 @@ namespace DCFApixels.DragonECS }); } - return Instantiate(newTargets.ToArray()); + return Instantiate(newTargets.Select(o => (TInterface)o).ToArray()); } public static TInterface Instantiate(IEnumerable targets) { - return Instantiate(targets.OfType().ToArray()); + return Instantiate(targets.Where(o => o is TInterface).Select(o => (TInterface)o).ToArray()); } internal static TInterface Instantiate(TInterface[] targets) { - EcsRunnerActivator.Init(); + if (_subclass == null) + EcsRunnerActivator.InitFor(); + var instance = (EcsRunner)Activator.CreateInstance(_subclass); return (TInterface)(IEcsProcessor)instance.Set(targets); } private static Type _subclass; + + protected static void SetSublcass(Type type) => _subclass = type; + protected TInterface[] targets; private EcsRunner Set(TInterface[] targets) diff --git a/test/TestSystem.cs b/test/TestSystem.cs index 88d2a73..e5c3182 100644 --- a/test/TestSystem.cs +++ b/test/TestSystem.cs @@ -6,26 +6,23 @@ using System.Threading.Tasks; namespace DCFApixels.DragonECS { - public class TestSystem : - IReceive<_OnInject>, - IDo<_Init>, IDo<_Run>, IDo<_Destroy> + public class TestSystem : + IEcsInject, + IEcsSimpleCycleSystem { private SharedData _sharedData; - void IReceive<_OnInject>.Do(EcsSession session, in _OnInject m) => _sharedData = m.data; + public void Inject(SharedData obj) => _sharedData = obj; - void IDo<_Init>.Do(EcsSession session) + + public void Init(EcsSession session) { } - - void IDo<_Run>.Do(EcsSession session) - { - - } - - void IDo<_Destroy>.Do(EcsSession session) + public void Run(EcsSession session) + { + } + public void Destroy(EcsSession session) { } - } }