update copy clone move remove

This commit is contained in:
Mikhail 2024-11-06 18:27:33 +08:00
parent b60308ac7e
commit 51b623e2c5
3 changed files with 133 additions and 154 deletions

View File

@ -545,15 +545,15 @@ namespace DCFApixels.DragonECS
int maxEntites = int.MaxValue;
EcsMaskChunck* preSortingBuffer;
if (maxBufferSize > STACK_BUFFER_THRESHOLD)
{
preSortingBuffer = TempBuffer<EcsMaskChunck>.Get(maxBufferSize);
}
else
if (maxBufferSize < STACK_BUFFER_THRESHOLD)
{
EcsMaskChunck* ptr = stackalloc EcsMaskChunck[maxBufferSize];
preSortingBuffer = ptr;
}
else
{
preSortingBuffer = TempBuffer<EcsMaskChunck>.Get(maxBufferSize);
}
if (_sortIncChunckBuffer.Length > 1)
{
@ -879,7 +879,7 @@ namespace DCFApixels.DragonECS.Internal
#endif
internal unsafe class EcsMaskIteratorUtility
{
internal const int STACK_BUFFER_THRESHOLD = 256;
internal const int STACK_BUFFER_THRESHOLD = 100;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void ConvertToChuncks(EcsMaskChunck* ptr, UnsafeArray<int> input, UnsafeArray<EcsMaskChunck> output)

View File

@ -463,41 +463,35 @@ namespace DCFApixels.DragonECS
#region CopyEntity
public unsafe void CopyEntity(int fromEntityID, int toEntityID)
{
const int COMPONENT_MASK_CHUNK_SIZE_HALF = COMPONENT_MASK_CHUNK_SIZE / 2;
int entityLineStartIndex = fromEntityID << _entityComponentMaskLengthBitShift;
int poolIndexWithoutOffset = 0;
for (int i = 0; i < _entityComponentMaskLength; i++)
const int BUFFER_THRESHOLD = 100;
int count = GetComponentsCount(fromEntityID);
int* poolIdsPtr;
if (count < BUFFER_THRESHOLD)
{
int chunk = _entityComponentMasks[entityLineStartIndex + i];
if (chunk != 0)
int* ptr = stackalloc int[count];
poolIdsPtr = ptr;
}
else
{
if ((chunk & 0x0000FFFF) != 0)
poolIdsPtr = UnmanagedArrayUtility.New<int>(count);
}
UnsafeArray<int> ua = UnsafeArray<int>.Manual(poolIdsPtr, count);
GetComponentTypeIDsFor_Internal(fromEntityID, poolIdsPtr, count);
for (int i = 0; i < count; i++)
{
int bit = 1;
for (int j = 0; j < COMPONENT_MASK_CHUNK_SIZE_HALF; j++)
_pools[poolIdsPtr[i]].Copy(fromEntityID, toEntityID);
}
if (count >= BUFFER_THRESHOLD)
{
if ((bit & chunk) != 0)
{
_pools[poolIndexWithoutOffset + j].Copy(fromEntityID, toEntityID);
}
bit <<= 1;
}
}
if ((chunk & -0x7FFF0000) != 0)
{
int bit = 0x00010000;
for (int j = COMPONENT_MASK_CHUNK_SIZE_HALF; j < COMPONENT_MASK_CHUNK_SIZE; j++)
{
if ((bit & chunk) != 0)
{
_pools[poolIndexWithoutOffset + j].Copy(fromEntityID, toEntityID);
}
bit <<= 1;
}
}
}
poolIndexWithoutOffset += COMPONENT_MASK_CHUNK_SIZE;
UnmanagedArrayUtility.Free(poolIdsPtr);
}
//foreach (var pool in _pools)
//{
// if (pool.Has(fromEntityID))
@ -517,42 +511,32 @@ namespace DCFApixels.DragonECS
}
}
}
public void CopyEntity(int fromEntityID, EcsWorld toWorld, int toEntityID)
public unsafe void CopyEntity(int fromEntityID, EcsWorld toWorld, int toEntityID)
{
const int COMPONENT_MASK_CHUNK_SIZE_HALF = COMPONENT_MASK_CHUNK_SIZE / 2;
int entityLineStartIndex = fromEntityID << _entityComponentMaskLengthBitShift;
int poolIndexWithoutOffset = 0;
for (int i = 0; i < _entityComponentMaskLength; i++)
const int BUFFER_THRESHOLD = 100;
int count = GetComponentsCount(fromEntityID);
int* poolIdsPtr;
if (count < BUFFER_THRESHOLD)
{
int chunk = _entityComponentMasks[entityLineStartIndex + i];
if (chunk != 0)
{
if ((chunk & 0x0000FFFF) != 0)
{
int bit = 0x00000001;
for (int j = 0; j < COMPONENT_MASK_CHUNK_SIZE_HALF; j++)
{
if ((bit & chunk) != 0)
{
_pools[poolIndexWithoutOffset + j].Copy(fromEntityID, toWorld, toEntityID);
int* ptr = stackalloc int[count];
poolIdsPtr = ptr;
}
bit <<= 1;
}
}
if ((chunk & -0x7FFF0000) != 0)
else
{
int bit = 0x00010000;
for (int j = COMPONENT_MASK_CHUNK_SIZE_HALF; j < COMPONENT_MASK_CHUNK_SIZE; j++)
poolIdsPtr = UnmanagedArrayUtility.New<int>(count);
}
GetComponentTypeIDsFor_Internal(fromEntityID, poolIdsPtr, count);
for (int i = 0; i < count; i++)
{
if ((bit & chunk) != 0)
_pools[poolIdsPtr[i]].Copy(fromEntityID, toWorld, toEntityID);
}
if (count >= BUFFER_THRESHOLD)
{
_pools[poolIndexWithoutOffset + j].Copy(fromEntityID, toWorld, toEntityID);
}
bit <<= 1;
}
}
}
poolIndexWithoutOffset += COMPONENT_MASK_CHUNK_SIZE;
UnmanagedArrayUtility.Free(poolIdsPtr);
}
//foreach (var pool in _pools)
@ -617,46 +601,34 @@ namespace DCFApixels.DragonECS
#endregion
#region MoveComponents
public void MoveComponents(int fromEntityID, int toEntityID)
public unsafe void MoveComponents(int fromEntityID, int toEntityID)
{
const int COMPONENT_MASK_CHUNK_SIZE_HALF = COMPONENT_MASK_CHUNK_SIZE / 2;
int entityLineStartIndex = fromEntityID << _entityComponentMaskLengthBitShift;
int poolIndexWithoutOffset = 0;
for (int i = 0; i < _entityComponentMaskLength; i++)
const int BUFFER_THRESHOLD = 100;
int count = GetComponentsCount(fromEntityID);
int* poolIdsPtr;
if (count < BUFFER_THRESHOLD)
{
int chunk = _entityComponentMasks[i];
poolIndexWithoutOffset += COMPONENT_MASK_CHUNK_SIZE;
if (chunk != 0)
int* ptr = stackalloc int[count];
poolIdsPtr = ptr;
}
else
{
if ((chunk & 0x0000FFFF) != 0)
poolIdsPtr = UnmanagedArrayUtility.New<int>(count);
}
GetComponentTypeIDsFor_Internal(fromEntityID, poolIdsPtr, count);
for (int i = 0; i < count; i++)
{
int bit = 1;
for (int j = 0; j < COMPONENT_MASK_CHUNK_SIZE_HALF; j++)
{
if ((bit & chunk) != 0)
{
var pool = _pools[poolIndexWithoutOffset + j];
var pool = _pools[poolIdsPtr[i]];
pool.Copy(fromEntityID, toEntityID);
pool.Del(fromEntityID);
}
bit <<= 1;
}
}
if ((chunk & -0x7FFF0000) != 0)
if (count >= BUFFER_THRESHOLD)
{
int bit = 0x00010000;
for (int j = COMPONENT_MASK_CHUNK_SIZE_HALF; j < COMPONENT_MASK_CHUNK_SIZE; j++)
{
if ((bit & chunk) != 0)
{
var pool = _pools[poolIndexWithoutOffset + j];
pool.Copy(fromEntityID, toEntityID);
pool.Del(fromEntityID);
}
bit <<= 1;
}
}
}
UnmanagedArrayUtility.Free(poolIdsPtr);
}
}
public void MoveComponents(int fromEntityID, int toEntityID, ReadOnlySpan<int> componentTypeIDs)
@ -674,42 +646,32 @@ namespace DCFApixels.DragonECS
#endregion
#region RemoveComponents
public void RemoveComponents(int fromEntityID, int toEntityID)
public unsafe void RemoveComponents(int fromEntityID, int toEntityID)
{
const int COMPONENT_MASK_CHUNK_SIZE_HALF = COMPONENT_MASK_CHUNK_SIZE / 2;
int entityLineStartIndex = fromEntityID << _entityComponentMaskLengthBitShift;
int poolIndexWithoutOffset = 0;
for (int i = 0; i < _entityComponentMaskLength; i++)
const int BUFFER_THRESHOLD = 100;
int count = GetComponentsCount(fromEntityID);
int* poolIdsPtr;
if (count < BUFFER_THRESHOLD)
{
int chunk = _entityComponentMasks[i];
poolIndexWithoutOffset += COMPONENT_MASK_CHUNK_SIZE;
if (chunk != 0)
{
if ((chunk & 0x0000FFFF) != 0)
{
int bit = 1;
for (int j = 0; j < COMPONENT_MASK_CHUNK_SIZE_HALF; j++)
{
if ((bit & chunk) != 0)
{
_pools[poolIndexWithoutOffset + j].Del(fromEntityID);
int* ptr = stackalloc int[count];
poolIdsPtr = ptr;
}
bit <<= 1;
}
}
if ((chunk & -0x7FFF0000) != 0)
else
{
int bit = 0x00010000;
for (int j = COMPONENT_MASK_CHUNK_SIZE_HALF; j < COMPONENT_MASK_CHUNK_SIZE; j++)
poolIdsPtr = UnmanagedArrayUtility.New<int>(count);
}
GetComponentTypeIDsFor_Internal(fromEntityID, poolIdsPtr, count);
for (int i = 0; i < count; i++)
{
if ((bit & chunk) != 0)
_pools[poolIdsPtr[i]].Del(fromEntityID);
}
if (count >= BUFFER_THRESHOLD)
{
_pools[poolIndexWithoutOffset + j].Del(fromEntityID);
}
bit <<= 1;
}
}
}
UnmanagedArrayUtility.Free(poolIdsPtr);
}
}
public void RemoveComponents(int fromEntityID, int toEntityID, ReadOnlySpan<int> componentTypeIDs)
@ -988,16 +950,20 @@ namespace DCFApixels.DragonECS
{
Array.Resize(ref componentIDs, itemsCount);
}
if (itemsCount <= 0) { return 0; }
fixed (int* ptr = componentIDs)
{
GetComponentTypeIDsFor_Internal(entityID, itemsCount, ptr);
GetComponentTypeIDsFor_Internal(entityID, ptr, itemsCount);
}
return itemsCount;
}
private unsafe void GetComponentTypeIDsFor_Internal(int entityID, int itemsCount, int* componentIDs)
private unsafe void GetComponentTypeIDsFor_Internal(int entityID, int* componentIDs, int itemsCount)
{
if (itemsCount <= 0) { return; }
const int COMPONENT_MASK_CHUNK_SIZE_HALF = COMPONENT_MASK_CHUNK_SIZE / 2;
// проверка на itemsCount <= 0 не обяательна, алгоритм не ломается,
// только впустую отрабатыват по всем чанкам,
// но как правильно для пустых сущностей этот алгоритм не применим.
int poolIndex = 0;
int bit;
for (int chunkIndex = entityID << _entityComponentMaskLengthBitShift,
@ -1015,11 +981,11 @@ namespace DCFApixels.DragonECS
if ((chunk & 0x0000FFFF) != 0)
{
bit = 0x0000_0001;
while (bit != 0x0001_0000)
while (bit < 0x0001_0000)
{
if ((chunk & bit) != 0)
{
*componentIDs = _pools[poolIndex].ComponentTypeID;
*componentIDs = poolIndex;
componentIDs++;
itemsCount--;
@ -1029,6 +995,10 @@ namespace DCFApixels.DragonECS
bit <<= 1;
}
}
else
{
poolIndex += COMPONENT_MASK_CHUNK_SIZE_HALF;
}
if ((chunk & -0x7FFF0000) != 0)
{
bit = 0x0001_0000;
@ -1036,7 +1006,7 @@ namespace DCFApixels.DragonECS
{
if ((chunk & bit) != 0)
{
*componentIDs = _pools[poolIndex].ComponentTypeID;
*componentIDs = poolIndex;
componentIDs++;
itemsCount--;
@ -1046,6 +1016,10 @@ namespace DCFApixels.DragonECS
bit <<= 1;
}
}
else
{
poolIndex += COMPONENT_MASK_CHUNK_SIZE_HALF;
}
}
}
}

View File

@ -83,6 +83,11 @@ namespace DCFApixels.DragonECS.Internal
Length = length;
}
public static UnsafeArray<T> Manual(T* ptr, int length)
{
return new UnsafeArray<T>(ptr, length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public UnsafeArray<T> Slice(int start)
{