diff --git a/src/Pools/EcsInterfacePool.cs b/src/Pools/EcsInterfacePool.cs index 8455a7e..6975d19 100644 --- a/src/Pools/EcsInterfacePool.cs +++ b/src/Pools/EcsInterfacePool.cs @@ -7,12 +7,18 @@ using System.Threading.Tasks; namespace DCFApixels.DragonECS { + public interface IEcsInterfacePool : IEcsReadonlyPool where T : class { T Get(int entityID); } + internal interface IEcsInterfacePoolInternal + { + void Add(int entityID, object component); + void Del(int entityID); + } public interface IEcsInterfaceComponent { } - public class EcsInterfacePool : IEcsPoolImplementation, IEcsInterfacePool, IEnumerable //IEnumerable - IntelliSense hack + public class EcsInterfacePool : IEcsPoolImplementation, IEcsInterfacePool, IEcsInterfacePoolInternal, IEnumerable //IEnumerable - IntelliSense hack where T : class, IEcsInterfaceComponent { private EcsWorld _source; @@ -66,6 +72,17 @@ namespace DCFApixels.DragonECS } #endregion + #region IEcsInterfacePoolInternal + void IEcsInterfacePoolInternal.Add(int entityID, object component) + { + + } + void IEcsInterfacePoolInternal.Del(int entityID) + { + + } + #endregion + #region Other object IEcsReadonlyPool.GetRaw(int entityID) { @@ -125,3 +142,152 @@ namespace DCFApixels.DragonECS #endregion } } + + + + + + + + + + + +namespace DCFApixels.DragonECS.Internal +{ + internal readonly struct InterfacePoolGraphCmp : IEcsWorldComponent + { + public readonly InterfacePoolGraph Graph; + private InterfacePoolGraphCmp(EcsWorld world) + { + Graph = new InterfacePoolGraph(world); + } + public void Init(ref InterfacePoolGraphCmp component, EcsWorld world) + { + component = new InterfacePoolGraphCmp(world); + } + public void OnDestroy(ref InterfacePoolGraphCmp component, EcsWorld world) + { + component = default; + } + } + public class InterfacePoolGraph + { + private EcsWorld _world; + private Dictionary _branches = new Dictionary(); + + public InterfacePoolGraph(EcsWorld world) + { + _world = world; + } + + public bool IsInstantiable(Type type) + { + return _branches.ContainsKey(type); + } + public bool TryGetBranch(Type type, out InterfacePoolBranch branch) + { + return _branches.TryGetValue(type, out branch); + } + public void InitNewInterfacePool(IEcsHybridPoolInternal pool) + { + foreach (var pair in _branches) + { + var type = pair.Key; + var branch = pair.Value; + if (type.IsAssignableFrom(pool.ComponentType)) + { + if (type == pool.ComponentType) + { + branch.InitRootTypePool(pool); + } + else + { + branch.InitNewPool(pool); + } + } + } + } + + public InterfacePoolBranch GetBranch(Type targetType) + { + if (_branches.TryGetValue(targetType, out InterfacePoolBranch branch) == false) + { + branch = new InterfacePoolBranch(_world, targetType, null); + _branches.Add(targetType, branch); + } + return branch; + } + } + public class InterfacePoolBranch + { + private EcsWorld _world; + + private Type _rootComponentType; + private int _rootComponentTypeID; + private IEcsHybridPoolInternal _rootTypePool; + private List _relatedPools = new List(); + + private VirtualHybridPool _virtualPoolRef; + private bool _isVirtualPool = false; + + public bool IsVirtualPool + { + get { return _isVirtualPool; } + } + + public HybridPoolBranch(EcsWorld world, Type rootComponentType, IEcsHybridPoolInternal rootTypePool) + { + _world = world; + + _rootComponentType = rootComponentType; + _rootComponentTypeID = world.GetComponentTypeID(rootComponentType); + + if (rootTypePool == null) + { + _virtualPoolRef = new VirtualHybridPool(world, rootComponentType); + rootTypePool = _virtualPoolRef; + _isVirtualPool = true; + } + _rootTypePool = rootTypePool; + } + + + public void InitRootTypePool(IEcsHybridPoolInternal rootTypePool) + { + if (_isVirtualPool == false) + { + Throw.UndefinedException(); + } + _isVirtualPool = false; + rootTypePool.Devirtualize(_virtualPoolRef); + _rootTypePool = rootTypePool; + _virtualPoolRef = null; + } + public void InitNewPool(IEcsHybridPoolInternal pool) + { + _relatedPools.Add(pool); + } + + public void Set(int entityID, object component) + { + throw new NotImplementedException(); + } + public void Add(int entityID, object component) + { + _rootTypePool.AddRefInternal(entityID, component, true); + foreach (var pool in _relatedPools) + { + pool.AddRefInternal(entityID, component, false); + } + } + public void Del(int entityID) + { + _rootTypePool.DelInternal(entityID, true); + foreach (var pool in _relatedPools) + { + pool.DelInternal(entityID, false); + } + } + } +}