update gen to lazy gen

This commit is contained in:
Mikhail 2024-02-29 03:28:13 +08:00
parent 67acf2cfeb
commit f67e6d59ea
2 changed files with 106 additions and 9 deletions

View File

@ -254,23 +254,39 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe entlong GetEntityLong(int entityID) public unsafe entlong GetEntityLong(int entityID)
{ {
long x = (long)id << 48 | (long)_gens[entityID] << 32 | (long)entityID; long x = (long)id << 48 | (long)GetGen(entityID) << 32 | (long)entityID;
return *(entlong*)&x; return *(entlong*)&x;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe EntitySlotInfo GetEntitySlotInfoDebug(int entityID)
{
return new EntitySlotInfo(entityID, _gens[entityID], id);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsAlive(int entityID, short gen) public bool IsAlive(int entityID, short gen)
{ {
return _gens[entityID] == gen; ref short slotGen = ref _gens[entityID];
return slotGen == gen && slotGen >= 0;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsUsed(int entityID) public bool IsUsed(int entityID)
{ {
return _gens[entityID] >= 0; return _entityDispenser.IsUsed(entityID);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public short GetGen(int entityID) public short GetGen(int entityID)
{ {
return _gens[entityID]; unchecked
{
ref short slotGen = ref _gens[entityID];
if (slotGen < 0)
{ //up gen
slotGen++;
slotGen &= GEN_MASK;
}
return slotGen;
}
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public short GetComponentsCount(int entityID) public short GetComponentsCount(int entityID)
@ -299,7 +315,9 @@ namespace DCFApixels.DragonECS
} }
return true; return true;
} }
#endregion
#region Leaked
public bool DeleteLeakedEntites() public bool DeleteLeakedEntites()
{ {
if (_deleteLeakedEntitesLastVersion == _version) if (_deleteLeakedEntitesLastVersion == _version)
@ -322,6 +340,22 @@ namespace DCFApixels.DragonECS
_deleteLeakedEntitesLastVersion = _version; _deleteLeakedEntitesLastVersion = _version;
return delCount > 0; return delCount > 0;
} }
public int CountLeakedEntitesDebug()
{
if (_deleteLeakedEntitesLastVersion == _version)
{
return 0;
}
int delCount = 0;
foreach (var e in Entities)
{
if (_componentCounts[e] <= 0)
{
delCount++;
}
}
return delCount;
}
#endregion #endregion
#region Copy/Clone #region Copy/Clone
@ -438,8 +472,8 @@ namespace DCFApixels.DragonECS
{ {
int e = buffer[i]; int e = buffer[i];
_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;
} }
Densify(); Densify();
} }

View File

@ -191,9 +191,9 @@ namespace DCFApixels.DragonECS
world = this.world; world = this.world;
} }
private class DebuggerProxy internal class DebuggerProxy
{ {
private List<object> _componentsList; private List<object> _componentsList = new List<object>();
private entlong _value; private entlong _value;
public long full { get { return _value.full; } } public long full { get { return _value.full; } }
public int id { get { return _value.id; } } public int id { get { return _value.id; } }
@ -212,10 +212,73 @@ namespace DCFApixels.DragonECS
public DebuggerProxy(entlong value) public DebuggerProxy(entlong value)
{ {
_value = value; _value = value;
_componentsList = new List<object>(); }
public DebuggerProxy(EntitySlotInfo value)
{
_value = new entlong(value.id, value.gen, value.world);
} }
public enum EntState { Null, Dead, Alive, } public enum EntState { Null, Dead, Alive, }
} }
#endregion #endregion
} }
[DebuggerTypeProxy(typeof(entlong.DebuggerProxy))]
public readonly struct EntitySlotInfo : IEquatable<EntitySlotInfo>
{
public readonly int id;
public readonly short gen;
public readonly short world;
#region Constructors
public EntitySlotInfo(int id, short gen, short world)
{
this.id = id;
this.gen = gen;
this.world = world;
}
#endregion
#region Operators
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(EntitySlotInfo a, EntitySlotInfo b)
{
return a.id == b.id &&
a.gen == b.gen &&
a.world == b.world;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(EntitySlotInfo a, EntitySlotInfo b)
{
return a.id != b.id ||
a.gen != b.gen ||
a.world != b.world;
}
#endregion
#region Other
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() { return unchecked(id ^ gen ^ (world * EcsConsts.MAGIC_PRIME)); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override string ToString() { return $"slot(id:{id} g:{gen} w:{world})"; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object obj) { return obj is EntitySlotInfo other && this == other; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(EntitySlotInfo other) { return this == other; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Deconstruct(out int id, out int gen, out int world)
{
id = this.id;
gen = this.gen;
world = this.world;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Deconstruct(out int id, out int world)
{
id = this.id;
world = this.world;
}
#endregion
}
} }