mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 09:54:35 +08:00
Updtae runners
This commit is contained in:
parent
6ae6775e00
commit
25fc3318d0
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,13 +6,23 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface IEcsInject<T>
|
||||
public interface IEcsInject<T> : IEcsProcessor
|
||||
{
|
||||
public void Inject(T obj);
|
||||
}
|
||||
public class InjectProcessor<T> : IDo<_PreInit>
|
||||
public class InjectRunner<T> : EcsRunner<IEcsInject<T>>, IEcsInject<T>
|
||||
{
|
||||
void IEcsInject<T>.Inject(T obj)
|
||||
{
|
||||
foreach (var item in targets)
|
||||
{
|
||||
item.Inject(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class InjectProcessor<T> : 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<T>>();
|
||||
messenger.Send(new _OnInject<T>(_injectedData));
|
||||
messenger.Destroy();
|
||||
var injector = session.GetRunner<IEcsInject<T>>();
|
||||
injector.Inject(_injectedData);
|
||||
}
|
||||
}
|
||||
|
||||
|
54
src/Builtin/Runners.cs
Normal file
54
src/Builtin/Runners.cs
Normal file
@ -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>, IEcsPreInitSystem
|
||||
{
|
||||
void IEcsPreInitSystem.PreInit(EcsSession session)
|
||||
{
|
||||
foreach (var item in targets) item.PreInit(session);
|
||||
}
|
||||
}
|
||||
public sealed class EcsInitRunner : EcsRunner<IEcsInitSystem>, IEcsInitSystem
|
||||
{
|
||||
void IEcsInitSystem.Init(EcsSession session)
|
||||
{
|
||||
foreach (var item in targets) item.Init(session);
|
||||
}
|
||||
}
|
||||
public sealed class EcsRunRunner : EcsRunner<IEcsRunSystem>, IEcsRunSystem
|
||||
{
|
||||
void IEcsRunSystem.Run(EcsSession session)
|
||||
{
|
||||
foreach (var item in targets) item.Run(session);
|
||||
}
|
||||
}
|
||||
public sealed class EcsDestroyRunner : EcsRunner<IEcsDestroySystem>, IEcsDestroySystem
|
||||
{
|
||||
void IEcsDestroySystem.Destroy(EcsSession session)
|
||||
{
|
||||
foreach (var item in targets) item.Destroy(session);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 473f26450295507498d518fb452be90f
|
||||
guid: 074bd83936df7c84daf6e295b2f21a9a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@ -40,57 +40,34 @@ namespace DCFApixels.DragonECS
|
||||
private int _id;
|
||||
|
||||
|
||||
private List<IEcsProcessor> _allProcessors;
|
||||
private ReadOnlyCollection<IEcsProcessor> _allProcessorsSealed;
|
||||
private List<IEcsProcessor> _allSystems;
|
||||
private ReadOnlyCollection<IEcsProcessor> _allSystemsSealed;
|
||||
|
||||
private bool _isInit = false;
|
||||
private bool _isDestoryed = false;
|
||||
|
||||
|
||||
private Dictionary<Type, IEcsProcessorsRunner> _runners;
|
||||
private Dictionary<Type, IEcsProcessorsMessenger> _messengers;
|
||||
private EcsProcessorsRunner<_Run> _runRunnerCache;
|
||||
private Dictionary<Type, IEcsRunner> _runners;
|
||||
private IEcsRunSystem _runRunnerCache;
|
||||
|
||||
private EcsWorldMap _worldMap = new EcsWorldMap();
|
||||
|
||||
#region Properties
|
||||
public ReadOnlyCollection<IEcsProcessor> AllProcessors => _allProcessorsSealed;
|
||||
public ReadOnlyCollection<IEcsProcessor> AllProcessors => _allSystemsSealed;
|
||||
|
||||
#endregion
|
||||
|
||||
#region React Runners/Messengers
|
||||
public EcsProcessorsRunner<TDoTag> GetRunner<TDoTag>()
|
||||
public T GetRunner<T>() 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<TDoTag>)result;
|
||||
return (T)result;
|
||||
}
|
||||
result = new EcsProcessorsRunner<TDoTag>(this);
|
||||
result = (IEcsRunner)EcsRunner<T>.Instantiate(_allSystems);
|
||||
_runners.Add(type, result);
|
||||
return (EcsProcessorsRunner<TDoTag>)result;
|
||||
}
|
||||
internal void OnRunnerDetroyed<TDoTag>(EcsProcessorsRunner<TDoTag> target)
|
||||
{
|
||||
_runners.Remove(typeof(TDoTag));
|
||||
}
|
||||
|
||||
public EcsProcessorsMessenger<TMessege> GetMessenger<TMessege>()
|
||||
where TMessege : IEcsMessage
|
||||
{
|
||||
Type type = typeof(EcsProcessorsMessenger<TMessege>);
|
||||
if (_messengers.TryGetValue(type, out IEcsProcessorsMessenger result))
|
||||
{
|
||||
return (EcsProcessorsMessenger<TMessege>)result;
|
||||
}
|
||||
result = new EcsProcessorsMessenger<TMessege>(this);
|
||||
_messengers.Add(type, result);
|
||||
return (EcsProcessorsMessenger<TMessege>)result;
|
||||
}
|
||||
internal void OnMessengerDetroyed<TMessege>(IEcsProcessorsMessenger<TMessege> 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<TArchetype>(EcsWorld<TArchetype> 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<EcsWorldMap>>().Send(new _OnInject<EcsWorldMap>(_worldMap));
|
||||
GetRunner<IEcsInject<EcsWorldMap>>().Inject(_worldMap);
|
||||
|
||||
GetRunner<_PreInit>().Run();
|
||||
GetRunner<_Init>().Run();
|
||||
GetRunner<IEcsPreInitSystem>().PreInit(this);
|
||||
GetRunner<IEcsInitSystem>().Init(this);
|
||||
|
||||
_runRunnerCache = GetRunner<_Run>();
|
||||
_runRunnerCache = GetRunner<IEcsRunSystem>();
|
||||
}
|
||||
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<IEcsDestroySystem>().Destroy(this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -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<TTag> : 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<T> : IEcsMessage
|
||||
{
|
||||
public readonly T data;
|
||||
public _OnInject(T data)
|
||||
{
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
public interface IReceive<TMessage> : IEcsProcessor
|
||||
where TMessage : IEcsMessage
|
||||
{
|
||||
public void Do(EcsSession session, in TMessage m);
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c440e40c9802ce54fb7a84fda930b22d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5fb1c6ecbb7c4fd4692f54a92b7d198e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8311d8200e99504693251ecdb1877c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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<Guid, Type> _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<Exception> exceptions = new List<Exception>();
|
||||
|
||||
Type runnerBaseType = typeof(EcsRunner<>);
|
||||
|
||||
List<Type> newRunnerTypes = new List<Type>();
|
||||
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<Guid, Type>();
|
||||
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<TInterface>() 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<TInterface>.Init(runnerType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface IEcsRunner { }
|
||||
|
||||
public abstract class EcsRunner<TInterface> : IEcsProcessor, IEcsRunner
|
||||
@ -79,11 +135,11 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
Type interfaceType = typeof(TInterface);
|
||||
|
||||
IEnumerable<TInterface> newTargets = targets.OfType<TInterface>();
|
||||
IEnumerable<IEcsProcessor> newTargets;
|
||||
|
||||
if (filter != null)
|
||||
{
|
||||
newTargets = newTargets.Where(o =>
|
||||
newTargets = targets.Where(o =>
|
||||
{
|
||||
if (o is TInterface == false) return false;
|
||||
var atr = o.GetType().GetCustomAttribute<EcsRunnerFilterAttribute>();
|
||||
@ -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<EcsRunnerFilterAttribute>();
|
||||
@ -100,20 +156,25 @@ namespace DCFApixels.DragonECS
|
||||
});
|
||||
}
|
||||
|
||||
return Instantiate(newTargets.ToArray());
|
||||
return Instantiate(newTargets.Select(o => (TInterface)o).ToArray());
|
||||
}
|
||||
public static TInterface Instantiate(IEnumerable<IEcsProcessor> targets)
|
||||
{
|
||||
return Instantiate(targets.OfType<TInterface>().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<TInterface>();
|
||||
|
||||
var instance = (EcsRunner<TInterface>)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<TInterface> Set(TInterface[] targets)
|
||||
|
@ -6,26 +6,23 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public class TestSystem :
|
||||
IReceive<_OnInject<SharedData>>,
|
||||
IDo<_Init>, IDo<_Run>, IDo<_Destroy>
|
||||
public class TestSystem :
|
||||
IEcsInject<SharedData>,
|
||||
IEcsSimpleCycleSystem
|
||||
{
|
||||
private SharedData _sharedData;
|
||||
void IReceive<_OnInject<SharedData>>.Do(EcsSession session, in _OnInject<SharedData> 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)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user