rework deleting empty entities

This commit is contained in:
DCFApixels 2025-03-31 12:02:19 +08:00
parent 2b4ec6377f
commit 3a9fed3c48
2 changed files with 48 additions and 7 deletions

View File

@ -65,6 +65,8 @@ namespace DCFApixels.DragonECS
private int[] _delEntBuffer = Array.Empty<int>(); private int[] _delEntBuffer = Array.Empty<int>();
private int _delEntBufferCount = 0; private int _delEntBufferCount = 0;
private int[] _emptyEntities = Array.Empty<int>();
private int _emptyEntitiesCount = 0;
private bool _isEnableAutoReleaseDelEntBuffer = true; private bool _isEnableAutoReleaseDelEntBuffer = true;
internal int _entityComponentMaskLength; internal int _entityComponentMaskLength;
@ -384,6 +386,7 @@ namespace DCFApixels.DragonECS
slot.gen |= GEN_SLEEP_MASK; slot.gen |= GEN_SLEEP_MASK;
} }
_entityListeners.InvokeOnNewEntity(entityID); _entityListeners.InvokeOnNewEntity(entityID);
MoveToEmptyEntities(entityID);
} }
@ -416,7 +419,7 @@ namespace DCFApixels.DragonECS
public void DelEntity(int entityID) public void DelEntity(int entityID)
{ {
#if DEBUG #if DEBUG
if (IsUsed(entityID) == false) { Throw.World_EntityIsAlreadyСontained(entityID); } if (IsUsed(entityID) == false) { Throw.World_EntityIsNotContained(entityID); }
#elif DRAGONECS_STABILITY_MODE #elif DRAGONECS_STABILITY_MODE
if (IsUsed(entityID) == false) { return; } if (IsUsed(entityID) == false) { return; }
#endif #endif
@ -426,6 +429,24 @@ namespace DCFApixels.DragonECS
_entitiesCount--; _entitiesCount--;
_entityListeners.InvokeOnDelEntity(entityID); _entityListeners.InvokeOnDelEntity(entityID);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void MoveToEmptyEntities(int entityID)
{
_emptyEntities[_emptyEntitiesCount++] = entityID;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool RemoveFromEmptyEntities(int entityID)
{
for (int i = _emptyEntitiesCount - 1; i >= 0; i--)
{
if(_emptyEntities[i] == entityID)
{
_emptyEntities[i] = _emptyEntities[--_emptyEntitiesCount];
return true;
}
}
return false;
}
#endregion #endregion
#region Other #region Other
@ -821,13 +842,24 @@ namespace DCFApixels.DragonECS
} }
public void ReleaseDelEntityBufferAll() public void ReleaseDelEntityBufferAll()
{ {
ReleaseDelEntityBuffer(_delEntBufferCount); ReleaseDelEntityBuffer(-1);
} }
public unsafe void ReleaseDelEntityBuffer(int count) public unsafe void ReleaseDelEntityBuffer(int count)
{ {
if (_delEntBufferCount <= 0) { return; } if (_emptyEntitiesCount <= 0 && _delEntBufferCount <= 0) { return; }
unchecked { _version++; } unchecked { _version++; }
for (int i = 0; i < _emptyEntitiesCount; i++)
{
TryDelEntity(_emptyEntities[i]);
}
_emptyEntitiesCount = 0;
if(count < 0)
{
count = _delEntBufferCount;
}
count = Math.Max(0, Math.Min(count, _delEntBufferCount)); count = Math.Max(0, Math.Min(count, _delEntBufferCount));
_delEntBufferCount -= count; _delEntBufferCount -= count;
int slisedCount = count; int slisedCount = count;
@ -907,6 +939,7 @@ namespace DCFApixels.DragonECS
SetEntityComponentMaskLength(CalcEntityComponentMaskLength()); //_pools.Length / COMPONENT_MASK_CHUNK_SIZE + 1; SetEntityComponentMaskLength(CalcEntityComponentMaskLength()); //_pools.Length / COMPONENT_MASK_CHUNK_SIZE + 1;
Array.Resize(ref _entities, newSize); Array.Resize(ref _entities, newSize);
Array.Resize(ref _delEntBuffer, newSize); Array.Resize(ref _delEntBuffer, newSize);
Array.Resize(ref _emptyEntities, newSize);
Array.Resize(ref _entityComponentMasks, newSize * _entityComponentMaskLength); Array.Resize(ref _entityComponentMasks, newSize * _entityComponentMaskLength);
ArrayUtility.Fill(_entities, EntitySlot.Empty, _entitiesCapacity); ArrayUtility.Fill(_entities, EntitySlot.Empty, _entitiesCapacity);

View File

@ -278,7 +278,11 @@ namespace DCFApixels.DragonECS
ref PoolSlot slot = ref _poolSlots[componentTypeID]; ref PoolSlot slot = ref _poolSlots[componentTypeID];
slot.count++; slot.count++;
slot.version++; slot.version++;
_entities[entityID].componentsCount++; var count = _entities[entityID].componentsCount++;
if (count == 0 && IsUsed(entityID))
{
RemoveFromEmptyEntities(entityID);
}
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] |= maskBit.mask; _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] |= maskBit.mask;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -293,7 +297,7 @@ namespace DCFApixels.DragonECS
if (count == 0 && IsUsed(entityID)) if (count == 0 && IsUsed(entityID))
{ {
DelEntity(entityID); MoveToEmptyEntities(entityID);
} }
CheckUnregisterValid(count, entityID); CheckUnregisterValid(count, entityID);
} }
@ -309,7 +313,11 @@ namespace DCFApixels.DragonECS
ref PoolSlot slot = ref _poolSlots[componentTypeID]; ref PoolSlot slot = ref _poolSlots[componentTypeID];
slot.count++; slot.count++;
slot.version++; slot.version++;
_entities[entityID].componentsCount++; var count = _entities[entityID].componentsCount++;
if(count == 0 && IsUsed(entityID))
{
RemoveFromEmptyEntities(entityID);
}
return true; return true;
} }
return false; return false;
@ -330,7 +338,7 @@ namespace DCFApixels.DragonECS
if (count == 0 && IsUsed(entityID)) if (count == 0 && IsUsed(entityID))
{ {
DelEntity(entityID); MoveToEmptyEntities(entityID);
} }
CheckUnregisterValid(count, entityID); CheckUnregisterValid(count, entityID);
return true; return true;