From f67e6d59ea7f049d013d75c3aa08d8edda4c0784 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 29 Feb 2024 03:28:13 +0800 Subject: [PATCH] update gen to lazy gen --- src/EcsWorld.cs | 46 ++++++++++++++++++++++++++++----- src/entlong.cs | 69 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 106 insertions(+), 9 deletions(-) diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 3f21460..83af163 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -254,23 +254,39 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] 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; } [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) { - return _gens[entityID] == gen; + ref short slotGen = ref _gens[entityID]; + return slotGen == gen && slotGen >= 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsUsed(int entityID) { - return _gens[entityID] >= 0; + return _entityDispenser.IsUsed(entityID); } [MethodImpl(MethodImplOptions.AggressiveInlining)] 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)] public short GetComponentsCount(int entityID) @@ -299,7 +315,9 @@ namespace DCFApixels.DragonECS } return true; } + #endregion + #region Leaked public bool DeleteLeakedEntites() { if (_deleteLeakedEntitesLastVersion == _version) @@ -322,6 +340,22 @@ namespace DCFApixels.DragonECS _deleteLeakedEntitesLastVersion = _version; 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 #region Copy/Clone @@ -438,8 +472,8 @@ namespace DCFApixels.DragonECS { int e = buffer[i]; _entityDispenser.Release(e); - unchecked { _gens[e]++; }//up gen - _gens[e] |= DEATH_GEN_BIT; + //unchecked { _gens[e]++; }//up gen + //_gens[e] |= DEATH_GEN_BIT; } Densify(); } diff --git a/src/entlong.cs b/src/entlong.cs index 0b7ba17..f9690fc 100644 --- a/src/entlong.cs +++ b/src/entlong.cs @@ -191,9 +191,9 @@ namespace DCFApixels.DragonECS world = this.world; } - private class DebuggerProxy + internal class DebuggerProxy { - private List _componentsList; + private List _componentsList = new List(); private entlong _value; public long full { get { return _value.full; } } public int id { get { return _value.id; } } @@ -212,10 +212,73 @@ namespace DCFApixels.DragonECS public DebuggerProxy(entlong value) { _value = value; - _componentsList = new List(); + } + public DebuggerProxy(EntitySlotInfo value) + { + _value = new entlong(value.id, value.gen, value.world); } public enum EntState { Null, Dead, Alive, } } #endregion } + + + [DebuggerTypeProxy(typeof(entlong.DebuggerProxy))] + public readonly struct EntitySlotInfo : IEquatable + { + 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 + } }