GetComponentTypeIDsFor optimization

This commit is contained in:
Mikhail 2024-11-07 16:16:47 +08:00
parent 4069f9b970
commit 09b209a7c0

View File

@ -687,7 +687,6 @@ namespace DCFApixels.DragonECS
}
#endregion
#endregion
#region DelEntBuffer
@ -912,15 +911,48 @@ namespace DCFApixels.DragonECS
int count = GetComponentTypeIDsFor_Internal(entityID, ref _componentIDsBuffer);
return new ReadOnlySpan<int>(_componentIDsBuffer, 0, count);
}
public void GetComponentPoolsFor(int entityID, List<IEcsPool> list)
public unsafe void GetComponentPoolsFor(int entityID, List<IEcsPool> list)
{
const int BUFFER_THRESHOLD = 100;
var count = GetComponentsCount(entityID);
if (count <= 0)
{
list.Clear();
return;
}
int* poolIdsPtr;
if (count < BUFFER_THRESHOLD)
{
int* ptr = stackalloc int[count];
poolIdsPtr = ptr;
}
else
{
poolIdsPtr = UnmanagedArrayUtility.New<int>(count);
}
GetComponentTypeIDsFor_Internal(entityID, poolIdsPtr, count);
if(list.Count != count)
{
list.Clear();
int count = GetComponentTypeIDsFor_Internal(entityID, ref _componentIDsBuffer);
for (int i = 0; i < count; i++)
{
list.Add(_pools[_componentIDsBuffer[i]]);
}
}
else
{
for (int i = 0; i < count; i++)
{
list[i] = _pools[_componentIDsBuffer[i]];
}
}
}
public void GetComponentsFor(int entityID, List<object> list)
{
list.Clear();
@ -952,10 +984,69 @@ namespace DCFApixels.DragonECS
}
if (itemsCount <= 0) { return 0; }
fixed (int* ptr = componentIDs)
const int COMPONENT_MASK_CHUNK_SIZE_HALF = COMPONENT_MASK_CHUNK_SIZE / 2;
// проверка на itemsCount <= 0 не обяательна, алгоритм не ломается,
// только впустую отрабатыват по всем чанкам,
// но как правильно для пустых сущностей этот алгоритм не применим.
int poolIndex = 0;
int bit;
int arrayIndex = 0;
for (int chunkIndex = entityID << _entityComponentMaskLengthBitShift,
chunkIndexMax = chunkIndex + _entityComponentMaskLength;
chunkIndex < chunkIndexMax;
chunkIndex++)
{
GetComponentTypeIDsFor_Internal(entityID, ptr, itemsCount);
int chunk = _entityComponentMasks[chunkIndex];
if (chunk == 0)
{
poolIndex += COMPONENT_MASK_CHUNK_SIZE;
}
else
{
if ((chunk & 0x0000FFFF) != 0)
{
bit = 0x0000_0001;
while (bit < 0x0001_0000)
{
if ((chunk & bit) != 0)
{
componentIDs[arrayIndex] = poolIndex;
itemsCount--;
if (itemsCount <= 0) { return itemsCount; }
}
poolIndex++;
bit <<= 1;
}
}
else
{
poolIndex += COMPONENT_MASK_CHUNK_SIZE_HALF;
}
if ((chunk & -0x7FFF0000) != 0)
{
bit = 0x0001_0000;
while (bit != 0x0000_0000)
{
if ((chunk & bit) != 0)
{
componentIDs[arrayIndex] = poolIndex;
itemsCount--;
if (itemsCount <= 0) { return itemsCount; }
}
poolIndex++;
bit <<= 1;
}
}
else
{
poolIndex += COMPONENT_MASK_CHUNK_SIZE_HALF;
}
}
}
return itemsCount;
}
private unsafe void GetComponentTypeIDsFor_Internal(int entityID, int* componentIDs, int itemsCount)