mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
update Copy/Clone(Entity) add Move/Remove(Components)
This commit is contained in:
parent
ab06cbce58
commit
ad2bcae5ad
@ -44,7 +44,7 @@ namespace DCFApixels.DragonECS
|
||||
internal EcsWorld _source;
|
||||
internal EcsMask _mask;
|
||||
private bool _isBuilt = false;
|
||||
private IEcsPool[] _pools;
|
||||
//private IEcsPool[] _pools;
|
||||
|
||||
#region Properties
|
||||
public EcsMask Mask
|
||||
@ -59,10 +59,10 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
get { return _isBuilt; }
|
||||
}
|
||||
public ReadOnlySpan<IEcsPool> Pools
|
||||
{
|
||||
get { return _pools; }
|
||||
}
|
||||
//public ReadOnlySpan<IEcsPool> Pools
|
||||
//{
|
||||
// get { return _pools; }
|
||||
//}
|
||||
/// <summary>
|
||||
/// Статическая инициализация означет что каждый новый эекземпляр идентичен другому, инициализация стандартным путем создает идентичные экземпляры, поэтому значение по умолчанию true.
|
||||
/// </summary>
|
||||
@ -86,8 +86,8 @@ namespace DCFApixels.DragonECS
|
||||
private EcsWorld _world;
|
||||
private EcsStaticMask.Builder _maskBuilder;
|
||||
|
||||
private IEcsPool[] _poolsBuffer = new IEcsPool[8];
|
||||
private int _poolsBufferCount;
|
||||
//private IEcsPool[] _poolsBuffer = new IEcsPool[8];
|
||||
//private int _poolsBufferCount;
|
||||
|
||||
#region Properties
|
||||
public IncludeMarker Inc
|
||||
@ -154,8 +154,8 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
newAspect._mask = staticMask.ToMask(world);
|
||||
var pools = new IEcsPool[builder._poolsBufferCount];
|
||||
Array.Copy(builder._poolsBuffer, pools, pools.Length);
|
||||
//var pools = new IEcsPool[builder._poolsBufferCount];
|
||||
//Array.Copy(builder._poolsBuffer, pools, pools.Length);
|
||||
newAspect._isBuilt = true;
|
||||
|
||||
_constructorBuildersStackIndex--;
|
||||
@ -184,11 +184,11 @@ namespace DCFApixels.DragonECS
|
||||
private TPool CachePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
||||
{
|
||||
var pool = _world.GetPoolInstance<TPool>();
|
||||
if (_poolsBufferCount >= _poolsBuffer.Length)
|
||||
{
|
||||
Array.Resize(ref _poolsBuffer, _poolsBuffer.Length << 1);
|
||||
}
|
||||
_poolsBuffer[_poolsBufferCount++] = pool;
|
||||
//if (_poolsBufferCount >= _poolsBuffer.Length)
|
||||
//{
|
||||
// Array.Resize(ref _poolsBuffer, _poolsBuffer.Length << 1);
|
||||
//}
|
||||
//_poolsBuffer[_poolsBufferCount++] = pool;
|
||||
return pool;
|
||||
}
|
||||
private void IncludeImplicit(Type type)
|
||||
|
@ -717,11 +717,11 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
while (_span.MoveNext())
|
||||
{
|
||||
int chunck = _span.Current << _entityComponentMaskLengthBitShift;
|
||||
int entityLineStartIndex = _span.Current << _entityComponentMaskLengthBitShift;
|
||||
for (int i = 0; i < _sortIncChunckBuffer.Length; i++)
|
||||
{
|
||||
var bit = _sortIncChunckBuffer.ptr[i];
|
||||
if ((_entityComponentMasks[chunck + bit.chunkIndex] & bit.mask) != bit.mask)
|
||||
if ((_entityComponentMasks[entityLineStartIndex + bit.chunkIndex] & bit.mask) != bit.mask)
|
||||
{
|
||||
goto skip;
|
||||
}
|
||||
@ -729,7 +729,7 @@ namespace DCFApixels.DragonECS
|
||||
for (int i = 0; i < _sortExcChunckBuffer.Length; i++)
|
||||
{
|
||||
var bit = _sortExcChunckBuffer.ptr[i];
|
||||
if ((_entityComponentMasks[chunck + bit.chunkIndex] & bit.mask) != 0)
|
||||
if ((_entityComponentMasks[entityLineStartIndex + bit.chunkIndex] & bit.mask) != 0)
|
||||
{
|
||||
goto skip;
|
||||
}
|
||||
@ -848,11 +848,11 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
while (_span.MoveNext())
|
||||
{
|
||||
int chunck = _span.Current << _entityComponentMaskLengthBitShift;
|
||||
int entityLineStartIndex = _span.Current << _entityComponentMaskLengthBitShift;
|
||||
for (int i = 0; i < _sortIncChunckBuffer.Length; i++)
|
||||
{
|
||||
var bit = _sortIncChunckBuffer.ptr[i];
|
||||
if ((_entityComponentMasks[chunck + bit.chunkIndex] & bit.mask) != bit.mask)
|
||||
if ((_entityComponentMasks[entityLineStartIndex + bit.chunkIndex] & bit.mask) != bit.mask)
|
||||
{
|
||||
goto skip;
|
||||
}
|
||||
|
244
src/EcsWorld.cs
244
src/EcsWorld.cs
@ -458,11 +458,59 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Copy/Clone
|
||||
public void CopyEntity(int fromEntityID, int toEntityID)
|
||||
//TODO протестить Copy Clone Move Remove
|
||||
|
||||
#region CopyEntity
|
||||
public unsafe void CopyEntity(int fromEntityID, int toEntityID)
|
||||
{
|
||||
foreach (var pool in _pools)
|
||||
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++)
|
||||
{
|
||||
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].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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//foreach (var pool in _pools)
|
||||
//{
|
||||
// if (pool.Has(fromEntityID))
|
||||
// {
|
||||
// pool.Copy(fromEntityID, toEntityID);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
public void CopyEntity(int fromEntityID, int toEntityID, ReadOnlySpan<int> componentTypeIDs)
|
||||
{
|
||||
foreach (var poolID in componentTypeIDs)
|
||||
{
|
||||
var pool = _pools[poolID];
|
||||
if (pool.Has(fromEntityID))
|
||||
{
|
||||
pool.Copy(fromEntityID, toEntityID);
|
||||
@ -471,26 +519,89 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public void CopyEntity(int fromEntityID, EcsWorld toWorld, int toEntityID)
|
||||
{
|
||||
foreach (var pool in _pools)
|
||||
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++)
|
||||
{
|
||||
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].Copy(fromEntityID, toWorld, 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, toWorld, toEntityID);
|
||||
}
|
||||
bit <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//foreach (var pool in _pools)
|
||||
//{
|
||||
// if (pool.Has(fromEntityID))
|
||||
// {
|
||||
// pool.Copy(fromEntityID, toWorld, toEntityID);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
public void CopyEntity(int fromEntityID, EcsWorld toWorld, int toEntityID, ReadOnlySpan<int> componentTypeIDs)
|
||||
{
|
||||
foreach (var poolID in componentTypeIDs)
|
||||
{
|
||||
var pool = _pools[poolID];
|
||||
if (pool.Has(fromEntityID))
|
||||
{
|
||||
pool.Copy(fromEntityID, toWorld, toEntityID);
|
||||
}
|
||||
}
|
||||
}
|
||||
public int CloneEntity(int fromEntityID)
|
||||
#endregion
|
||||
|
||||
#region CloneEntity
|
||||
public int CloneEntity(int entityID)
|
||||
{
|
||||
int newEntity = NewEntity();
|
||||
CopyEntity(fromEntityID, newEntity);
|
||||
CopyEntity(entityID, newEntity);
|
||||
return newEntity;
|
||||
}
|
||||
public int CloneEntity(int fromEntityID, EcsWorld toWorld)
|
||||
public int CloneEntity(int entityID, ReadOnlySpan<int> componentTypeIDs)
|
||||
{
|
||||
int newEntity = NewEntity();
|
||||
CopyEntity(fromEntityID, toWorld, newEntity);
|
||||
CopyEntity(entityID, newEntity, componentTypeIDs);
|
||||
return newEntity;
|
||||
}
|
||||
public int CloneEntity(int entityID, EcsWorld toWorld)
|
||||
{
|
||||
int newEntity = NewEntity();
|
||||
CopyEntity(entityID, toWorld, newEntity);
|
||||
return newEntity;
|
||||
}
|
||||
public int CloneEntity(int entityID, EcsWorld toWorld, ReadOnlySpan<int> componentTypeIDs)
|
||||
{
|
||||
int newEntity = NewEntity();
|
||||
CopyEntity(entityID, toWorld, newEntity, componentTypeIDs);
|
||||
return newEntity;
|
||||
}
|
||||
|
||||
public void CloneEntity(int fromEntityID, int toEntityID)
|
||||
{
|
||||
CopyEntity(fromEntityID, toEntityID);
|
||||
@ -505,6 +616,116 @@ namespace DCFApixels.DragonECS
|
||||
//public void CloneEntity(int fromEntityID, EcsWorld toWorld, int toEntityID)
|
||||
#endregion
|
||||
|
||||
#region MoveComponents
|
||||
public 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++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var pool = _pools[poolIndexWithoutOffset + j];
|
||||
pool.Copy(fromEntityID, toEntityID);
|
||||
pool.Del(fromEntityID);
|
||||
}
|
||||
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)
|
||||
{
|
||||
var pool = _pools[poolIndexWithoutOffset + j];
|
||||
pool.Copy(fromEntityID, toEntityID);
|
||||
pool.Del(fromEntityID);
|
||||
}
|
||||
bit <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void MoveComponents(int fromEntityID, int toEntityID, ReadOnlySpan<int> componentTypeIDs)
|
||||
{
|
||||
foreach (var poolID in componentTypeIDs)
|
||||
{
|
||||
var pool = _pools[poolID];
|
||||
if (pool.Has(fromEntityID))
|
||||
{
|
||||
pool.Copy(fromEntityID, toEntityID);
|
||||
pool.Del(fromEntityID);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RemoveComponents
|
||||
public 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++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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].Del(fromEntityID);
|
||||
}
|
||||
bit <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void MoveComponents(int fromEntityID, int toEntityID, ReadOnlySpan<int> componentTypeIDs)
|
||||
{
|
||||
foreach (var poolID in componentTypeIDs)
|
||||
{
|
||||
var pool = _pools[poolID];
|
||||
if (pool.Has(fromEntityID))
|
||||
{
|
||||
pool.Del(fromEntityID);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region DelEntBuffer
|
||||
@ -800,18 +1021,13 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region EntitySlot
|
||||
[StructLayout(LayoutKind.Explicit, Pack = 4, Size = 4 * 3)]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct EntitySlot
|
||||
{
|
||||
public static readonly EntitySlot Empty = new EntitySlot(SLEEPING_GEN_FLAG, 0, false);
|
||||
[FieldOffset(0)]
|
||||
public short gen;
|
||||
[FieldOffset(2)]
|
||||
public short componentsCount;
|
||||
[FieldOffset(4)]
|
||||
public bool isUsed;
|
||||
//[FieldOffset(5)]
|
||||
//public bool isLocked;
|
||||
public EntitySlot(short gen, short componentsCount, bool isUsed)
|
||||
{
|
||||
this.gen = gen;
|
||||
|
@ -253,12 +253,12 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private bool TryRegisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
||||
{
|
||||
ref int chunk = ref _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex];
|
||||
int newChunk = chunk | maskBit.mask;
|
||||
if (chunk != newChunk)
|
||||
ref int entityLineStartIndex = ref _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex];
|
||||
int newChunk = entityLineStartIndex | maskBit.mask;
|
||||
if (entityLineStartIndex != newChunk)
|
||||
{
|
||||
UpVersion();
|
||||
chunk = newChunk;
|
||||
entityLineStartIndex = newChunk;
|
||||
ref PoolSlot slot = ref _poolSlots[componentTypeID];
|
||||
slot.count++;
|
||||
slot.version++;
|
||||
@ -270,16 +270,16 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private bool TryUnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
||||
{
|
||||
ref int chunk = ref _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex];
|
||||
int newChunk = chunk & ~maskBit.mask;
|
||||
if (chunk != newChunk)
|
||||
ref int entityLineStartIndex = ref _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex];
|
||||
int newChunk = entityLineStartIndex & ~maskBit.mask;
|
||||
if (entityLineStartIndex != newChunk)
|
||||
{
|
||||
UpVersion();
|
||||
ref PoolSlot slot = ref _poolSlots[componentTypeID];
|
||||
slot.count--;
|
||||
slot.version++;
|
||||
var count = --_entities[entityID].componentsCount;
|
||||
chunk = newChunk;
|
||||
entityLineStartIndex = newChunk;
|
||||
|
||||
if (count == 0 && IsUsed(entityID))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user