From ee500fadfd5a27b58a106f9b9975f00f0c33f196 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 16 Apr 2024 12:46:09 +0800 Subject: [PATCH] fix worldID --- src/Collections/EcsGroup.cs | 2 +- src/Collections/EcsSpan.cs | 12 ++++++------ src/EcsAspect.cs | 2 +- src/EcsMask.cs | 10 +++++----- src/EcsWorld.cs | 34 +++++++++++++++++++++++----------- src/EcsWorld.static.cs | 23 +++++++++++++++++------ src/Internal/IdDispenser.cs | 2 +- 7 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/Collections/EcsGroup.cs b/src/Collections/EcsGroup.cs index 32e435b..e07a5b3 100644 --- a/src/Collections/EcsGroup.cs +++ b/src/Collections/EcsGroup.cs @@ -150,7 +150,7 @@ namespace DCFApixels.DragonECS internal bool _isReleased = true; #region Properties - public int WorldID + public short WorldID { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _source.id; } diff --git a/src/Collections/EcsSpan.cs b/src/Collections/EcsSpan.cs index e43bcd6..92a3ac9 100644 --- a/src/Collections/EcsSpan.cs +++ b/src/Collections/EcsSpan.cs @@ -9,8 +9,8 @@ namespace DCFApixels.DragonECS [DebuggerTypeProxy(typeof(DebuggerProxy))] public readonly ref struct EcsSpan { - private readonly int _worldID; private readonly ReadOnlySpan _values; + private readonly short _worldID; #region Properties public bool IsNull @@ -46,24 +46,24 @@ namespace DCFApixels.DragonECS #region Constructors [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal EcsSpan(int worldID, ReadOnlySpan span) + internal EcsSpan(short worldID, ReadOnlySpan span) { _worldID = worldID; _values = span; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal EcsSpan(int worldID, int[] array) + internal EcsSpan(short worldID, int[] array) { _worldID = worldID; _values = new ReadOnlySpan(array); } - internal EcsSpan(int worldID, int[] array, int length) + internal EcsSpan(short worldID, int[] array, int length) { _worldID = worldID; _values = new ReadOnlySpan(array, 0, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal EcsSpan(int worldID, int[] array, int start, int length) + internal EcsSpan(short worldID, int[] array, int start, int length) { _worldID = worldID; _values = new ReadOnlySpan(array, start, length); @@ -110,7 +110,7 @@ namespace DCFApixels.DragonECS internal class DebuggerProxy { private int[] _values; - private int _worldID; + private short _worldID; public EcsWorld World { get { return EcsWorld.GetWorld(_worldID); } } public EntitySlotInfo[] Entities { diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index b41b9a3..dca9a4e 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -260,7 +260,7 @@ namespace DCFApixels.DragonECS #region Iterator public ref struct Iterator { - public readonly int worldID; + public readonly short worldID; public readonly EcsAspect aspect; private EcsSpan _span; diff --git a/src/EcsMask.cs b/src/EcsMask.cs index d4070fc..fe6562c 100644 --- a/src/EcsMask.cs +++ b/src/EcsMask.cs @@ -11,7 +11,7 @@ namespace DCFApixels.DragonECS public sealed class EcsMask : IEquatable { internal readonly int id; - internal readonly int worldID; + internal readonly short worldID; internal readonly EcsMaskChunck[] incChunckMasks; internal readonly EcsMaskChunck[] excChunckMasks; internal readonly int[] inc; //Sorted @@ -22,7 +22,7 @@ namespace DCFApixels.DragonECS { get { return id; } } - public int WorldID + public short WorldID { get { return worldID; } } @@ -51,7 +51,7 @@ namespace DCFApixels.DragonECS { return new Builder(world); } - internal EcsMask(int id, int worldID, int[] inc, int[] exc) + internal EcsMask(int id, short worldID, int[] inc, int[] exc) { #if DEBUG CheckConstraints(inc, exc); @@ -223,7 +223,7 @@ namespace DCFApixels.DragonECS return false; } #endif - private static string CreateLogString(int worldID, int[] inc, int[] exc) + private static string CreateLogString(short worldID, int[] inc, int[] exc) { #if (DEBUG && !DISABLE_DEBUG) string converter(int o) { return EcsDebugUtility.GetGenericTypeName(EcsWorld.GetWorld(worldID).AllPools[o].ComponentType, 1); } @@ -237,7 +237,7 @@ namespace DCFApixels.DragonECS { public readonly int ID; public readonly EcsWorld world; - private readonly int _worldID; + private readonly short _worldID; public readonly EcsMaskChunck[] includedChunkMasks; public readonly EcsMaskChunck[] excludedChunkMasks; public readonly int[] included; diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 0800dfa..e75d200 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -239,31 +239,39 @@ namespace DCFApixels.DragonECS return entityID; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void NewEntity(int entityID) + public int NewEntity(int entityID) { #if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS if (IsUsed(entityID)) { Throw.World_EntityIsAlreadyСontained(entityID); } #endif _entityDispenser.Use(entityID); CreateConcreteEntity(entityID); + return entityID; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void CreateConcreteEntity(int entityID) { UpVersionLeaked(); _entitiesCount++; - if (_entitiesCapacity <= entityID) - { - OnEntityDispenserResized(_entities.Length << 1); + ref var slot = ref _entities[entityID]; + slot.isUsed = true; + if(slot.gen >= 0) + { //если gen был пробужен у не мертвой сущности, то для отличия от мертвой, нужно инкрементировать и усыпить + slot.gen++; + slot.gen &= SLEEP_GEN_MASK; } - _entities[entityID].isUsed = true; _entityListeners.InvokeOnNewEntity(entityID); } public entlong NewEntityLong() { - int e = NewEntity(); - return GetEntityLong(e); + int entityID = NewEntity(); + return GetEntityLong(entityID); + } + public entlong NewEntityLong(int entityID) + { + NewEntity(entityID); + return GetEntityLong(entityID); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -275,6 +283,11 @@ namespace DCFApixels.DragonECS } } [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DelEntity(entlong entity) + { + DelEntity(entity.ID); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void DelEntity(int entityID) { #if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS @@ -325,15 +338,14 @@ namespace DCFApixels.DragonECS { unchecked { - ref short slotGen = ref _entities[entityID].gen; + ref var slotGen = ref _entities[entityID].gen; if (slotGen < 0) - { //up gen + { //если gen меньше 0 значит он спящий, спящие нужно инкремировать slotGen++; - slotGen &= GEN_MASK; + slotGen &= WAKE_UP_GEN_MASK; } return slotGen; } - } [MethodImpl(MethodImplOptions.AggressiveInlining)] public short GetComponentsCount(int entityID) diff --git a/src/EcsWorld.static.cs b/src/EcsWorld.static.cs index 51f1fdf..e87db69 100644 --- a/src/EcsWorld.static.cs +++ b/src/EcsWorld.static.cs @@ -9,8 +9,8 @@ namespace DCFApixels.DragonECS [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 4)] public struct EcsWorldCmp where T : struct { - private int _worldID; - public EcsWorldCmp(int worldID) => _worldID = worldID; + private short _worldID; + public EcsWorldCmp(short worldID) => _worldID = worldID; public EcsWorld World => EcsWorld.GetWorld(_worldID); public ref T Value => ref EcsWorld.GetData(_worldID); } @@ -18,7 +18,9 @@ namespace DCFApixels.DragonECS { private const short NULL_WORLD_ID = 0; - private const short GEN_MASK = 0x7fff; + private const short WAKE_UP_GEN_MASK = 0x7fff; + private const short SLEEP_GEN_MASK = ~WAKE_UP_GEN_MASK; + private const short SLEEPING_GEN_FLAG = short.MinValue; private const int DEL_ENT_BUFFER_SIZE_OFFSET = 5; private const int DEL_ENT_BUFFER_MIN_SIZE = 64; @@ -45,12 +47,21 @@ namespace DCFApixels.DragonECS Array.Resize(ref _worlds, newSize); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static EcsWorld GetWorld(int worldID) => _worlds[worldID]; + public static EcsWorld GetWorld(short worldID) + { + return _worlds[worldID]; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref T GetData(int worldID) => ref WorldComponentPool.GetForWorld(worldID); + public static ref T GetData(int worldID) + { + return ref WorldComponentPool.GetForWorld(worldID); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref T GetDataUnchecked(int worldID) => ref WorldComponentPool.GetForWorldUnchecked(worldID); + public static ref T GetDataUnchecked(int worldID) + { + return ref WorldComponentPool.GetForWorldUnchecked(worldID); + } private abstract class DataReleaser { diff --git a/src/Internal/IdDispenser.cs b/src/Internal/IdDispenser.cs index 685e1cc..86850a4 100644 --- a/src/Internal/IdDispenser.cs +++ b/src/Internal/IdDispenser.cs @@ -279,7 +279,7 @@ namespace DCFApixels.DragonECS.Internal #endregion #region UsedToEcsSpan - public EcsSpan UsedToEcsSpan(int worldID) + public EcsSpan UsedToEcsSpan(short worldID) { return new EcsSpan(worldID, _dense, 1, _usedCount - 1); }