mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 09:54:35 +08:00
update copy clone move remove
This commit is contained in:
parent
b60308ac7e
commit
51b623e2c5
@ -545,15 +545,15 @@ namespace DCFApixels.DragonECS
|
|||||||
int maxEntites = int.MaxValue;
|
int maxEntites = int.MaxValue;
|
||||||
|
|
||||||
EcsMaskChunck* preSortingBuffer;
|
EcsMaskChunck* preSortingBuffer;
|
||||||
if (maxBufferSize > STACK_BUFFER_THRESHOLD)
|
if (maxBufferSize < STACK_BUFFER_THRESHOLD)
|
||||||
{
|
|
||||||
preSortingBuffer = TempBuffer<EcsMaskChunck>.Get(maxBufferSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
EcsMaskChunck* ptr = stackalloc EcsMaskChunck[maxBufferSize];
|
EcsMaskChunck* ptr = stackalloc EcsMaskChunck[maxBufferSize];
|
||||||
preSortingBuffer = ptr;
|
preSortingBuffer = ptr;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
preSortingBuffer = TempBuffer<EcsMaskChunck>.Get(maxBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
if (_sortIncChunckBuffer.Length > 1)
|
if (_sortIncChunckBuffer.Length > 1)
|
||||||
{
|
{
|
||||||
@ -879,7 +879,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
#endif
|
#endif
|
||||||
internal unsafe class EcsMaskIteratorUtility
|
internal unsafe class EcsMaskIteratorUtility
|
||||||
{
|
{
|
||||||
internal const int STACK_BUFFER_THRESHOLD = 256;
|
internal const int STACK_BUFFER_THRESHOLD = 100;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static void ConvertToChuncks(EcsMaskChunck* ptr, UnsafeArray<int> input, UnsafeArray<EcsMaskChunck> output)
|
internal static void ConvertToChuncks(EcsMaskChunck* ptr, UnsafeArray<int> input, UnsafeArray<EcsMaskChunck> output)
|
||||||
|
270
src/EcsWorld.cs
270
src/EcsWorld.cs
@ -463,41 +463,35 @@ namespace DCFApixels.DragonECS
|
|||||||
#region CopyEntity
|
#region CopyEntity
|
||||||
public unsafe void CopyEntity(int fromEntityID, int toEntityID)
|
public unsafe void CopyEntity(int fromEntityID, int toEntityID)
|
||||||
{
|
{
|
||||||
const int COMPONENT_MASK_CHUNK_SIZE_HALF = COMPONENT_MASK_CHUNK_SIZE / 2;
|
const int BUFFER_THRESHOLD = 100;
|
||||||
int entityLineStartIndex = fromEntityID << _entityComponentMaskLengthBitShift;
|
|
||||||
int poolIndexWithoutOffset = 0;
|
int count = GetComponentsCount(fromEntityID);
|
||||||
for (int i = 0; i < _entityComponentMaskLength; i++)
|
|
||||||
|
int* poolIdsPtr;
|
||||||
|
if (count < BUFFER_THRESHOLD)
|
||||||
{
|
{
|
||||||
int chunk = _entityComponentMasks[entityLineStartIndex + i];
|
int* ptr = stackalloc int[count];
|
||||||
if (chunk != 0)
|
poolIdsPtr = ptr;
|
||||||
{
|
|
||||||
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].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;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
_pools[poolIdsPtr[i]].Copy(fromEntityID, toEntityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count >= BUFFER_THRESHOLD)
|
||||||
|
{
|
||||||
|
UnmanagedArrayUtility.Free(poolIdsPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//foreach (var pool in _pools)
|
//foreach (var pool in _pools)
|
||||||
//{
|
//{
|
||||||
// if (pool.Has(fromEntityID))
|
// 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;
|
const int BUFFER_THRESHOLD = 100;
|
||||||
int entityLineStartIndex = fromEntityID << _entityComponentMaskLengthBitShift;
|
|
||||||
int poolIndexWithoutOffset = 0;
|
int count = GetComponentsCount(fromEntityID);
|
||||||
for (int i = 0; i < _entityComponentMaskLength; i++)
|
|
||||||
|
int* poolIdsPtr;
|
||||||
|
if (count < BUFFER_THRESHOLD)
|
||||||
{
|
{
|
||||||
int chunk = _entityComponentMasks[entityLineStartIndex + i];
|
int* ptr = stackalloc int[count];
|
||||||
if (chunk != 0)
|
poolIdsPtr = ptr;
|
||||||
{
|
}
|
||||||
if ((chunk & 0x0000FFFF) != 0)
|
else
|
||||||
{
|
{
|
||||||
int bit = 0x00000001;
|
poolIdsPtr = UnmanagedArrayUtility.New<int>(count);
|
||||||
for (int j = 0; j < COMPONENT_MASK_CHUNK_SIZE_HALF; j++)
|
}
|
||||||
{
|
|
||||||
if ((bit & chunk) != 0)
|
GetComponentTypeIDsFor_Internal(fromEntityID, poolIdsPtr, count);
|
||||||
{
|
for (int i = 0; i < count; i++)
|
||||||
_pools[poolIndexWithoutOffset + j].Copy(fromEntityID, toWorld, toEntityID);
|
{
|
||||||
}
|
_pools[poolIdsPtr[i]].Copy(fromEntityID, toWorld, toEntityID);
|
||||||
bit <<= 1;
|
}
|
||||||
}
|
|
||||||
}
|
if (count >= BUFFER_THRESHOLD)
|
||||||
if ((chunk & -0x7FFF0000) != 0)
|
{
|
||||||
{
|
UnmanagedArrayUtility.Free(poolIdsPtr);
|
||||||
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, toWorld, toEntityID);
|
|
||||||
}
|
|
||||||
bit <<= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
poolIndexWithoutOffset += COMPONENT_MASK_CHUNK_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//foreach (var pool in _pools)
|
//foreach (var pool in _pools)
|
||||||
@ -617,46 +601,34 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region MoveComponents
|
#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;
|
const int BUFFER_THRESHOLD = 100;
|
||||||
int entityLineStartIndex = fromEntityID << _entityComponentMaskLengthBitShift;
|
|
||||||
int poolIndexWithoutOffset = 0;
|
int count = GetComponentsCount(fromEntityID);
|
||||||
for (int i = 0; i < _entityComponentMaskLength; i++)
|
|
||||||
|
int* poolIdsPtr;
|
||||||
|
if (count < BUFFER_THRESHOLD)
|
||||||
{
|
{
|
||||||
int chunk = _entityComponentMasks[i];
|
int* ptr = stackalloc int[count];
|
||||||
poolIndexWithoutOffset += COMPONENT_MASK_CHUNK_SIZE;
|
poolIdsPtr = ptr;
|
||||||
if (chunk != 0)
|
}
|
||||||
{
|
else
|
||||||
if ((chunk & 0x0000FFFF) != 0)
|
{
|
||||||
{
|
poolIdsPtr = UnmanagedArrayUtility.New<int>(count);
|
||||||
int bit = 1;
|
}
|
||||||
for (int j = 0; j < COMPONENT_MASK_CHUNK_SIZE_HALF; j++)
|
|
||||||
{
|
GetComponentTypeIDsFor_Internal(fromEntityID, poolIdsPtr, count);
|
||||||
if ((bit & chunk) != 0)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var pool = _pools[poolIndexWithoutOffset + j];
|
var pool = _pools[poolIdsPtr[i]];
|
||||||
pool.Copy(fromEntityID, toEntityID);
|
pool.Copy(fromEntityID, toEntityID);
|
||||||
pool.Del(fromEntityID);
|
pool.Del(fromEntityID);
|
||||||
}
|
}
|
||||||
bit <<= 1;
|
|
||||||
}
|
if (count >= BUFFER_THRESHOLD)
|
||||||
}
|
{
|
||||||
if ((chunk & -0x7FFF0000) != 0)
|
UnmanagedArrayUtility.Free(poolIdsPtr);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void MoveComponents(int fromEntityID, int toEntityID, ReadOnlySpan<int> componentTypeIDs)
|
public void MoveComponents(int fromEntityID, int toEntityID, ReadOnlySpan<int> componentTypeIDs)
|
||||||
@ -674,42 +646,32 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region RemoveComponents
|
#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;
|
const int BUFFER_THRESHOLD = 100;
|
||||||
int entityLineStartIndex = fromEntityID << _entityComponentMaskLengthBitShift;
|
|
||||||
int poolIndexWithoutOffset = 0;
|
int count = GetComponentsCount(fromEntityID);
|
||||||
for (int i = 0; i < _entityComponentMaskLength; i++)
|
|
||||||
|
int* poolIdsPtr;
|
||||||
|
if (count < BUFFER_THRESHOLD)
|
||||||
{
|
{
|
||||||
int chunk = _entityComponentMasks[i];
|
int* ptr = stackalloc int[count];
|
||||||
poolIndexWithoutOffset += COMPONENT_MASK_CHUNK_SIZE;
|
poolIdsPtr = ptr;
|
||||||
if (chunk != 0)
|
}
|
||||||
{
|
else
|
||||||
if ((chunk & 0x0000FFFF) != 0)
|
{
|
||||||
{
|
poolIdsPtr = UnmanagedArrayUtility.New<int>(count);
|
||||||
int bit = 1;
|
}
|
||||||
for (int j = 0; j < COMPONENT_MASK_CHUNK_SIZE_HALF; j++)
|
|
||||||
{
|
GetComponentTypeIDsFor_Internal(fromEntityID, poolIdsPtr, count);
|
||||||
if ((bit & chunk) != 0)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
_pools[poolIndexWithoutOffset + j].Del(fromEntityID);
|
_pools[poolIdsPtr[i]].Del(fromEntityID);
|
||||||
}
|
}
|
||||||
bit <<= 1;
|
|
||||||
}
|
if (count >= BUFFER_THRESHOLD)
|
||||||
}
|
{
|
||||||
if ((chunk & -0x7FFF0000) != 0)
|
UnmanagedArrayUtility.Free(poolIdsPtr);
|
||||||
{
|
|
||||||
int bit = 0x00010000;
|
|
||||||
for (int j = COMPONENT_MASK_CHUNK_SIZE_HALF; j < COMPONENT_MASK_CHUNK_SIZE; j++)
|
|
||||||
{
|
|
||||||
if ((bit & chunk) != 0)
|
|
||||||
{
|
|
||||||
_pools[poolIndexWithoutOffset + j].Del(fromEntityID);
|
|
||||||
}
|
|
||||||
bit <<= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void RemoveComponents(int fromEntityID, int toEntityID, ReadOnlySpan<int> componentTypeIDs)
|
public void RemoveComponents(int fromEntityID, int toEntityID, ReadOnlySpan<int> componentTypeIDs)
|
||||||
@ -980,24 +942,28 @@ namespace DCFApixels.DragonECS
|
|||||||
private unsafe int GetComponentTypeIDsFor_Internal(int entityID, ref int[] componentIDs)
|
private unsafe int GetComponentTypeIDsFor_Internal(int entityID, ref int[] componentIDs)
|
||||||
{
|
{
|
||||||
var itemsCount = GetComponentsCount(entityID);
|
var itemsCount = GetComponentsCount(entityID);
|
||||||
if(componentIDs == null)
|
if (componentIDs == null)
|
||||||
{
|
{
|
||||||
componentIDs = new int[itemsCount];
|
componentIDs = new int[itemsCount];
|
||||||
}
|
}
|
||||||
if(componentIDs.Length < itemsCount)
|
if (componentIDs.Length < itemsCount)
|
||||||
{
|
{
|
||||||
Array.Resize(ref componentIDs, itemsCount);
|
Array.Resize(ref componentIDs, itemsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (itemsCount <= 0) { return 0; }
|
||||||
fixed (int* ptr = componentIDs)
|
fixed (int* ptr = componentIDs)
|
||||||
{
|
{
|
||||||
GetComponentTypeIDsFor_Internal(entityID, itemsCount, ptr);
|
GetComponentTypeIDsFor_Internal(entityID, ptr, itemsCount);
|
||||||
}
|
}
|
||||||
return 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 poolIndex = 0;
|
||||||
int bit;
|
int bit;
|
||||||
for (int chunkIndex = entityID << _entityComponentMaskLengthBitShift,
|
for (int chunkIndex = entityID << _entityComponentMaskLengthBitShift,
|
||||||
@ -1015,11 +981,11 @@ namespace DCFApixels.DragonECS
|
|||||||
if ((chunk & 0x0000FFFF) != 0)
|
if ((chunk & 0x0000FFFF) != 0)
|
||||||
{
|
{
|
||||||
bit = 0x0000_0001;
|
bit = 0x0000_0001;
|
||||||
while (bit != 0x0001_0000)
|
while (bit < 0x0001_0000)
|
||||||
{
|
{
|
||||||
if ((chunk & bit) != 0)
|
if ((chunk & bit) != 0)
|
||||||
{
|
{
|
||||||
*componentIDs = _pools[poolIndex].ComponentTypeID;
|
*componentIDs = poolIndex;
|
||||||
componentIDs++;
|
componentIDs++;
|
||||||
|
|
||||||
itemsCount--;
|
itemsCount--;
|
||||||
@ -1029,6 +995,10 @@ namespace DCFApixels.DragonECS
|
|||||||
bit <<= 1;
|
bit <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
poolIndex += COMPONENT_MASK_CHUNK_SIZE_HALF;
|
||||||
|
}
|
||||||
if ((chunk & -0x7FFF0000) != 0)
|
if ((chunk & -0x7FFF0000) != 0)
|
||||||
{
|
{
|
||||||
bit = 0x0001_0000;
|
bit = 0x0001_0000;
|
||||||
@ -1036,7 +1006,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if ((chunk & bit) != 0)
|
if ((chunk & bit) != 0)
|
||||||
{
|
{
|
||||||
*componentIDs = _pools[poolIndex].ComponentTypeID;
|
*componentIDs = poolIndex;
|
||||||
componentIDs++;
|
componentIDs++;
|
||||||
|
|
||||||
itemsCount--;
|
itemsCount--;
|
||||||
@ -1046,6 +1016,10 @@ namespace DCFApixels.DragonECS
|
|||||||
bit <<= 1;
|
bit <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
poolIndex += COMPONENT_MASK_CHUNK_SIZE_HALF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,11 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
Length = length;
|
Length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static UnsafeArray<T> Manual(T* ptr, int length)
|
||||||
|
{
|
||||||
|
return new UnsafeArray<T>(ptr, length);
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UnsafeArray<T> Slice(int start)
|
public UnsafeArray<T> Slice(int start)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user