add debug locking of pools

This commit is contained in:
Mikhail 2024-11-04 07:36:42 +08:00
parent 8a175399db
commit ce6fdfa33a
4 changed files with 76 additions and 3 deletions

View File

@ -13,6 +13,7 @@ namespace DCFApixels.DragonECS
private int _poolsCount; private int _poolsCount;
internal IEcsPoolImplementation[] _pools; internal IEcsPoolImplementation[] _pools;
internal PoolSlot[] _poolSlots; internal PoolSlot[] _poolSlots;
private int _lockedPoolCount = 0;
private readonly PoolsMediator _poolsMediator; private readonly PoolsMediator _poolsMediator;
@ -360,11 +361,59 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region LockPool/UnLockPool
public void LockPool_Debug(int ComponentTypeID)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
ref var slot = ref _poolSlots[ComponentTypeID];
if (slot.locked == false)
{
slot.locked = true;
if (_lockedPoolCount == 0)
{
ReleaseDelEntityBufferAll();
}
_lockedPoolCount++;
_pools[ComponentTypeID].OnLockedChanged_Debug(true);
}
#endif
}
public void UnlockPool_Debug(int ComponentTypeID)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
ref var slot = ref _poolSlots[ComponentTypeID];
if (slot.locked == true)
{
slot.locked = false;
_lockedPoolCount--;
if (_lockedPoolCount < 0)
{
_lockedPoolCount = 0;
Throw.UndefinedException();
}
_pools[ComponentTypeID].OnLockedChanged_Debug(false);
}
#endif
}
public bool CheckPoolLocked_Debug(int ComponentTypeID)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
return _poolSlots[ComponentTypeID].locked;
#else
return false;
#endif
}
#endregion
#region PoolSlot #region PoolSlot
internal struct PoolSlot internal struct PoolSlot
{ {
public int count; public int count;
public long version; public long version;
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
public bool locked;
#endif
} }
#endregion #endregion
} }

View File

@ -47,6 +47,7 @@ namespace DCFApixels.DragonECS
private readonly List<IEcsPoolEventListener> _listeners = new List<IEcsPoolEventListener>(); private readonly List<IEcsPoolEventListener> _listeners = new List<IEcsPoolEventListener>();
private int _listenersCachedCount = 0; private int _listenersCachedCount = 0;
#endif #endif
private bool _isLocked;
private EcsWorld.PoolsMediator _mediator; private EcsWorld.PoolsMediator _mediator;
@ -83,6 +84,7 @@ namespace DCFApixels.DragonECS
ref int itemIndex = ref _mapping[entityID]; ref int itemIndex = ref _mapping[entityID];
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (itemIndex > 0) { EcsPoolThrowHalper.ThrowAlreadyHasComponent<T>(entityID); } if (itemIndex > 0) { EcsPoolThrowHalper.ThrowAlreadyHasComponent<T>(entityID); }
if (_isLocked) { EcsPoolThrowHalper.ThrowPoolLocked(); }
#endif #endif
if (_recycledItemsCount > 0) if (_recycledItemsCount > 0)
{ {
@ -127,7 +129,10 @@ namespace DCFApixels.DragonECS
{ {
ref int itemIndex = ref _mapping[entityID]; ref int itemIndex = ref _mapping[entityID];
if (itemIndex <= 0) if (itemIndex <= 0)
{ { //Add block
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_isLocked) { EcsPoolThrowHalper.ThrowPoolLocked(); }
#endif
if (_recycledItemsCount > 0) if (_recycledItemsCount > 0)
{ {
itemIndex = _recycledItems[--_recycledItemsCount]; itemIndex = _recycledItems[--_recycledItemsCount];
@ -146,7 +151,7 @@ namespace DCFApixels.DragonECS
#if !DISABLE_POOLS_EVENTS #if !DISABLE_POOLS_EVENTS
_listeners.InvokeOnAdd(entityID, _listenersCachedCount); _listeners.InvokeOnAdd(entityID, _listenersCachedCount);
#endif #endif
} } //Add block end
#if !DISABLE_POOLS_EVENTS #if !DISABLE_POOLS_EVENTS
_listeners.InvokeOnGet(entityID, _listenersCachedCount); _listeners.InvokeOnGet(entityID, _listenersCachedCount);
#endif #endif
@ -159,6 +164,9 @@ namespace DCFApixels.DragonECS
} }
public void Del(int entityID) public void Del(int entityID)
{ {
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_isLocked) { EcsPoolThrowHalper.ThrowPoolLocked(); }
#endif
ref int itemIndex = ref _mapping[entityID]; ref int itemIndex = ref _mapping[entityID];
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (itemIndex <= 0) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); } if (itemIndex <= 0) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); }
@ -200,6 +208,9 @@ namespace DCFApixels.DragonECS
public void ClearAll() public void ClearAll()
{ {
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_isLocked) { EcsPoolThrowHalper.ThrowPoolLocked(); }
#endif
var span = _source.Where(out SingleAspect<EcsPool<T>> _); var span = _source.Where(out SingleAspect<EcsPool<T>> _);
_itemsCount = 0; _itemsCount = 0;
_recycledItemsCount = 0; _recycledItemsCount = 0;
@ -244,6 +255,7 @@ namespace DCFApixels.DragonECS
TryDel(entityID); TryDel(entityID);
} }
} }
void IEcsPoolImplementation.OnLockedChanged_Debug(bool locked) { _isLocked = locked; }
#endregion #endregion
#region Other #region Other

View File

@ -14,6 +14,7 @@ namespace DCFApixels.DragonECS.PoolsCore
void OnWorldResize(int newSize); void OnWorldResize(int newSize);
void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer); void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer);
void OnWorldDestroy(); void OnWorldDestroy();
void OnLockedChanged_Debug(bool locked);
#endregion #endregion
} }
@ -43,6 +44,10 @@ namespace DCFApixels.DragonECS.PoolsCore
{ {
throw new ArgumentNullException("listener is null"); throw new ArgumentNullException("listener is null");
} }
public static void ThrowPoolLocked()
{
throw new EcsFrameworkException("The pool is currently locked and cannot add or remove components.");
}
} }
} }
@ -56,7 +61,6 @@ namespace DCFApixels.DragonECS.Internal
public sealed class EcsNullPool : IEcsPoolImplementation<NullComponent> public sealed class EcsNullPool : IEcsPoolImplementation<NullComponent>
{ {
public static readonly EcsNullPool instance = new EcsNullPool(); public static readonly EcsNullPool instance = new EcsNullPool();
#region Properties #region Properties
int IEcsReadonlyPool.ComponentTypeID { get { return 0; } }//TODO Првоерить что NullComponent всегда имеет id 0 int IEcsReadonlyPool.ComponentTypeID { get { return 0; } }//TODO Првоерить что NullComponent всегда имеет id 0
Type IEcsReadonlyPool.ComponentType { get { return typeof(NullComponent); } } Type IEcsReadonlyPool.ComponentType { get { return typeof(NullComponent); } }
@ -131,6 +135,7 @@ namespace DCFApixels.DragonECS.Internal
void IEcsPoolImplementation.OnWorldDestroy() { } void IEcsPoolImplementation.OnWorldDestroy() { }
void IEcsPoolImplementation.OnWorldResize(int newSize) { } void IEcsPoolImplementation.OnWorldResize(int newSize) { }
void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer) { } void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer) { }
void IEcsPoolImplementation.OnLockedChanged_Debug(bool locked) { }
#endregion #endregion
#region Listeners #region Listeners

View File

@ -41,6 +41,7 @@ namespace DCFApixels.DragonECS
private List<IEcsPoolEventListener> _listeners = new List<IEcsPoolEventListener>(); private List<IEcsPoolEventListener> _listeners = new List<IEcsPoolEventListener>();
private int _listenersCachedCount = 0; private int _listenersCachedCount = 0;
#endif #endif
private bool _isLocked;
private T _fakeComponent; private T _fakeComponent;
private EcsWorld.PoolsMediator _mediator; private EcsWorld.PoolsMediator _mediator;
@ -92,6 +93,7 @@ namespace DCFApixels.DragonECS
{ {
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (Has(entityID)) { EcsPoolThrowHalper.ThrowAlreadyHasComponent<T>(entityID); } if (Has(entityID)) { EcsPoolThrowHalper.ThrowAlreadyHasComponent<T>(entityID); }
if (_isLocked) { EcsPoolThrowHalper.ThrowPoolLocked(); }
#endif #endif
_count++; _count++;
_mapping[entityID] = true; _mapping[entityID] = true;
@ -116,6 +118,7 @@ namespace DCFApixels.DragonECS
{ {
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); } if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); }
if (_isLocked) { EcsPoolThrowHalper.ThrowPoolLocked(); }
#endif #endif
_mapping[entityID] = false; _mapping[entityID] = false;
_count--; _count--;
@ -174,6 +177,9 @@ namespace DCFApixels.DragonECS
public void ClearAll() public void ClearAll()
{ {
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_isLocked) { EcsPoolThrowHalper.ThrowPoolLocked(); }
#endif
var span = _source.Where(out SingleAspect<EcsTagPool<T>> _); var span = _source.Where(out SingleAspect<EcsTagPool<T>> _);
_count = 0; _count = 0;
foreach (var entityID in span) foreach (var entityID in span)
@ -214,6 +220,7 @@ namespace DCFApixels.DragonECS
TryDel(entityID); TryDel(entityID);
} }
} }
void IEcsPoolImplementation.OnLockedChanged_Debug(bool locked) { _isLocked = locked; }
#endregion #endregion
#region Other #region Other