DragonECS/src/EcsWorld.pools.cs

477 lines
19 KiB
C#
Raw Normal View History

using DCFApixels.DragonECS.Internal;
using DCFApixels.DragonECS.PoolsCore;
using System;
using System.Linq;
using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS
{
public partial class EcsWorld
{
2025-03-11 09:46:00 +08:00
private SparseArray<int> _poolTypeCode_2_CmpTypeIDs = new SparseArray<int>();
private SparseArray<int> _cmpTypeCode_2_CmpTypeIDs = new SparseArray<int>();
2025-01-06 10:48:39 +08:00
internal IEcsPoolImplementation[] _pools;
2024-08-23 22:31:43 +08:00
internal PoolSlot[] _poolSlots;
2025-01-06 10:48:39 +08:00
private int _poolsCount;
2024-11-08 17:19:59 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
2024-11-04 07:36:42 +08:00
private int _lockedPoolCount = 0;
2024-11-08 17:19:59 +08:00
#endif
2024-01-01 21:44:33 +08:00
2024-02-15 18:11:24 +08:00
private readonly PoolsMediator _poolsMediator;
2024-08-23 22:31:43 +08:00
private EcsNullPool _nullPool = EcsNullPool.instance;
#region FindPoolInstance
public IEcsPool FindPoolInstance(int componentTypeID)
2024-02-25 00:55:30 +08:00
{
2024-04-22 17:09:06 +08:00
if (IsComponentTypeDeclared(componentTypeID))
{
return FindPoolInstance_Internal(componentTypeID);
2024-04-22 17:09:06 +08:00
}
return null;
2024-02-25 00:55:30 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public IEcsPool FindPoolInstance(Type componentType)
{
return FindPoolInstance_Internal(GetComponentTypeID(componentType));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private IEcsPool FindPoolInstance_Internal(int componentTypeID)
{
ref var result = ref _pools[componentTypeID];
if (result != _nullPool)
2024-02-24 03:02:41 +08:00
{
#if (DEBUG && !DISABLE_DEBUG)
if (result.ComponentTypeID != componentTypeID) { Throw.UndefinedException(); }
#endif
return result;
2024-02-24 03:02:41 +08:00
}
return null;
}
#endregion
#region GetPoolInstance
#if UNITY_2020_3_OR_NEWER
[UnityEngine.Scripting.Preserve]
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-07 03:30:18 +08:00
public TPool GetPoolInstance<TPool>() where TPool : IEcsPoolImplementation, new()
{
2024-10-03 08:20:22 +08:00
return Get<PoolCache<TPool>>().Instance;
}
#if UNITY_2020_3_OR_NEWER
[UnityEngine.Scripting.Preserve]
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-07 03:30:18 +08:00
public TPool GetPoolInstanceUnchecked<TPool>() where TPool : IEcsPoolImplementation, new()
{
2024-10-03 08:20:22 +08:00
return GetUnchecked<PoolCache<TPool>>().Instance;
}
#if UNITY_2020_3_OR_NEWER
[UnityEngine.Scripting.Preserve]
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TPool GetPoolInstance<TPool>(short worldID) where TPool : IEcsPoolImplementation, new()
{
2024-10-03 08:20:22 +08:00
return Get<PoolCache<TPool>>(worldID).Instance;
}
#if UNITY_2020_3_OR_NEWER
[UnityEngine.Scripting.Preserve]
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TPool GetPoolInstanceUnchecked<TPool>(short worldID) where TPool : IEcsPoolImplementation, new()
{
2024-10-03 08:20:22 +08:00
return GetUnchecked<PoolCache<TPool>>(worldID).Instance;
}
2024-12-03 17:44:16 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public GetPoolInstanceMarker GetPoolInstance()
{
return new GetPoolInstanceMarker(this);
}
#endregion
2024-02-14 21:13:00 +08:00
#region ComponentInfo
public int GetComponentTypeID<TComponent>()
{
2024-10-02 22:13:10 +08:00
return DeclareOrGetComponentTypeID(EcsTypeCodeManager.Get<TComponent>());
2024-02-14 21:13:00 +08:00
}
public int GetComponentTypeID(Type componentType)
{
2024-10-02 22:13:10 +08:00
return DeclareOrGetComponentTypeID(EcsTypeCodeManager.Get(componentType));
2024-02-14 21:13:00 +08:00
}
2024-12-03 16:59:32 +08:00
public Type GetComponentType(int componentTypeID)
{
return _pools[componentTypeID].ComponentType;
}
2024-02-14 21:13:00 +08:00
public bool IsComponentTypeDeclared<TComponent>()
{
2024-10-02 22:13:10 +08:00
return _cmpTypeCode_2_CmpTypeIDs.Contains((int)EcsTypeCodeManager.Get<TComponent>());
2024-02-14 21:13:00 +08:00
}
public bool IsComponentTypeDeclared(Type componentType)
{
2024-10-02 22:13:10 +08:00
return _cmpTypeCode_2_CmpTypeIDs.Contains((int)EcsTypeCodeManager.Get(componentType));
2024-02-14 21:13:00 +08:00
}
2024-12-03 16:59:32 +08:00
//TODO пересмотреть нейминг или функцию
2024-02-14 21:13:00 +08:00
public bool IsComponentTypeDeclared(int componentTypeID)
{
if (componentTypeID >= 0 && componentTypeID < _pools.Length)
{
return _pools[componentTypeID] != _nullPool;
}
return false;
}
#endregion
2024-02-24 03:30:23 +08:00
#region Declare
2024-10-02 22:13:10 +08:00
internal int DeclareOrGetComponentTypeID(EcsTypeCode componentTypeCode)
{
2024-10-02 22:13:10 +08:00
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue((int)componentTypeCode, out int ComponentTypeID) == false)
{
2024-02-14 21:13:00 +08:00
ComponentTypeID = _poolsCount++;
2024-10-02 22:13:10 +08:00
_cmpTypeCode_2_CmpTypeIDs.Add((int)componentTypeCode, ComponentTypeID);
}
2024-02-14 21:13:00 +08:00
return ComponentTypeID;
}
2024-10-02 22:13:10 +08:00
internal bool TryDeclareComponentTypeID(EcsTypeCode componentTypeCode, out int componentTypeID)
2024-02-24 03:02:41 +08:00
{
2024-10-02 22:13:10 +08:00
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue((int)componentTypeCode, out componentTypeID) == false)
2024-02-24 03:02:41 +08:00
{
componentTypeID = _poolsCount++;
2024-10-02 22:13:10 +08:00
_cmpTypeCode_2_CmpTypeIDs.Add((int)componentTypeCode, componentTypeID);
2024-02-24 03:02:41 +08:00
return true;
}
return false;
}
2024-02-24 03:30:23 +08:00
#endregion
2024-12-18 16:18:44 +08:00
#region FindOrAutoCreatePool/InitPool
public void InitPool(IEcsPoolImplementation poolImplementation)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (Count > 0) { Throw.World_MethodCalledAfterEntityCreation(nameof(InitEntitySlot)); }
#endif
InitPool_Internal(poolImplementation);
}
private TPool FindOrAutoCreatePool<TPool>() where TPool : IEcsPoolImplementation, new()
{
2025-01-06 10:48:39 +08:00
lock (_worldLock)
2024-12-18 16:18:44 +08:00
{
2025-01-06 10:48:39 +08:00
int poolTypeCode = (int)EcsTypeCodeManager.Get<TPool>();
if (_poolTypeCode_2_CmpTypeIDs.TryGetValue(poolTypeCode, out int cmpTypeID))
{
var pool = _pools[cmpTypeID];
2024-12-18 16:18:44 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
2025-01-06 10:48:39 +08:00
if ((pool is TPool) == false) { Throw.UndefinedException(); }
2024-12-18 16:18:44 +08:00
#endif
2025-01-06 10:48:39 +08:00
return (TPool)pool;
}
TPool newPool = new TPool();
InitPool_Internal(newPool);
return newPool;
2024-12-18 16:18:44 +08:00
}
}
private void InitPool_Internal(IEcsPoolImplementation newPool)
{
2024-09-09 18:21:21 +08:00
lock (_worldLock)
2024-02-14 21:13:00 +08:00
{
2024-12-18 16:18:44 +08:00
int poolTypeCode = (int)EcsTypeCodeManager.Get(newPool.GetType());
2024-09-09 18:21:21 +08:00
if (_poolTypeCode_2_CmpTypeIDs.Contains(poolTypeCode))
{
Throw.World_PoolAlreadyCreated();
}
2024-09-09 18:21:21 +08:00
Type componentType = newPool.ComponentType;
#if DEBUG //проверка соответсвия типов
#pragma warning disable IL2090 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The generic parameter of the source method or type does not have matching annotations.
2024-12-18 16:18:44 +08:00
if (componentType != newPool.GetType().GetInterfaces()
2024-09-09 18:21:21 +08:00
.First(o => o.IsGenericType && o.GetGenericTypeDefinition() == typeof(IEcsPoolImplementation<>))
.GetGenericArguments()[0])
{
Throw.Exception("A custom pool must implement the interface IEcsPoolImplementation<T> where T is the type that stores the pool.");
}
#pragma warning restore IL2090 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The generic parameter of the source method or type does not have matching annotations.
#endif
2024-10-02 22:13:10 +08:00
int componentTypeCode = (int)EcsTypeCodeManager.Get(componentType);
2024-09-09 18:21:21 +08:00
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue(componentTypeCode, out int componentTypeID))
{
_poolTypeCode_2_CmpTypeIDs[poolTypeCode] = componentTypeID;
}
else
{
componentTypeID = _poolsCount++;
_poolTypeCode_2_CmpTypeIDs[poolTypeCode] = componentTypeID;
_cmpTypeCode_2_CmpTypeIDs[componentTypeCode] = componentTypeID;
}
2024-09-09 18:21:21 +08:00
if (_poolsCount >= _pools.Length)
2024-02-14 21:13:00 +08:00
{
2024-09-09 18:21:21 +08:00
int oldCapacity = _pools.Length;
Array.Resize(ref _pools, _pools.Length << 1);
Array.Resize(ref _poolSlots, _pools.Length);
ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
int newEntityComponentMaskLength = CalcEntityComponentMaskLength(); //_pools.Length / COMPONENT_MASK_CHUNK_SIZE + 1;
int dif = newEntityComponentMaskLength - _entityComponentMaskLength;
if (dif > 0)
2024-02-16 21:17:20 +08:00
{
2024-09-09 18:21:21 +08:00
int[] newEntityComponentMasks = new int[_entitiesCapacity * newEntityComponentMaskLength];
int indxMax = _entityComponentMaskLength * _entitiesCapacity;
int indx = 0;
int newIndx = 0;
int nextIndx = _entityComponentMaskLength;
while (indx < indxMax)
2024-02-16 21:17:20 +08:00
{
2024-09-09 18:21:21 +08:00
while (indx < nextIndx)
{
newEntityComponentMasks[newIndx] = _entityComponentMasks[indx];
indx++;
newIndx++;
}
newIndx += dif;
nextIndx += _entityComponentMaskLength;
2024-02-16 21:17:20 +08:00
}
2024-09-09 18:21:21 +08:00
SetEntityComponentMaskLength(newEntityComponentMaskLength);
_entityComponentMasks = newEntityComponentMasks;
2024-02-16 21:17:20 +08:00
}
2024-09-09 18:21:21 +08:00
2024-02-14 21:13:00 +08:00
}
2024-02-16 21:17:20 +08:00
2024-09-09 18:21:21 +08:00
var oldPool = _pools[componentTypeID];
2024-09-09 18:21:21 +08:00
if (oldPool != _nullPool)
{
2024-11-06 19:55:33 +08:00
Throw.Exception("Attempt to initialize a pool with the indetifier of an already existing pool.");
2024-09-09 18:21:21 +08:00
}
2024-09-09 18:21:21 +08:00
_pools[componentTypeID] = newPool;
newPool.OnInit(this, _poolsMediator, componentTypeID);
2025-01-06 10:48:39 +08:00
OnPoolInitialized?.Invoke(newPool);
2024-02-24 16:59:09 +08:00
}
}
#endregion
2024-01-01 21:44:33 +08:00
#region Pools mediation
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-01-07 18:52:54 +08:00
private void RegisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
2024-01-01 21:44:33 +08:00
{
2024-03-01 22:02:36 +08:00
UpVersion();
2024-08-23 22:31:43 +08:00
ref PoolSlot slot = ref _poolSlots[componentTypeID];
slot.count++;
slot.version++;
2024-02-29 22:42:33 +08:00
_entities[entityID].componentsCount++;
2024-10-10 19:57:19 +08:00
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] |= maskBit.mask;
2024-01-01 21:44:33 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-01-07 18:52:54 +08:00
private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
2024-01-01 21:44:33 +08:00
{
2024-03-01 22:02:36 +08:00
UpVersion();
2024-08-23 22:31:43 +08:00
ref PoolSlot slot = ref _poolSlots[componentTypeID];
slot.count--;
slot.version++;
2024-02-29 22:42:33 +08:00
var count = --_entities[entityID].componentsCount;
2024-10-10 19:57:19 +08:00
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] &= ~maskBit.mask;
2024-02-13 21:13:46 +08:00
if (count == 0 && IsUsed(entityID))
{
DelEntity(entityID);
}
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (count < 0) Throw.World_InvalidIncrementComponentsBalance();
#endif
2024-01-01 21:44:33 +08:00
}
2024-02-23 20:44:11 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool TryRegisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
{
ref int entityLineStartIndex = ref _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex];
int newChunk = entityLineStartIndex | maskBit.mask;
if (entityLineStartIndex != newChunk)
2024-02-23 20:44:11 +08:00
{
2024-05-01 23:50:40 +08:00
UpVersion();
entityLineStartIndex = newChunk;
2024-08-23 22:31:43 +08:00
ref PoolSlot slot = ref _poolSlots[componentTypeID];
slot.count++;
slot.version++;
2024-02-29 22:42:33 +08:00
_entities[entityID].componentsCount++;
2024-02-23 20:44:11 +08:00
return true;
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool TryUnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
{
ref int entityLineStartIndex = ref _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex];
int newChunk = entityLineStartIndex & ~maskBit.mask;
if (entityLineStartIndex != newChunk)
2024-02-23 20:44:11 +08:00
{
2024-05-01 23:50:40 +08:00
UpVersion();
2024-08-23 22:31:43 +08:00
ref PoolSlot slot = ref _poolSlots[componentTypeID];
slot.count--;
slot.version++;
2024-02-29 22:42:33 +08:00
var count = --_entities[entityID].componentsCount;
entityLineStartIndex = newChunk;
2024-02-23 20:44:11 +08:00
if (count == 0 && IsUsed(entityID))
{
DelEntity(entityID);
}
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (count < 0) Throw.World_InvalidIncrementComponentsBalance();
#endif
return true;
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPoolComponentCount(int componentTypeID)
{
2024-08-23 22:31:43 +08:00
return _poolSlots[componentTypeID].count;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private long GetPoolVersion(int componentTypeID)
{
return _poolSlots[componentTypeID].version;
2024-02-23 20:44:11 +08:00
}
2024-01-01 21:44:33 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-01-07 18:52:54 +08:00
private bool HasEntityComponent(int entityID, EcsMaskChunck maskBit)
2024-01-01 21:44:33 +08:00
{
2024-10-10 19:57:19 +08:00
return (_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] & maskBit.mask) == maskBit.mask;
2024-01-01 21:44:33 +08:00
}
#endregion
#region PoolsMediator
public readonly struct PoolsMediator
{
2024-02-25 00:55:30 +08:00
public readonly EcsWorld World;
2024-01-01 21:44:33 +08:00
internal PoolsMediator(EcsWorld world)
{
2024-02-25 00:55:30 +08:00
if (world == null || world._poolsMediator.World != null)
2024-01-01 21:44:33 +08:00
{
2024-02-23 20:44:11 +08:00
throw new InvalidOperationException();
2024-01-01 21:44:33 +08:00
}
2024-02-25 00:55:30 +08:00
World = world;
2024-01-01 21:44:33 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-01-07 18:52:54 +08:00
public void RegisterComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
2024-01-01 21:44:33 +08:00
{
2024-02-25 00:55:30 +08:00
World.RegisterEntityComponent(entityID, componentTypeID, maskBit);
2024-01-01 21:44:33 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-01-07 18:52:54 +08:00
public void UnregisterComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
2024-01-01 21:44:33 +08:00
{
2024-02-25 00:55:30 +08:00
World.UnregisterEntityComponent(entityID, componentTypeID, maskBit);
2024-01-01 21:44:33 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-23 20:44:11 +08:00
public bool TryRegisterComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
{
2024-02-25 00:55:30 +08:00
return World.TryRegisterEntityComponent(entityID, componentTypeID, maskBit);
2024-02-23 20:44:11 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryUnregisterComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
{
2024-02-25 00:55:30 +08:00
return World.TryUnregisterEntityComponent(entityID, componentTypeID, maskBit);
2024-02-23 20:44:11 +08:00
}
2024-02-26 11:58:19 +08:00
2024-02-23 20:44:11 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetComponentCount(int componentTypeID)
{
2024-02-25 00:55:30 +08:00
return World.GetPoolComponentCount(componentTypeID);
2024-02-23 20:44:11 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-08-23 22:31:43 +08:00
public long GetVersion(int componentTypeID)
{
return World.GetPoolVersion(componentTypeID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-01-07 18:52:54 +08:00
public bool HasComponent(int entityID, EcsMaskChunck maskBit)
2024-01-01 21:44:33 +08:00
{
2024-02-25 00:55:30 +08:00
return World.HasEntityComponent(entityID, maskBit);
2024-01-01 21:44:33 +08:00
}
}
#endregion
2024-08-23 22:31:43 +08:00
2024-11-04 07:36:42 +08:00
#region LockPool/UnLockPool
2024-12-03 16:59:32 +08:00
public void LockPool_Debug(int componentTypeID)
2024-11-04 07:36:42 +08:00
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
2024-12-03 16:59:32 +08:00
ref var slot = ref _poolSlots[componentTypeID];
2024-12-04 16:10:09 +08:00
if (slot.lockedCounter == 0)
2024-11-04 07:36:42 +08:00
{
2024-12-04 16:10:09 +08:00
//очистка буффера, чтобы она рандомно не сработала в блоке блоикровки пула
ReleaseDelEntityBufferAll();
2024-11-04 07:36:42 +08:00
_lockedPoolCount++;
}
2024-12-04 16:10:09 +08:00
slot.lockedCounter++;
_pools[componentTypeID].OnLockedChanged_Debug(true);
2024-11-04 07:36:42 +08:00
#endif
}
2024-12-03 16:59:32 +08:00
public void UnlockPool_Debug(int componentTypeID)
2024-11-04 07:36:42 +08:00
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
2024-12-03 16:59:32 +08:00
ref var slot = ref _poolSlots[componentTypeID];
2024-12-04 16:10:09 +08:00
slot.lockedCounter--;
if (slot.lockedCounter <= 0)
2024-11-04 07:36:42 +08:00
{
_lockedPoolCount--;
2024-12-04 16:10:09 +08:00
if (_lockedPoolCount < 0 || slot.lockedCounter < 0)
2024-11-04 07:36:42 +08:00
{
_lockedPoolCount = 0;
2024-12-04 16:10:09 +08:00
slot.lockedCounter = 0;
2024-11-06 19:55:33 +08:00
Throw.OpeningClosingMethodsBalanceError();
2024-11-04 07:36:42 +08:00
}
}
2024-12-04 16:10:09 +08:00
_pools[componentTypeID].OnLockedChanged_Debug(false);
2024-11-04 07:36:42 +08:00
#endif
}
2024-12-03 16:59:32 +08:00
public bool CheckPoolLocked_Debug(int componentTypeID)
2024-11-04 07:36:42 +08:00
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
2024-12-04 16:10:09 +08:00
return _poolSlots[componentTypeID].lockedCounter != 0;
2024-11-04 07:36:42 +08:00
#else
return false;
#endif
}
#endregion
2024-12-03 16:59:32 +08:00
#region Utils
2024-08-23 22:31:43 +08:00
internal struct PoolSlot
{
public long version;
2024-12-04 16:10:09 +08:00
public int count;
2024-11-04 07:36:42 +08:00
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
2024-12-04 16:10:09 +08:00
public int lockedCounter;
2024-11-04 07:36:42 +08:00
#endif
2024-08-23 22:31:43 +08:00
}
2024-12-03 17:44:16 +08:00
public readonly ref struct GetPoolInstanceMarker
{
public readonly EcsWorld World;
public GetPoolInstanceMarker(EcsWorld world)
{
World = world;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TPool GetInstance<TPool>() where TPool : IEcsPoolImplementation, new()
{
return World.GetPoolInstance<TPool>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TPool GetInstanceUnchecked<TPool>() where TPool : IEcsPoolImplementation, new()
{
return World.GetPoolInstanceUnchecked<TPool>();
}
}
2024-08-23 22:31:43 +08:00
#endregion
2025-01-06 10:48:39 +08:00
#region Events
public delegate void OnPoolInitializedHandler(IEcsPool pool);
public event OnPoolInitializedHandler OnPoolInitialized;
#endregion
}
}