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

View File

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