diff --git a/src/EcsWorld.pools.cs b/src/EcsWorld.pools.cs
index c1e71bf..5f07ede 100644
--- a/src/EcsWorld.pools.cs
+++ b/src/EcsWorld.pools.cs
@@ -18,10 +18,16 @@ namespace DCFApixels.DragonECS
private EcsNullPool _nullPool = EcsNullPool.instance;
#region Getters
+ public IEcsPool GetPool(int componentTypeID)
+ {
+#if DEBUG
+ if (_pools[componentTypeID].ComponentTypeID != componentTypeID) { Throw.UndefinedException(); }
+#endif
+ return _pools[componentTypeID];
+ }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public IEcsPool GetPool(Type componentType)
- //TODO. Есть проблема, возврат виртуального пула и последующая девиртуализация сделает ссылку невалидной. Одно из решений возвращать обертку
{
int componentTypeID = GetComponentTypeID(componentType);
ref var pool = ref _pools[componentTypeID];
@@ -276,45 +282,45 @@ namespace DCFApixels.DragonECS
#region PoolsMediator
public readonly struct PoolsMediator
{
- private readonly EcsWorld _world;
+ public readonly EcsWorld World;
internal PoolsMediator(EcsWorld world)
{
- if (world == null || world._poolsMediator._world != null)
+ if (world == null || world._poolsMediator.World != null)
{
throw new InvalidOperationException();
}
- _world = world;
+ World = world;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RegisterComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
{
- _world.RegisterEntityComponent(entityID, componentTypeID, maskBit);
+ World.RegisterEntityComponent(entityID, componentTypeID, maskBit);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void UnregisterComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
{
- _world.UnregisterEntityComponent(entityID, componentTypeID, maskBit);
+ World.UnregisterEntityComponent(entityID, componentTypeID, maskBit);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryRegisterComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
{
- return _world.TryRegisterEntityComponent(entityID, componentTypeID, maskBit);
+ return World.TryRegisterEntityComponent(entityID, componentTypeID, maskBit);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryUnregisterComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
{
- return _world.TryUnregisterEntityComponent(entityID, componentTypeID, maskBit);
+ return World.TryUnregisterEntityComponent(entityID, componentTypeID, maskBit);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetComponentCount(int componentTypeID)
{
- return _world.GetPoolComponentCount(componentTypeID);
+ return World.GetPoolComponentCount(componentTypeID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool HasComponent(int entityID, EcsMaskChunck maskBit)
{
- return _world.HasEntityComponent(entityID, maskBit);
+ return World.HasEntityComponent(entityID, maskBit);
}
}
#endregion
diff --git a/src/Pools/EcsHybridPool.cs b/src/Pools/EcsHybridPool.cs
index 26e40e8..ca3013e 100644
--- a/src/Pools/EcsHybridPool.cs
+++ b/src/Pools/EcsHybridPool.cs
@@ -1,4 +1,3 @@
-using DCFApixels.DragonECS;
using DCFApixels.DragonECS.Internal;
using System;
using System.Collections;
@@ -8,14 +7,6 @@ using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS
{
- namespace Internal
- {
- public interface IEcsHybridPoolInternal : IEcsPool
- {
- void AddRefInternal(int entityID, object component, bool isAppend);
- void DelInternal(int entityID, bool isAppend);
- }
- }
/// Pool for IEcsHybridComponent components
public sealed class EcsHybridPool : IEcsPoolImplementation, IEcsHybridPool, IEcsHybridPoolInternal, IEnumerable //IEnumerable - IntelliSense hack
where T : class, IEcsHybridComponent
@@ -36,6 +27,8 @@ namespace DCFApixels.DragonECS
private EcsWorld.PoolsMediator _mediator;
+ private HybridPoolGraph _graph;
+
#region Properites
public int Count
{
@@ -45,7 +38,7 @@ namespace DCFApixels.DragonECS
{
get { return _items.Length; }
}
- public int ComponentID
+ public int ComponentTypeID
{
get { return _componentTypeID; }
}
@@ -57,6 +50,10 @@ namespace DCFApixels.DragonECS
{
get { return _source; }
}
+ public bool IReadOnly
+ {
+ get { return false; }
+ }
#endregion
#region Methods
@@ -95,15 +92,20 @@ namespace DCFApixels.DragonECS
}
public void Add(int entityID, T component)
{
- HybridMapping mapping = _source.GetHybridMapping(component.GetType());
- mapping.GetTargetTypePool().AddRefInternal(entityID, component, true);
- foreach (var pool in mapping.GetPools())
- pool.AddRefInternal(entityID, component, false);
+ //HybridMapping mapping = _source.GetHybridMapping(component.GetType());
+ //mapping.GetTargetTypePool().AddRefInternal(entityID, component, true);
+ //foreach (var pool in mapping.GetPools())
+ //{
+ // pool.AddRefInternal(entityID, component, false);
+ //}
+ _graph.GetBranch(component.GetType()).Add(entityID, component);
}
public void Set(int entityID, T component)
{
if (Has(entityID))
+ {
Del(entityID);
+ }
Add(entityID, component);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -188,7 +190,9 @@ namespace DCFApixels.DragonECS
for (int i = _itemsCount - 1; i >= 0; i--)
{
if (!_items[i].IsAlive)
+ {
Del(_entities[i]);
+ }
}
}
#endregion
@@ -196,6 +200,8 @@ namespace DCFApixels.DragonECS
#region Callbacks
void IEcsPoolImplementation.OnInit(EcsWorld world, EcsWorld.PoolsMediator mediator, int componentTypeID)
{
+ _graph = world.Get().Graph;
+
_source = world;
_mediator = mediator;
_componentTypeID = componentTypeID;
@@ -224,7 +230,7 @@ namespace DCFApixels.DragonECS
#region Other
void IEcsPool.AddRaw(int entityID, object dataRaw) => Add(entityID, (T)dataRaw);
- object IEcsPool.GetRaw(int entityID) => Read(entityID);
+ object IEcsReadonlyPool.GetRaw(int entityID) => Read(entityID);
void IEcsPool.SetRaw(int entityID, object dataRaw) => Set(entityID, (T)dataRaw);
#endregion
@@ -245,6 +251,14 @@ namespace DCFApixels.DragonECS
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
#endregion
+
+ #region Devirtualize
+ void IEcsHybridPoolInternal.Devirtualize(VirtualHybridPool virtualHybridPool)
+ {
+ _mapping = virtualHybridPool._mapping;
+ _itemsCount = virtualHybridPool._itemsCount;
+ }
+ #endregion
}
/// Hybrid component
public interface IEcsHybridComponent
@@ -403,52 +417,150 @@ namespace DCFApixels.DragonECS
}
-public class HybridTypeMapping
+
+
+namespace DCFApixels.DragonECS.Internal
{
- private EcsWorld _world;
- private Dictionary _declared = new Dictionary();
-
- private Dictionary _canInstantiatedTypes = new Dictionary();
-
- public void AddIntsanceType(object instance)
+ internal interface IEcsHybridPoolInternal
{
- // _canInstantiatedTypes.Add(instance.GetType());
+ Type ComponentType { get; }
+ void AddRefInternal(int entityID, object component, bool isMain);
+ void DelInternal(int entityID, bool isMain);
+ void Devirtualize(VirtualHybridPool virtualHybridPool);
}
-
- public void Declare()
+ internal readonly struct HybridPoolGraphCmp : IEcsWorldComponent
{
-
+ public readonly HybridPoolGraph Graph;
+ private HybridPoolGraphCmp(EcsWorld world)
+ {
+ Graph = new HybridPoolGraph(world);
+ }
+ public void Init(ref HybridPoolGraphCmp component, EcsWorld world)
+ {
+ component = new HybridPoolGraphCmp(world);
+ }
+ public void OnDestroy(ref HybridPoolGraphCmp component, EcsWorld world)
+ {
+ component = default;
+ }
}
-
-
- private void Init()
+ public class HybridPoolGraph
{
+ private EcsWorld _world;
+ private Dictionary _branches = new Dictionary();
+ public HybridPoolGraph(EcsWorld world)
+ {
+ _world = world;
+ }
+
+ public bool IsInstantiable(Type type)
+ {
+ return _branches.ContainsKey(type);
+ }
+ public bool TryGetBranch(Type type, out HybridPoolBranch branch)
+ {
+ return _branches.TryGetValue(type, out branch);
+ }
+ public void InitNewPool(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 HybridPoolBranch GetBranch(Type targetType)
+ {
+ if (_branches.TryGetValue(targetType, out HybridPoolBranch branch) == false)
+ {
+ branch = new HybridPoolBranch(_world, targetType, null);
+ _branches.Add(targetType, branch);
+ }
+ return branch;
+ }
}
-}
+ public class HybridPoolBranch
+ {
+ 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 abstract class HybridBranchBase { }
-//public class HybridBranch : HybridBranchBase
-// where T : IEcsHybridComponent
-//{
-// private EcsHybridPool _targetTypePool;
-// public HybridBranch(EcsWorld source)
-// {
-// source.GetHybridPool();
-// }
-//}
-//
-//
-//
-//
-//public abstract class HybridNodeBase { }
-//public class HybridNode : HybridNodeBase
-// where T : IEcsHybridComponent
-//{
-// private EcsHybridPool _targetTypePool;
-// public HybridNode(EcsWorld source)
-// {
-// source.GetHybridPool();
-// }
-//}
+ 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);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Pools/EcsInterfacePool.cs b/src/Pools/EcsInterfacePool.cs
new file mode 100644
index 0000000..8455a7e
--- /dev/null
+++ b/src/Pools/EcsInterfacePool.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DCFApixels.DragonECS
+{
+ public interface IEcsInterfacePool : IEcsReadonlyPool where T : class
+ {
+ T Get(int entityID);
+ }
+ public interface IEcsInterfaceComponent { }
+ public class EcsInterfacePool : IEcsPoolImplementation, IEcsInterfacePool, IEnumerable //IEnumerable - IntelliSense hack
+ where T : class, IEcsInterfaceComponent
+ {
+ private EcsWorld _source;
+ private int _componentTypeID;
+
+ private int[] _mapping;// index = entityID / value = itemIndex;/ value = 0 = no entityID
+ private T[] _items; //dense
+ private int _itemsCount;
+ private int[] _recycledItems;
+ private int _recycledItemsCount;
+
+ private List _listeners = new List();
+
+ private EcsWorld.PoolsMediator _mediator;
+
+ #region Properties
+ public int ComponentTypeID
+ {
+ get { return _componentTypeID; }
+ }
+ public Type ComponentType
+ {
+ get { return typeof(T); }
+ }
+ public EcsWorld World
+ {
+ get { return _source; }
+ }
+ public int Count
+ {
+ get { return _itemsCount; }
+ }
+ public bool IReadOnly
+ {
+ get { return true; }
+ }
+ #endregion
+
+ #region Methdos
+ public T Get(int entityID)
+ {
+#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
+ if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent(entityID); }
+#endif
+ _listeners.InvokeOnGet(entityID);
+ return _items[_mapping[entityID]];
+ }
+ public bool Has(int entityID)
+ {
+ return _mapping[entityID] > 0;
+ }
+ #endregion
+
+ #region Other
+ object IEcsReadonlyPool.GetRaw(int entityID)
+ {
+ return Get(entityID);
+ }
+ public void Copy(int fromEntityID, int toEntityID) { }
+ public void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID) { }
+ void IEcsPool.AddRaw(int entityID, object dataRaw)
+ {
+ EcsDebug.PrintWarning("Is read only!");
+ }
+ void IEcsPool.SetRaw(int entityID, object dataRaw)
+ {
+ EcsDebug.PrintWarning("Is read only!");
+ }
+ void IEcsPool.Del(int entityID)
+ {
+ EcsDebug.PrintWarning("Is read only!");
+ }
+ #endregion
+
+ #region Callbacks
+ void IEcsPoolImplementation.OnInit(EcsWorld world, EcsWorld.PoolsMediator mediator, int componentTypeID)
+ {
+ throw new NotImplementedException();
+ }
+ void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan buffer)
+ {
+ throw new NotImplementedException();
+ }
+ void IEcsPoolImplementation.OnWorldResize(int newSize)
+ {
+ throw new NotImplementedException();
+ }
+ void IEcsPoolImplementation.OnWorldDestroy()
+ {
+ throw new NotImplementedException();
+ }
+ #endregion
+
+ #region Listeners
+ public void AddListener(IEcsPoolEventListener listener)
+ {
+ if (listener == null) { throw new ArgumentNullException("listener is null"); }
+ _listeners.Add(listener);
+ }
+ public void RemoveListener(IEcsPoolEventListener listener)
+ {
+ if (listener == null) { throw new ArgumentNullException("listener is null"); }
+ _listeners.Remove(listener);
+ }
+ #endregion
+
+ #region IEnumerator - IntelliSense hack
+ IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
+ IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
+ #endregion
+ }
+}
diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs
index e8f019c..a0b918e 100644
--- a/src/Pools/EcsPool.cs
+++ b/src/Pools/EcsPool.cs
@@ -38,7 +38,7 @@ namespace DCFApixels.DragonECS
{
get { return _items.Length; }
}
- public int ComponentID
+ public int ComponentTypeID
{
get { return _componentTypeID; }
}
@@ -50,6 +50,10 @@ namespace DCFApixels.DragonECS
{
get { return _source; }
}
+ public bool IReadOnly
+ {
+ get { return false; }
+ }
#endregion
#region Methods
@@ -194,7 +198,7 @@ namespace DCFApixels.DragonECS
#region Other
void IEcsPool.AddRaw(int entityID, object dataRaw) { Add(entityID) = (T)dataRaw; }
- object IEcsPool.GetRaw(int entityID) { return Get(entityID); }
+ object IEcsReadonlyPool.GetRaw(int entityID) { return Get(entityID); }
void IEcsPool.SetRaw(int entityID, object dataRaw) { Get(entityID) = (T)dataRaw; }
#endregion
diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs
index 97ca510..3329275 100644
--- a/src/Pools/EcsPoolBase.cs
+++ b/src/Pools/EcsPoolBase.cs
@@ -5,22 +5,19 @@ using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS
{
- public interface IEcsPool
+ public interface IEcsReadonlyPool
{
#region Properties
- int ComponentID { get; }
+ int ComponentTypeID { get; }
Type ComponentType { get; }
EcsWorld World { get; }
int Count { get; }
- int Capacity { get; } //TODO удалить. не во всех реализация нужен, проще привести к типу
+ bool IReadOnly { get; }
#endregion
#region Methods
bool Has(int entityID);
- void Del(int entityID);
- void AddRaw(int entityID, object dataRaw);
object GetRaw(int entityID);
- void SetRaw(int entityID, object dataRaw);
void Copy(int fromEntityID, int toEntityID);
void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID);
#endregion
@@ -30,6 +27,14 @@ namespace DCFApixels.DragonECS
void RemoveListener(IEcsPoolEventListener listener);
#endregion
}
+ public interface IEcsPool : IEcsReadonlyPool
+ {
+ #region Methods
+ void AddRaw(int entityID, object dataRaw);
+ void SetRaw(int entityID, object dataRaw);
+ void Del(int entityID);
+ #endregion
+ }
/// A pool for struct components.
public interface IEcsStructPool : IEcsPool where T: struct
{
@@ -98,21 +103,21 @@ namespace DCFApixels.DragonECS
public static readonly EcsNullPool instance = new EcsNullPool();
#region Properties
- int IEcsPool.ComponentID => -1;
- Type IEcsPool.ComponentType => typeof(NullComponent);
- EcsWorld IEcsPool.World => throw new NotImplementedException();
+ int IEcsReadonlyPool.ComponentTypeID => -1;
+ Type IEcsReadonlyPool.ComponentType => typeof(NullComponent);
+ EcsWorld IEcsReadonlyPool.World => throw new NotImplementedException();
public int Count => -1;
- public int Capacity => -1;
+ public bool IReadOnly { get { return true; } }
#endregion
#region Methods
- bool IEcsPool.Has(int index) => false;
+ bool IEcsReadonlyPool.Has(int index) => false;
void IEcsPool.Del(int entityID) => throw new NotImplementedException();
void IEcsPool.AddRaw(int entityID, object dataRaw) => throw new NotImplementedException();
- object IEcsPool.GetRaw(int entityID) => throw new NotImplementedException();
+ object IEcsReadonlyPool.GetRaw(int entityID) => throw new NotImplementedException();
void IEcsPool.SetRaw(int entity, object dataRaw) => throw new NotImplementedException();
- void IEcsPool.Copy(int fromEntityID, int toEntityID) => throw new NotImplementedException();
- void IEcsPool.Copy(int fromEntityID, EcsWorld toWorld, int toEntityID) => throw new NotImplementedException();
+ void IEcsReadonlyPool.Copy(int fromEntityID, int toEntityID) => throw new NotImplementedException();
+ void IEcsReadonlyPool.Copy(int fromEntityID, EcsWorld toWorld, int toEntityID) => throw new NotImplementedException();
#endregion
#region Callbacks
@@ -123,8 +128,8 @@ namespace DCFApixels.DragonECS
#endregion
#region Listeners
- void IEcsPool.AddListener(IEcsPoolEventListener listener) { }
- void IEcsPool.RemoveListener(IEcsPoolEventListener listener) { }
+ void IEcsReadonlyPool.AddListener(IEcsPoolEventListener listener) { }
+ void IEcsReadonlyPool.RemoveListener(IEcsPoolEventListener listener) { }
#endregion
}
}
diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs
index 775ceca..cdf9f33 100644
--- a/src/Pools/EcsTagPool.cs
+++ b/src/Pools/EcsTagPool.cs
@@ -46,11 +46,7 @@ namespace DCFApixels.DragonECS
{
get { return _count; }
}
- int IEcsPool.Capacity
- {
- get { return -1; }
- }
- public int ComponentID
+ public int ComponentTypeID
{
get { return _componentTypeID; }
}
@@ -62,6 +58,10 @@ namespace DCFApixels.DragonECS
{
get { return _source; }
}
+ public bool IReadOnly
+ {
+ get { return false; }
+ }
#endregion
#region Method
@@ -176,7 +176,7 @@ namespace DCFApixels.DragonECS
#region Other
void IEcsPool.AddRaw(int entityID, object dataRaw) { Add(entityID); }
- object IEcsPool.GetRaw(int entityID)
+ object IEcsReadonlyPool.GetRaw(int entityID)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (Has(entityID) == false) { EcsPoolThrowHalper.ThrowNotHaveComponent(entityID); }
diff --git a/src/Pools/Utils/VirtualHybridPool.cs b/src/Pools/Utils/VirtualHybridPool.cs
new file mode 100644
index 0000000..ede8fce
--- /dev/null
+++ b/src/Pools/Utils/VirtualHybridPool.cs
@@ -0,0 +1,168 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace DCFApixels.DragonECS.Internal
+{
+ internal class VirtualHybridPool : IEcsHybridPoolInternal
+ {
+ private EcsWorld _source;
+ private Type _componentType;
+
+ internal int[] _mapping;
+ internal object[] _items;
+ private int[] _entities;
+ internal int _itemsCount = 0;
+
+ internal int[] _recycledItems;
+ internal int _recycledItemsCount;
+
+ private bool _isDevirtualized = false;
+
+ #region Properties
+ public Type ComponentType
+ {
+ get { return _componentType; }
+ }
+ public EcsWorld World
+ {
+ get { return _source; }
+ }
+ public int Count
+ {
+ get { return _itemsCount; }
+ }
+ public int Capacity
+ {
+ get { return _mapping.Length; }
+ }
+ public bool IsDevirtualized
+ {
+ get { return _isDevirtualized; }
+ }
+ #endregion
+
+ #region Constructors
+ public VirtualHybridPool(EcsWorld world, Type componentType)
+ {
+ _source = world;
+ _componentType = componentType;
+
+ _mapping = new int[world.Capacity];
+ _recycledItems = new int[world.Config.Get_PoolRecycledComponentsCapacity()];
+ _recycledItemsCount = 0;
+ _items = new object[ArrayUtility.NormalizeSizeToPowerOfTwo(world.Config.Get_PoolComponentsCapacity())];
+ _itemsCount = 0;
+ }
+ #endregion
+
+ #region Callbacks
+ public void OnWorldResize(int newSize)
+ {
+ Array.Resize(ref _mapping, newSize);
+ }
+ #endregion
+
+ #region Methods
+ public void AddRaw(int entityID, object dataRaw)
+ {
+ ref int itemIndex = ref _mapping[entityID];
+#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
+ if (itemIndex > 0) { EcsPoolThrowHalper.ThrowAlreadyHasComponent(_componentType, entityID); }
+#endif
+ if (_recycledItemsCount > 0)
+ {
+ itemIndex = _recycledItems[--_recycledItemsCount];
+ _itemsCount++;
+ }
+ else
+ {
+ itemIndex = ++_itemsCount;
+ if (_itemsCount >= _items.Length)
+ {
+ Array.Resize(ref _items, _items.Length << 1);
+ }
+ }
+ _items[itemIndex] = dataRaw;
+ }
+ public bool TryAddRaw(int entityID, object dataRaw)
+ {
+ if (Has(entityID))
+ {
+ return false;
+ }
+ AddRaw(entityID, dataRaw);
+ return true;
+ }
+ public void SetRaw(int entityID, object dataRaw)
+ {
+#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
+ if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent(_componentType, entityID); }
+#endif
+ _items[_mapping[entityID]] = dataRaw;
+ }
+ public object GetRaw(int entityID)
+ {
+#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
+ if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent(_componentType, entityID); }
+#endif
+ return _items[_mapping[entityID]];
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool Has(int entityID)
+ {
+ return _mapping[entityID] > 0;
+ }
+ public void Del(int entityID)
+ {
+ ref int itemIndex = ref _mapping[entityID];
+#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
+ if (itemIndex <= 0) EcsPoolThrowHalper.ThrowNotHaveComponent(_componentType, entityID);
+#endif
+ _items[itemIndex] = null;
+ if (_recycledItemsCount >= _recycledItems.Length)
+ {
+ Array.Resize(ref _recycledItems, _recycledItems.Length << 1);
+ }
+ _recycledItems[_recycledItemsCount++] = itemIndex;
+ itemIndex = 0;
+ _itemsCount--;
+ }
+ public bool TryDel(int entityID)
+ {
+ if (Has(entityID))
+ {
+ Del(entityID);
+ return true;
+ }
+ return false;
+ }
+
+ public void Copy(int fromEntityID, int toEntityID)
+ {
+ throw new NotImplementedException();
+ }
+ public void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID)
+ {
+ Throw.Exception("Copying data to another world is not supported for virtual pools, devirtualize the pool first.");
+ }
+ #endregion
+
+ #region IEcsHybridPoolInternal
+ public void AddRefInternal(int entityID, object component, bool isMain)
+ {
+ AddRaw(entityID, component);
+ }
+ public void DelInternal(int entityID, bool isMain)
+ {
+ Del(entityID);
+ }
+ #endregion
+
+ #region Devirtualize
+ void IEcsHybridPoolInternal.Devirtualize(VirtualHybridPool virtualHybridPool)
+ {
+ Throw.UndefinedException();
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Pools/VirtualPool.cs b/src/Pools/VirtualPool.cs
deleted file mode 100644
index cda8df3..0000000
--- a/src/Pools/VirtualPool.cs
+++ /dev/null
@@ -1,314 +0,0 @@
-using DCFApixels.DragonECS;
-using DCFApixels.DragonECS.Internal;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-
-
-internal class VirtualPool : IEcsPoolImplementation, IEnumerable
-{
- private EcsWorld _source;
- private Type _componentType;
- private int _componentTypeID;
- private EcsMaskChunck _maskBit;
-
- private int[] _mapping;
- private object[] _items;
- private int _itemsCount = 0;
- private int[] _recycledItems;
- private int _recycledItemsCount;
-
- private List _listeners = new List();
-
- private EcsWorld.PoolsMediator _mediator;
-
- private bool _isDevirtualized = false;
-
- #region Properties
- public int ComponentID
- {
- get { return _componentTypeID; }
- }
- public Type ComponentType
- {
- get { return _componentType; }
- }
- public EcsWorld World
- {
- get { return _source; }
- }
- public int Count
- {
- get { return _itemsCount; }
- }
- public int Capacity
- {
- get { return _mapping.Length; }
- }
- public bool IsDevirtualized
- {
- get { return _isDevirtualized; }
- }
- #endregion
-
- #region Callbacks
- void IEcsPoolImplementation.OnInit(EcsWorld world, EcsWorld.PoolsMediator mediator, int componentTypeID)
- {
- _componentType = world.GetComponentType(componentTypeID);
-
- _source = world;
- _mediator = mediator;
- _componentTypeID = componentTypeID;
- _maskBit = EcsMaskChunck.FromID(componentTypeID);
-
- _mapping = new int[world.Capacity];
- _recycledItems = new int[world.Config.Get_PoolRecycledComponentsCapacity()];
- _recycledItemsCount = 0;
- _items = new object[ArrayUtility.NormalizeSizeToPowerOfTwo(world.Config.Get_PoolComponentsCapacity())];
- _itemsCount = 0;
- }
- void IEcsPoolImplementation.OnDevirtualize(Data data)
- {
- Throw.UndefinedException();
- }
- void IEcsPoolImplementation.OnWorldResize(int newSize)
- {
- Array.Resize(ref _mapping, newSize);
- }
- void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan buffer)
- {
- foreach (var entityID in buffer)
- {
- TryDel(entityID);
- }
- }
- void IEcsPoolImplementation.OnWorldDestroy() { }
- #endregion
-
- #region Methods
- public void AddRaw(int entityID, object dataRaw)
- {
- ref int itemIndex = ref _mapping[entityID];
-#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
- if (itemIndex > 0) { EcsPoolThrowHalper.ThrowAlreadyHasComponent(_componentType, entityID); }
-#endif
- if (_recycledItemsCount > 0)
- {
- itemIndex = _recycledItems[--_recycledItemsCount];
- _itemsCount++;
- }
- else
- {
- itemIndex = ++_itemsCount;
- if (_itemsCount >= _items.Length)
- {
- Array.Resize(ref _items, _items.Length << 1);
- }
- }
- _items[itemIndex] = dataRaw;
- _mediator.RegisterComponent(entityID, _componentTypeID, _maskBit);
- _listeners.InvokeOnAddAndGet(entityID);
- }
- public bool TryAddRaw(int entityID, object dataRaw)
- {
- if (Has(entityID))
- {
- return false;
- }
- AddRaw(entityID, dataRaw);
- return true;
- }
- public void SetRaw(int entityID, object dataRaw)
- {
-#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
- if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent(_componentType, entityID); }
-#endif
- _items[_mapping[entityID]] = dataRaw;
- }
- public object GetRaw(int entityID)
- {
-#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
- if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent(_componentType, entityID); }
-#endif
- _listeners.InvokeOnGet(entityID);
- return _items[_mapping[entityID]];
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool Has(int entityID)
- {
- return _mapping[entityID] > 0;
- }
- public void Del(int entityID)
- {
- ref int itemIndex = ref _mapping[entityID];
-#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
- if (itemIndex <= 0) EcsPoolThrowHalper.ThrowNotHaveComponent(_componentType, entityID);
-#endif
- _items[itemIndex] = null;
- if (_recycledItemsCount >= _recycledItems.Length)
- {
- Array.Resize(ref _recycledItems, _recycledItems.Length << 1);
- }
- _recycledItems[_recycledItemsCount++] = itemIndex;
- itemIndex = 0;
- _itemsCount--;
- _mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit);
- _listeners.InvokeOnDel(entityID);
- }
- public bool TryDel(int entityID)
- {
- if (Has(entityID))
- {
- Del(entityID);
- return true;
- }
- return false;
- }
-
- public void Copy(int fromEntityID, int toEntityID)
- {
- throw new NotImplementedException();
- }
- public void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID)
- {
- Throw.Exception("Copying data to another world is not supported for virtual pools, devirtualize the pool first.");
- }
- #endregion
-
- #region Listeners
- public void AddListener(IEcsPoolEventListener listener)
- {
- if (listener == null) { throw new ArgumentNullException("listener is null"); }
- _listeners.Add(listener);
- }
- public void RemoveListener(IEcsPoolEventListener listener)
- {
- if (listener == null) { throw new ArgumentNullException("listener is null"); }
- _listeners.Remove(listener);
- }
- #endregion
-
- #region IEnumerator - IntelliSense hack
- IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
- #endregion
-
- #region Devirtualization
- public Data GetDevirtualizationData()
- {
- return new Data(this);
- }
- public readonly ref struct Data
- {
- private readonly VirtualPool _target;
-
- public int ComponentsCount
- {
- get { return _target.Count; }
- }
- public RawDataIterator RawComponents
- {
- get { return new RawDataIterator(_target); }
- }
- public ListenersIterator Listeners
- {
- get { return new ListenersIterator(_target); }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Data(VirtualPool target)
- {
- _target = target;
- }
-
- public readonly ref struct ListenersIterator
- {
- private readonly VirtualPool _target;
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ListenersIterator(VirtualPool target)
- {
- _target = target;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public List.Enumerator GetEnumerator() { return _target._listeners.GetEnumerator(); }
- }
-
- public readonly ref struct RawDataIterator
- {
- private readonly VirtualPool _target;
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public RawDataIterator(VirtualPool target)
- {
- _target = target;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Enumerator GetEnumerator() { return new Enumerator(this); }
- public ref struct Enumerator
- {
- private readonly int[] _mapping;
- private readonly object[] _items;
- private readonly int _entitesCount;
- private int _entityID;
- private int _itemIndex;
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Enumerator(RawDataIterator devirtualizator)
- {
- _mapping = devirtualizator._target._mapping;
- _items = devirtualizator._target._items;
- _entitesCount = devirtualizator._target.World.Count + 1;
- if (_entitesCount > _mapping.Length)
- {
- _entitesCount = _mapping.Length;
- }
- _entityID = 0;
- }
- public EntityRawDataPair Current
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get { return new EntityRawDataPair(_entityID, _items[_itemIndex]); }
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool MoveNext()
- {
- while (_entityID++ < _entitesCount)
- {
- _itemIndex = _mapping[_entityID];
- if (_itemIndex != 0)
- {
- return true;
- }
- }
- return false;
- }
- }
- }
- }
- public readonly struct EntityRawDataPair
- {
- public readonly int EntityID;
- public readonly object RawData;
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public EntityRawDataPair(int entityID, object rawData)
- {
- EntityID = entityID;
- RawData = rawData;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Deconstruct(out int entityID, out object rawData)
- {
- entityID = EntityID;
- rawData = RawData;
- }
- }
- #endregion
-}
-
-
-
-public static class VirtualPoolExtensions
-{
- public static bool IsVirtual(this IEcsPool self)
- {
- return self is VirtualPool;
- }
-}
\ No newline at end of file