update EcsPool.ToSpan

This commit is contained in:
DCFApixels 2025-04-24 08:19:58 +08:00
parent 4a5ac65b4a
commit 1ee27d7013

View File

@ -5,11 +5,11 @@ using DCFApixels.DragonECS.Core;
using DCFApixels.DragonECS.Internal; using DCFApixels.DragonECS.Internal;
using DCFApixels.DragonECS.PoolsCore; using DCFApixels.DragonECS.PoolsCore;
using System; using System;
using System.Linq;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
#if ENABLE_IL2CPP #if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices; using Unity.IL2CPP.CompilerServices;
@ -193,19 +193,30 @@ namespace DCFApixels.DragonECS
} }
public void Del(int entityID) public void Del(int entityID)
{ {
ref int itemIndex = ref _mapping[entityID]; ref int removedItemIndex = ref _mapping[entityID];
#if DEBUG #if DEBUG
if (itemIndex <= 0) { EcsPoolThrowHelper.ThrowNotHaveComponent<T>(entityID); } if (removedItemIndex <= 0) { EcsPoolThrowHelper.ThrowNotHaveComponent<T>(entityID); }
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
#elif DRAGONECS_STABILITY_MODE #elif DRAGONECS_STABILITY_MODE
if (itemIndex <= 0) { return; } if (itemIndex <= 0) { return; }
if (_isLocked) { return; } if (_isLocked) { return; }
#endif #endif
DisableComponent(ref _items[itemIndex]); DisableComponent(ref _items[removedItemIndex]);
//_sparseEntities[itemIndex] = 0;
_table[itemIndex] = 0; _denseEntitiesDelayePtr--;
itemIndex = 0; _recycledCount++;
_itemsCount--; _itemsCount--;
var movedEntityID = _table[_denseEntitiesDelayePtr];
var removedDenseIndex = _table[removedItemIndex];
_table[_mapping[movedEntityID]] = removedDenseIndex;
_table[_denseEntitiesDelayePtr] = removedItemIndex;
_table[removedDenseIndex] = movedEntityID;
//_table[removedItemIndex] = 0;
removedItemIndex = 0;
_mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit); _mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit);
_isDenseEntitiesDelayedValid = false; _isDenseEntitiesDelayedValid = false;
#if !DISABLE_POOLS_EVENTS #if !DISABLE_POOLS_EVENTS
@ -357,7 +368,6 @@ namespace DCFApixels.DragonECS
return _source.Entities; return _source.Entities;
} }
#endif #endif
UpdateDenseEntities();
var span = new EcsSpan(_source.ID, _table, 1 + _capacity, _itemsCount); var span = new EcsSpan(_source.ID, _table, 1 + _capacity, _itemsCount);
#if DRAGONECS_DEEP_DEBUG #if DRAGONECS_DEEP_DEBUG
if (DCFApixels.DragonECS.UncheckedCore.UncheckedCoreUtility.CheckSpanValideDebug(span) == false) if (DCFApixels.DragonECS.UncheckedCore.UncheckedCoreUtility.CheckSpanValideDebug(span) == false)
@ -367,78 +377,21 @@ namespace DCFApixels.DragonECS
#endif #endif
return span; return span;
} }
private unsafe void UpdateDenseEntities()
{
if (_isDenseEntitiesDelayedValid) { return; }
_denseEntitiesDelayePtr = 1 + _capacity;
_table[_capacity] = 0;
_recycledCount = 0;
for (int i = 1, jRight = _itemsCount + 1 + _capacity, max = _itemsCount | _capacity; _denseEntitiesDelayePtr <= max; i++)
{
if (_table[i] == 0)
{
_table[jRight] = i;
jRight++;
_recycledCount++;
}
else
{
_table[_denseEntitiesDelayePtr++] = _table[i];
}
}
#if DRAGONECS_DEEP_DEBUG
_lockToSpan = true;
//if (_denseEntitiesDelayed[0] != 0)
if (_table[_capacity] != 0)
{
Throw.UndefinedException();
}
if (_denseEntitiesDelayePtr != _itemsCount + 1 + _capacity)
{
Throw.UndefinedException();
}
int coreCount = _mediator.GetComponentCount(_componentTypeID);
if (coreCount != _itemsCount)
{
Throw.UndefinedException();
}
using (_source.DisableAutoReleaseDelEntBuffer()) using (var group = EcsGroup.New(_source))
{
EcsStaticMask.Inc<T>().Build().ToMask(_source).GetIterator().IterateTo(World.Entities, group);
var span = new EcsSpan(_source.ID, _table, 1 + _capacity, _itemsCount);
if (group.SetEquals(span) == false)
{
Throw.UndefinedException();
}
}
_lockToSpan = false;
for (int i = _denseEntitiesDelayePtr; i < _denseEntitiesDelayePtr + _recycledCount; i++)
{
var index = _table[i];
if (_table[index] != 0)
{
Throw.UndefinedException();
}
}
#endif
_isDenseEntitiesDelayedValid = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetFreeItemIndex(int entityID) private int GetFreeItemIndex(int entityID)
{ {
if (_denseEntitiesDelayePtr == _table.Length) _itemsCount++;
{
UpdateDenseEntities(); int before_recycledCount = _recycledCount;
if (_itemsCount + 1 == _capacity)
{
Resize(_items.Length << 1);
}
}
int result = 0; int result = 0;
if (_recycledCount == 0) if (_recycledCount == 0)
{ {
if (_itemsCount == _capacity)
{
Resize(_items.Length << 1);
}
result = _denseEntitiesDelayePtr - _capacity; result = _denseEntitiesDelayePtr - _capacity;
} }
else else
@ -448,10 +401,10 @@ namespace DCFApixels.DragonECS
} }
#if DRAGONECS_DEEP_DEBUG #if DRAGONECS_DEEP_DEBUG
if (_table[result] != 0) //if (_table[result] != 0)//так как не отчищается, то не может быть истинной
{ //{
Throw.UndefinedException(); // Throw.UndefinedException();
} //}
if (result == 0) if (result == 0)
{ {
Throw.UndefinedException(); Throw.UndefinedException();
@ -462,8 +415,9 @@ namespace DCFApixels.DragonECS
} }
#endif #endif
_table[result] = _table[_denseEntitiesDelayePtr] = entityID; _table[result] = _denseEntitiesDelayePtr;
_itemsCount++; _table[_denseEntitiesDelayePtr] = entityID;
_denseEntitiesDelayePtr++; _denseEntitiesDelayePtr++;
return result; return result;
} }
@ -472,23 +426,29 @@ namespace DCFApixels.DragonECS
{ {
if (newSize <= _capacity) { return; } if (newSize <= _capacity) { return; }
//ArrayUtility.ResizeOrCreate(ref _sparseEntities, newSize);
//ArrayUtility.ResizeOrCreate(ref _items, newSize);
//_denseEntitiesDelayed = new int[newSize];
ArrayUtility.ResizeOrCreate(ref _items, newSize); ArrayUtility.ResizeOrCreate(ref _items, newSize);
var newTable = new int[newSize * 2]; var newTable = new int[newSize * 2];
if(_table != null) if(_table != null)
{ {
Array.Copy(_table, newTable, _table.Length / 2); for (int i = 0; i < _capacity; i++)
{
if (_table[i] == 0) { continue; }
_table[i] -= _capacity;
_table[i] += newSize;
} }
_table = newTable;
Array.Copy(_table, newTable, _capacity);
Array.Copy(_table, _capacity, newTable, newSize, _capacity);
_denseEntitiesDelayePtr -= _capacity;
_denseEntitiesDelayePtr += newSize;
}
else
{
_denseEntitiesDelayePtr = newSize + 1;
}
_table = newTable;
_capacity = newSize; _capacity = newSize;
_denseEntitiesDelayePtr = _capacity + 1;
//_denseEntitiesDelayedPtr = _capacity;
_isDenseEntitiesDelayedValid = false;
UpdateDenseEntities();
} }
#endregion #endregion