diff --git a/src/Builtin/Worlds.cs b/src/Builtin/Worlds.cs index 3278ef9..463d9ee 100644 --- a/src/Builtin/Worlds.cs +++ b/src/Builtin/Worlds.cs @@ -1,18 +1,18 @@ namespace DCFApixels.DragonECS { //TODO использовать этот мир для холостых вызовов. чтоб все нулевые ентити стучались в него, так можно попробовать сократить число проверок - //internal sealed class EcsDeathWrold : EcsWorld + //internal sealed class EcsDeathWrold : EcsWorld //{ // public EcsDeathWrold(EcsPipeline pipeline) : base(pipeline) { } //} - public sealed class EcsDefaultWrold : EcsWorld + public sealed class EcsDefaultWorld : EcsWorld { - public EcsDefaultWrold(EcsPipeline pipeline = null) : base(pipeline) { } + public EcsDefaultWorld(EcsPipeline pipeline = null) : base(pipeline) { } } - public sealed class EcsEventWrold : EcsWorld + public sealed class EcsEventWorld : EcsWorld { - public EcsEventWrold(EcsPipeline pipeline = null) : base(pipeline) { } + public EcsEventWorld(EcsPipeline pipeline = null) : base(pipeline) { } } } diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index b4fcc4e..d7e24f9 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -22,6 +22,9 @@ namespace DCFApixels.DragonECS public abstract class EcsWorld : IEcsWorld { + private const short GEN_BITS = 0x7fff; + private const short DEATH_GEN_BIT = short.MinValue; + public static EcsWorld[] Worlds = new EcsWorld[8]; private static IntDispenser _worldIdDispenser = new IntDispenser(0); public readonly short uniqueID; @@ -72,6 +75,8 @@ namespace DCFApixels.DragonECS #region Constructors/Destroy public EcsWorld(EcsPipeline pipline) { + _entitesCapacity = 512; + uniqueID = (short)_worldIdDispenser.GetFree(); if (uniqueID >= Worlds.Length) Array.Resize(ref Worlds, Worlds.Length << 1); @@ -86,10 +91,10 @@ namespace DCFApixels.DragonECS _pools = new EcsPoolBase[512]; ArrayUtility.Fill(_pools, _nullPool); - _gens = new short[512]; - _entitesCapacity = _gens.Length; + _gens = new short[_entitesCapacity]; + ArrayUtility.Fill(_gens, DEATH_GEN_BIT); _delEntBufferCount = 0; - _delEntBuffer = new int[_gens.Length >> DEL_ENT_BUFFER_SIZE_OFFSET]; + _delEntBuffer = new int[_entitesCapacity >> DEL_ENT_BUFFER_SIZE_OFFSET]; _groups = new List>(); _allEntites = GetGroupFromPool(); @@ -193,7 +198,9 @@ namespace DCFApixels.DragonECS if (_gens.Length <= entityID) { Array.Resize(ref _gens, _gens.Length << 1); + ArrayUtility.Fill(_gens, DEATH_GEN_BIT, _entitesCapacity); _entitesCapacity = _gens.Length; + for (int i = 0; i < _groups.Count; i++) { if (_groups[i].TryGetTarget(out EcsGroup group)) @@ -210,8 +217,9 @@ namespace DCFApixels.DragonECS foreach (var item in _pools) item.InvokeOnWorldResize(_gens.Length); } - _gens[entityID] |= short.MinValue; - EcsEntity entity = new EcsEntity(entityID, _gens[entityID]++, uniqueID); + _gens[entityID] &= GEN_BITS; + EcsEntity entity = new EcsEntity(entityID, ++_gens[entityID], uniqueID); + UnityEngine.Debug.Log($"{entityID} {_gens[entityID]} {uniqueID}"); _entityCreate.OnEntityCreate(entity); _allEntites.Add(entityID); return entity; @@ -220,7 +228,7 @@ namespace DCFApixels.DragonECS { _allEntites.Remove(entity.id); _delEntBuffer[_delEntBufferCount++] = entity.id; - _gens[entity.id] |= short.MinValue; + _gens[entity.id] |= DEATH_GEN_BIT; _entitiesCount--; _entityDestry.OnEntityDestroy(entity); diff --git a/src/Entities/EcsEntity.cs b/src/Entities/EcsEntity.cs index ed41eef..4e939a1 100644 --- a/src/Entities/EcsEntity.cs +++ b/src/Entities/EcsEntity.cs @@ -8,17 +8,17 @@ namespace DCFApixels.DragonECS // gen - 16 bits // world - 16 bits /// Strong identifier/Permanent entity identifier - [StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)] + [StructLayout(LayoutKind.Explicit, Pack =2, Size = 8)] public readonly partial struct EcsEntity : IEquatable, IEquatable { public static readonly EcsEntity NULL = default; [FieldOffset(0)] internal readonly long full; //Union - [FieldOffset(3)] - public readonly int id; - [FieldOffset(1)] - public readonly short gen; [FieldOffset(0)] + public readonly int id; + [FieldOffset(4)] + public readonly short gen; + [FieldOffset(6)] public readonly short world; //[MethodImpl(MethodImplOptions.AggressiveInlining)]