mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-19 02:24:37 +08:00
add virtual pool
This commit is contained in:
parent
fcc0d1ae97
commit
a7276ce966
@ -143,7 +143,7 @@ namespace DCFApixels.DragonECS
|
|||||||
_worldIdDispenser.Release(id);
|
_worldIdDispenser.Release(id);
|
||||||
_isDestroyed = true;
|
_isDestroyed = true;
|
||||||
_poolTypeCode_2_CmpTypeIDs = null;
|
_poolTypeCode_2_CmpTypeIDs = null;
|
||||||
_componentTypeCode_2_CmpTypeIDs = null;
|
_cmpTypeCode_2_CmpTypeIDs = null;
|
||||||
}
|
}
|
||||||
//public void Clear() { }
|
//public void Clear() { }
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -8,7 +8,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public partial class EcsWorld
|
public partial class EcsWorld
|
||||||
{
|
{
|
||||||
private SparseArray<int> _poolTypeCode_2_CmpTypeIDs = new SparseArray<int>();
|
private SparseArray<int> _poolTypeCode_2_CmpTypeIDs = new SparseArray<int>();
|
||||||
private SparseArray<int> _componentTypeCode_2_CmpTypeIDs = new SparseArray<int>();
|
private SparseArray<int> _cmpTypeCode_2_CmpTypeIDs = new SparseArray<int>();
|
||||||
private int _poolsCount;
|
private int _poolsCount;
|
||||||
internal IEcsPoolImplementation[] _pools;
|
internal IEcsPoolImplementation[] _pools;
|
||||||
internal int[] _poolComponentCounts;
|
internal int[] _poolComponentCounts;
|
||||||
@ -20,11 +20,20 @@ namespace DCFApixels.DragonECS
|
|||||||
#region Getters
|
#region Getters
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public TPool TestGetPool<TPool>() where TPool : IEcsPoolImplementation, new()
|
public IEcsPool GetPool(Type componentType)
|
||||||
|
//TODO. Есть проблема, возврат виртуального пула и последующая девиртуализация сделает ссылку невалидной. Одно из решений возвращать обертку
|
||||||
{
|
{
|
||||||
return Get<PoolCache<TPool>>().instance;
|
#if DEBUG
|
||||||
|
#endif
|
||||||
|
int componentTypeID = GetComponentTypeID(componentType);
|
||||||
|
ref var pool = ref _pools[componentTypeID];
|
||||||
|
if (pool == _nullPool)
|
||||||
|
{
|
||||||
|
pool = new EcsVirtualPool();
|
||||||
|
pool.OnInit(this, _poolsMediator, componentTypeID);
|
||||||
|
}
|
||||||
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if UNITY_2020_3_OR_NEWER
|
#if UNITY_2020_3_OR_NEWER
|
||||||
[UnityEngine.Scripting.Preserve]
|
[UnityEngine.Scripting.Preserve]
|
||||||
@ -71,11 +80,11 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public bool IsComponentTypeDeclared<TComponent>()
|
public bool IsComponentTypeDeclared<TComponent>()
|
||||||
{
|
{
|
||||||
return _componentTypeCode_2_CmpTypeIDs.Contains(EcsTypeCode.Get<TComponent>());
|
return _cmpTypeCode_2_CmpTypeIDs.Contains(EcsTypeCode.Get<TComponent>());
|
||||||
}
|
}
|
||||||
public bool IsComponentTypeDeclared(Type componentType)
|
public bool IsComponentTypeDeclared(Type componentType)
|
||||||
{
|
{
|
||||||
return _componentTypeCode_2_CmpTypeIDs.Contains(EcsTypeCode.Get(componentType));
|
return _cmpTypeCode_2_CmpTypeIDs.Contains(EcsTypeCode.Get(componentType));
|
||||||
}
|
}
|
||||||
public bool IsComponentTypeDeclared(int componentTypeID)
|
public bool IsComponentTypeDeclared(int componentTypeID)
|
||||||
{
|
{
|
||||||
@ -94,13 +103,23 @@ namespace DCFApixels.DragonECS
|
|||||||
#region Declare/Create
|
#region Declare/Create
|
||||||
private int DeclareOrGetComponentTypeID(int componentTypeCode)
|
private int DeclareOrGetComponentTypeID(int componentTypeCode)
|
||||||
{
|
{
|
||||||
if (!_componentTypeCode_2_CmpTypeIDs.TryGetValue(componentTypeCode, out int ComponentTypeID))
|
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue(componentTypeCode, out int ComponentTypeID) == false)
|
||||||
{
|
{
|
||||||
ComponentTypeID = _poolsCount++;
|
ComponentTypeID = _poolsCount++;
|
||||||
_componentTypeCode_2_CmpTypeIDs.Add(componentTypeCode, ComponentTypeID);
|
_cmpTypeCode_2_CmpTypeIDs.Add(componentTypeCode, ComponentTypeID);
|
||||||
}
|
}
|
||||||
return ComponentTypeID;
|
return ComponentTypeID;
|
||||||
}
|
}
|
||||||
|
private bool TryDeclareComponentTypeID(int componentTypeCode, out int componentTypeID)
|
||||||
|
{
|
||||||
|
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue(componentTypeCode, out componentTypeID) == false)
|
||||||
|
{
|
||||||
|
componentTypeID = _poolsCount++;
|
||||||
|
_cmpTypeCode_2_CmpTypeIDs.Add(componentTypeCode, componentTypeID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
private TPool CreatePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
private TPool CreatePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
||||||
{
|
{
|
||||||
int poolTypeCode = EcsTypeCode.Get<TPool>();
|
int poolTypeCode = EcsTypeCode.Get<TPool>();
|
||||||
@ -123,7 +142,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#endif
|
#endif
|
||||||
int componentTypeCode = EcsTypeCode.Get(componentType);
|
int componentTypeCode = EcsTypeCode.Get(componentType);
|
||||||
|
|
||||||
if (_componentTypeCode_2_CmpTypeIDs.TryGetValue(componentTypeCode, out int componentTypeID))
|
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue(componentTypeCode, out int componentTypeID))
|
||||||
{
|
{
|
||||||
_poolTypeCode_2_CmpTypeIDs[poolTypeCode] = componentTypeID;
|
_poolTypeCode_2_CmpTypeIDs[poolTypeCode] = componentTypeID;
|
||||||
}
|
}
|
||||||
@ -131,7 +150,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
componentTypeID = _poolsCount++;
|
componentTypeID = _poolsCount++;
|
||||||
_poolTypeCode_2_CmpTypeIDs[poolTypeCode] = componentTypeID;
|
_poolTypeCode_2_CmpTypeIDs[poolTypeCode] = componentTypeID;
|
||||||
_componentTypeCode_2_CmpTypeIDs[componentTypeCode] = componentTypeID;
|
_cmpTypeCode_2_CmpTypeIDs[componentTypeCode] = componentTypeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_poolsCount >= _pools.Length)
|
if (_poolsCount >= _pools.Length)
|
||||||
|
@ -210,6 +210,22 @@ namespace DCFApixels.DragonECS
|
|||||||
_entities = new int[capacity];
|
_entities = new int[capacity];
|
||||||
_itemsCount = 0;
|
_itemsCount = 0;
|
||||||
}
|
}
|
||||||
|
void IEcsPoolImplementation.OnDevirtualize(EcsVirtualPool.Data data)
|
||||||
|
{
|
||||||
|
if (_items.Length < data.ComponentsCount)
|
||||||
|
{
|
||||||
|
Array.Resize(ref _items, ArrayUtility.NormalizeSizeToPowerOfTwo(data.ComponentsCount));
|
||||||
|
}
|
||||||
|
foreach (var item in data.RawComponents)
|
||||||
|
{
|
||||||
|
_mapping[item.EntityID] = ++_itemsCount;
|
||||||
|
_items[_itemsCount] = (T)item.RawData;
|
||||||
|
}
|
||||||
|
foreach (var item in data.Listeners)
|
||||||
|
{
|
||||||
|
_listeners.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
||||||
{
|
{
|
||||||
Array.Resize(ref _mapping, newSize);
|
Array.Resize(ref _mapping, newSize);
|
||||||
@ -401,3 +417,54 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class HybridTypeMapping
|
||||||
|
{
|
||||||
|
private EcsWorld _world;
|
||||||
|
private Dictionary<Type, IEcsHybridPoolInternal> _declared = new Dictionary<Type, IEcsHybridPoolInternal>();
|
||||||
|
|
||||||
|
private HashSet<Type> _canInstantiatedTypes = new HashSet<Type>();
|
||||||
|
|
||||||
|
public void AddIntsanceType(object instance)
|
||||||
|
{
|
||||||
|
_canInstantiatedTypes.Add(instance.GetType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Declare<T>()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void Init()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//public abstract class HybridBranchBase { }
|
||||||
|
//public class HybridBranch<T> : HybridBranchBase
|
||||||
|
// where T : IEcsHybridComponent
|
||||||
|
//{
|
||||||
|
// private EcsHybridPool<T> _targetTypePool;
|
||||||
|
// public HybridBranch(EcsWorld source)
|
||||||
|
// {
|
||||||
|
// source.GetHybridPool<T>();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//public abstract class HybridNodeBase { }
|
||||||
|
//public class HybridNode<T> : HybridNodeBase
|
||||||
|
// where T : IEcsHybridComponent
|
||||||
|
//{
|
||||||
|
// private EcsHybridPool<T> _targetTypePool;
|
||||||
|
// public HybridNode(EcsWorld source)
|
||||||
|
// {
|
||||||
|
// source.GetHybridPool<T>();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
@ -178,6 +178,22 @@ namespace DCFApixels.DragonECS
|
|||||||
_items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(world.Config.Get_PoolComponentsCapacity())];
|
_items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(world.Config.Get_PoolComponentsCapacity())];
|
||||||
_itemsCount = 0;
|
_itemsCount = 0;
|
||||||
}
|
}
|
||||||
|
void IEcsPoolImplementation.OnDevirtualize(EcsVirtualPool.Data data)
|
||||||
|
{
|
||||||
|
if(_items.Length < data.ComponentsCount)
|
||||||
|
{
|
||||||
|
Array.Resize(ref _items, ArrayUtility.NormalizeSizeToPowerOfTwo(data.ComponentsCount));
|
||||||
|
}
|
||||||
|
foreach (var item in data.RawComponents)
|
||||||
|
{
|
||||||
|
_mapping[item.EntityID] = ++_itemsCount;
|
||||||
|
_items[_itemsCount] = (T)item.RawData;
|
||||||
|
}
|
||||||
|
foreach (var item in data.Listeners)
|
||||||
|
{
|
||||||
|
_listeners.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
||||||
{
|
{
|
||||||
Array.Resize(ref _mapping, newSize);
|
Array.Resize(ref _mapping, newSize);
|
||||||
|
@ -53,6 +53,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public interface IEcsPoolImplementation : IEcsPool
|
public interface IEcsPoolImplementation : IEcsPool
|
||||||
{
|
{
|
||||||
void OnInit(EcsWorld world, EcsWorld.PoolsMediator mediator, int componentTypeID);
|
void OnInit(EcsWorld world, EcsWorld.PoolsMediator mediator, int componentTypeID);
|
||||||
|
void OnDevirtualize(EcsVirtualPool.Data data);
|
||||||
void OnWorldResize(int newSize);
|
void OnWorldResize(int newSize);
|
||||||
void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer);
|
void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer);
|
||||||
void OnWorldDestroy();
|
void OnWorldDestroy();
|
||||||
@ -113,6 +114,10 @@ namespace DCFApixels.DragonECS
|
|||||||
void IEcsPool.SetRaw(int entity, object dataRaw) => 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, int toEntityID) => throw new NotImplementedException();
|
||||||
void IEcsPool.Copy(int fromEntityID, EcsWorld toWorld, int toEntityID) => throw new NotImplementedException();
|
void IEcsPool.Copy(int fromEntityID, EcsWorld toWorld, int toEntityID) => throw new NotImplementedException();
|
||||||
|
void IEcsPoolImplementation.OnDevirtualize(EcsVirtualPool.Data virtualPoolData)
|
||||||
|
{
|
||||||
|
Throw.UndefinedException();
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Callbacks
|
#region Callbacks
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using DCFApixels.DragonECS.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -158,6 +159,18 @@ namespace DCFApixels.DragonECS
|
|||||||
_mapping = new bool[world.Capacity];
|
_mapping = new bool[world.Capacity];
|
||||||
_count = 0;
|
_count = 0;
|
||||||
}
|
}
|
||||||
|
void IEcsPoolImplementation.OnDevirtualize(EcsVirtualPool.Data data)
|
||||||
|
{
|
||||||
|
_count = data.ComponentsCount;
|
||||||
|
foreach (var item in data.RawComponents)
|
||||||
|
{
|
||||||
|
_mapping[item.EntityID] = true;
|
||||||
|
}
|
||||||
|
foreach (var item in data.Listeners)
|
||||||
|
{
|
||||||
|
_listeners.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
||||||
{
|
{
|
||||||
Array.Resize(ref _mapping, newSize);
|
Array.Resize(ref _mapping, newSize);
|
||||||
|
301
src/Pools/EcsVirtualPool.cs
Normal file
301
src/Pools/EcsVirtualPool.cs
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
using DCFApixels.DragonECS;
|
||||||
|
using DCFApixels.DragonECS.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
public class EcsVirtualPool : 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<IEcsPoolEventListener> _listeners = new List<IEcsPoolEventListener>();
|
||||||
|
|
||||||
|
private EcsWorld.PoolsMediator _mediator;
|
||||||
|
|
||||||
|
#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; }
|
||||||
|
}
|
||||||
|
#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<int> 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 readonly ref struct Data
|
||||||
|
{
|
||||||
|
private readonly EcsVirtualPool _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(EcsVirtualPool target)
|
||||||
|
{
|
||||||
|
_target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly ref struct ListenersIterator
|
||||||
|
{
|
||||||
|
private readonly EcsVirtualPool _target;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public ListenersIterator(EcsVirtualPool target)
|
||||||
|
{
|
||||||
|
_target = target;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public List<IEcsPoolEventListener>.Enumerator GetEnumerator() { return _target._listeners.GetEnumerator(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly ref struct RawDataIterator
|
||||||
|
{
|
||||||
|
private readonly EcsVirtualPool _target;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public RawDataIterator(EcsVirtualPool 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;
|
||||||
|
[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[_entityID]); }
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
while (_entityID++ < _entitesCount)
|
||||||
|
{
|
||||||
|
if (_mapping[_entityID] != 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 EcsVirtualPool;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user