mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
update/fix lazy gen
This commit is contained in:
parent
f67e6d59ea
commit
a3a61d21da
@ -749,14 +749,16 @@ namespace DCFApixels.DragonECS
|
|||||||
private EcsGroup _group;
|
private EcsGroup _group;
|
||||||
public EcsWorld World => _group.World;
|
public EcsWorld World => _group.World;
|
||||||
public bool IsReleased => _group.IsReleased;
|
public bool IsReleased => _group.IsReleased;
|
||||||
public entlong[] Entities
|
public EntitySlotInfo[] Entities
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
entlong[] result = new entlong[_group.Count];
|
EntitySlotInfo[] result = new EntitySlotInfo[_group.Count];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var e in _group)
|
foreach (var e in _group)
|
||||||
result[i++] = _group.World.GetEntityLong(e);
|
{
|
||||||
|
result[i++] = _group.World.GetEntitySlotInfoDebug(e);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,14 +131,16 @@ namespace DCFApixels.DragonECS
|
|||||||
private int[] _values;
|
private int[] _values;
|
||||||
private int _worldID;
|
private int _worldID;
|
||||||
public EcsWorld World => EcsWorld.GetWorld(_worldID);
|
public EcsWorld World => EcsWorld.GetWorld(_worldID);
|
||||||
public entlong[] Entities
|
public EntitySlotInfo[] Entities
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
entlong[] result = new entlong[_values.Length];
|
EntitySlotInfo[] result = new EntitySlotInfo[_values.Length];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var e in _values)
|
foreach (var e in _values)
|
||||||
result[i++] = World.GetEntityLong(e);
|
{
|
||||||
|
result[i++] = World.GetEntitySlotInfoDebug(e);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,29 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
public partial class EcsWorld : IEntityStorage
|
public partial class EcsWorld : IEntityStorage
|
||||||
{
|
{
|
||||||
|
[StructLayout(LayoutKind.Explicit, Pack = 4, Size = 4 * 3)]
|
||||||
|
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;
|
||||||
|
public EntitySlot(short gen, short componentsCount, bool isUsed)
|
||||||
|
{
|
||||||
|
this.gen = gen;
|
||||||
|
this.componentsCount = componentsCount;
|
||||||
|
this.isUsed = isUsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
public readonly short id;
|
public readonly short id;
|
||||||
private IEcsWorldConfig _config;
|
private IEcsWorldConfig _config;
|
||||||
|
|
||||||
@ -15,8 +33,9 @@ namespace DCFApixels.DragonECS
|
|||||||
private IdDispenser _entityDispenser;
|
private IdDispenser _entityDispenser;
|
||||||
private int _entitiesCount = 0;
|
private int _entitiesCount = 0;
|
||||||
private int _entitiesCapacity = 0;
|
private int _entitiesCapacity = 0;
|
||||||
private short[] _gens = Array.Empty<short>(); //старший бит указывает на то жива ли сущность
|
//private short[] _gens = Array.Empty<short>(); //старший бит указывает на то жива ли сущность
|
||||||
private short[] _componentCounts = Array.Empty<short>();
|
//private short[] _componentCounts = Array.Empty<short>();
|
||||||
|
private EntitySlot[] _entities = Array.Empty<EntitySlot>();
|
||||||
|
|
||||||
private int[] _delEntBuffer = Array.Empty<int>();
|
private int[] _delEntBuffer = Array.Empty<int>();
|
||||||
private int _delEntBufferCount = 0;
|
private int _delEntBufferCount = 0;
|
||||||
@ -135,7 +154,8 @@ namespace DCFApixels.DragonECS
|
|||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
_entityDispenser = null;
|
_entityDispenser = null;
|
||||||
_gens = null;
|
//_gens = null;
|
||||||
|
//_componentCounts = null;
|
||||||
_pools = null;
|
_pools = null;
|
||||||
_nullPool = null;
|
_nullPool = null;
|
||||||
_worlds[id] = null;
|
_worlds[id] = null;
|
||||||
@ -211,9 +231,12 @@ namespace DCFApixels.DragonECS
|
|||||||
_entitiesCount++;
|
_entitiesCount++;
|
||||||
if (_entitiesCapacity <= entityID)
|
if (_entitiesCapacity <= entityID)
|
||||||
{
|
{
|
||||||
OnEntityDispenserResized(_gens.Length << 1);
|
//OnEntityDispenserResized(_gens.Length << 1);
|
||||||
|
OnEntityDispenserResized(_entities.Length << 1);
|
||||||
}
|
}
|
||||||
_gens[entityID] &= GEN_MASK;
|
//_gens[entityID] &= GEN_MASK;
|
||||||
|
//_entities[entityID].gen &= GEN_MASK;
|
||||||
|
_entities[entityID].isUsed = true;
|
||||||
_entityListeners.InvokeOnNewEntity(entityID);
|
_entityListeners.InvokeOnNewEntity(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +262,8 @@ namespace DCFApixels.DragonECS
|
|||||||
#endif
|
#endif
|
||||||
UpVersion();
|
UpVersion();
|
||||||
_delEntBuffer[_delEntBufferCount++] = entityID;
|
_delEntBuffer[_delEntBufferCount++] = entityID;
|
||||||
_gens[entityID] |= DEATH_GEN_BIT;
|
//_gens[entityID] |= DEATH_GEN_BIT;
|
||||||
|
_entities[entityID].isUsed = false;
|
||||||
_entitiesCount--;
|
_entitiesCount--;
|
||||||
_entityListeners.InvokeOnDelEntity(entityID);
|
_entityListeners.InvokeOnDelEntity(entityID);
|
||||||
}
|
}
|
||||||
@ -249,6 +273,10 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public EcsSpan ToSpan()
|
public EcsSpan ToSpan()
|
||||||
{
|
{
|
||||||
|
if (_isEnableAutoReleaseDelEntBuffer)
|
||||||
|
{
|
||||||
|
ReleaseDelEntityBufferAll();
|
||||||
|
}
|
||||||
return _entityDispenser.UsedToEcsSpan(id);
|
return _entityDispenser.UsedToEcsSpan(id);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -260,29 +288,33 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public unsafe EntitySlotInfo GetEntitySlotInfoDebug(int entityID)
|
public unsafe EntitySlotInfo GetEntitySlotInfoDebug(int entityID)
|
||||||
{
|
{
|
||||||
return new EntitySlotInfo(entityID, _gens[entityID], id);
|
//return new EntitySlotInfo(entityID, _gens[entityID], id);
|
||||||
|
return new EntitySlotInfo(entityID, _entities[entityID].gen, id);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool IsAlive(int entityID, short gen)
|
public bool IsAlive(int entityID, short gen)
|
||||||
{
|
{
|
||||||
ref short slotGen = ref _gens[entityID];
|
//ref short slotGen = ref _gens[entityID];
|
||||||
return slotGen == gen && slotGen >= 0;
|
ref var slot = ref _entities[entityID];
|
||||||
|
return slot.gen == gen && slot.isUsed;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool IsUsed(int entityID)
|
public bool IsUsed(int entityID)
|
||||||
{
|
{
|
||||||
return _entityDispenser.IsUsed(entityID);
|
//return _entityDispenser.IsUsed(entityID);
|
||||||
|
return _entities[entityID].isUsed;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public short GetGen(int entityID)
|
public short GetGen(int entityID)
|
||||||
{
|
{
|
||||||
unchecked
|
unchecked
|
||||||
{
|
{
|
||||||
ref short slotGen = ref _gens[entityID];
|
//ref short slotGen = ref _gens[entityID];
|
||||||
|
ref short slotGen = ref _entities[entityID].gen;
|
||||||
if (slotGen < 0)
|
if (slotGen < 0)
|
||||||
{ //up gen
|
{ //up gen
|
||||||
slotGen++;
|
slotGen++;
|
||||||
slotGen &= GEN_MASK;
|
slotGen &= GEN_MASK;
|
||||||
}
|
}
|
||||||
return slotGen;
|
return slotGen;
|
||||||
}
|
}
|
||||||
@ -291,7 +323,8 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public short GetComponentsCount(int entityID)
|
public short GetComponentsCount(int entityID)
|
||||||
{
|
{
|
||||||
return _componentCounts[entityID];
|
//return _componentCounts[entityID];
|
||||||
|
return _entities[entityID].componentsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatchesMask(EcsMask mask, int entityID)
|
public bool IsMatchesMask(EcsMask mask, int entityID)
|
||||||
@ -327,7 +360,8 @@ namespace DCFApixels.DragonECS
|
|||||||
int delCount = 0;
|
int delCount = 0;
|
||||||
foreach (var e in Entities)
|
foreach (var e in Entities)
|
||||||
{
|
{
|
||||||
if (_componentCounts[e] <= 0)
|
//if (_componentCounts[e] <= 0)
|
||||||
|
if (_entities[e].componentsCount <= 0)
|
||||||
{
|
{
|
||||||
DelEntity(e);
|
DelEntity(e);
|
||||||
delCount++;
|
delCount++;
|
||||||
@ -349,7 +383,8 @@ namespace DCFApixels.DragonECS
|
|||||||
int delCount = 0;
|
int delCount = 0;
|
||||||
foreach (var e in Entities)
|
foreach (var e in Entities)
|
||||||
{
|
{
|
||||||
if (_componentCounts[e] <= 0)
|
//if (_componentCounts[e] <= 0)
|
||||||
|
if (_entities[e].componentsCount <= 0)
|
||||||
{
|
{
|
||||||
delCount++;
|
delCount++;
|
||||||
}
|
}
|
||||||
@ -448,7 +483,8 @@ namespace DCFApixels.DragonECS
|
|||||||
for (int i = 0; i < slisedCount; i++)
|
for (int i = 0; i < slisedCount; i++)
|
||||||
{
|
{
|
||||||
int e = _delEntBuffer[i];
|
int e = _delEntBuffer[i];
|
||||||
if (_componentCounts[e] <= 0)
|
//if (_componentCounts[e] <= 0)
|
||||||
|
if (_entities[e].componentsCount <= 0)
|
||||||
{
|
{
|
||||||
int tmp = _delEntBuffer[i];
|
int tmp = _delEntBuffer[i];
|
||||||
_delEntBuffer[i] = _delEntBuffer[--slisedCount];
|
_delEntBuffer[i] = _delEntBuffer[--slisedCount];
|
||||||
@ -474,6 +510,7 @@ namespace DCFApixels.DragonECS
|
|||||||
_entityDispenser.Release(e);
|
_entityDispenser.Release(e);
|
||||||
//unchecked { _gens[e]++; }//up gen
|
//unchecked { _gens[e]++; }//up gen
|
||||||
//_gens[e] |= DEATH_GEN_BIT;
|
//_gens[e] |= DEATH_GEN_BIT;
|
||||||
|
_entities[e].gen |= SLEEPING_GEN_FLAG;
|
||||||
}
|
}
|
||||||
Densify();
|
Densify();
|
||||||
}
|
}
|
||||||
@ -491,13 +528,15 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
private void OnEntityDispenserResized(int newSize)
|
private void OnEntityDispenserResized(int newSize)
|
||||||
{
|
{
|
||||||
Array.Resize(ref _gens, newSize);
|
//Array.Resize(ref _gens, newSize);
|
||||||
Array.Resize(ref _componentCounts, newSize);
|
//Array.Resize(ref _componentCounts, newSize);
|
||||||
|
Array.Resize(ref _entities, newSize);
|
||||||
Array.Resize(ref _delEntBuffer, newSize);
|
Array.Resize(ref _delEntBuffer, newSize);
|
||||||
_entityComponentMaskLength = _pools.Length / COMPONENT_MATRIX_MASK_BITSIZE + 1;
|
_entityComponentMaskLength = _pools.Length / COMPONENT_MATRIX_MASK_BITSIZE + 1;
|
||||||
Array.Resize(ref _entityComponentMasks, newSize * _entityComponentMaskLength);
|
Array.Resize(ref _entityComponentMasks, newSize * _entityComponentMaskLength);
|
||||||
|
|
||||||
ArrayUtility.Fill(_gens, DEATH_GEN_BIT, _entitiesCapacity);
|
//ArrayUtility.Fill(_gens, DEATH_GEN_BIT, _entitiesCapacity);
|
||||||
|
ArrayUtility.Fill(_entities, EntitySlot.Empty, _entitiesCapacity);
|
||||||
|
|
||||||
_entitiesCapacity = newSize;
|
_entitiesCapacity = newSize;
|
||||||
|
|
||||||
|
@ -210,14 +210,16 @@ namespace DCFApixels.DragonECS
|
|||||||
private void RegisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
private void RegisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
||||||
{
|
{
|
||||||
_poolComponentCounts[componentTypeID]++;
|
_poolComponentCounts[componentTypeID]++;
|
||||||
_componentCounts[entityID]++;
|
//_componentCounts[entityID]++;
|
||||||
|
_entities[entityID].componentsCount++;
|
||||||
_entityComponentMasks[entityID * _entityComponentMaskLength + maskBit.chankIndex] |= maskBit.mask;
|
_entityComponentMasks[entityID * _entityComponentMaskLength + maskBit.chankIndex] |= maskBit.mask;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
||||||
{
|
{
|
||||||
_poolComponentCounts[componentTypeID]--;
|
_poolComponentCounts[componentTypeID]--;
|
||||||
var count = --_componentCounts[entityID];
|
//var count = --_componentCounts[entityID];
|
||||||
|
var count = --_entities[entityID].componentsCount;
|
||||||
_entityComponentMasks[entityID * _entityComponentMaskLength + maskBit.chankIndex] &= ~maskBit.mask;
|
_entityComponentMasks[entityID * _entityComponentMaskLength + maskBit.chankIndex] &= ~maskBit.mask;
|
||||||
|
|
||||||
if (count == 0 && IsUsed(entityID))
|
if (count == 0 && IsUsed(entityID))
|
||||||
@ -239,7 +241,8 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
chunk = newChunk;
|
chunk = newChunk;
|
||||||
_poolComponentCounts[componentTypeID]++;
|
_poolComponentCounts[componentTypeID]++;
|
||||||
_componentCounts[entityID]++;
|
//_componentCounts[entityID]++;
|
||||||
|
_entities[entityID].componentsCount++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -252,7 +255,8 @@ namespace DCFApixels.DragonECS
|
|||||||
if (chunk != newChunk)
|
if (chunk != newChunk)
|
||||||
{
|
{
|
||||||
_poolComponentCounts[componentTypeID]--;
|
_poolComponentCounts[componentTypeID]--;
|
||||||
var count = --_componentCounts[entityID];
|
//var count = --_componentCounts[entityID];
|
||||||
|
var count = --_entities[entityID].componentsCount;
|
||||||
chunk = newChunk;
|
chunk = newChunk;
|
||||||
|
|
||||||
if (count == 0 && IsUsed(entityID))
|
if (count == 0 && IsUsed(entityID))
|
||||||
|
@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public partial class EcsWorld
|
public partial class EcsWorld
|
||||||
{
|
{
|
||||||
private const short GEN_MASK = 0x7fff;
|
private const short GEN_MASK = 0x7fff;
|
||||||
private const short DEATH_GEN_BIT = short.MinValue;
|
private const short SLEEPING_GEN_FLAG = short.MinValue;
|
||||||
private const int DEL_ENT_BUFFER_SIZE_OFFSET = 5;
|
private const int DEL_ENT_BUFFER_SIZE_OFFSET = 5;
|
||||||
private const int DEL_ENT_BUFFER_MIN_SIZE = 64;
|
private const int DEL_ENT_BUFFER_MIN_SIZE = 64;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user