diff --git a/package.json b/package.json index 3fe128b..559235e 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "displayName": "DragonECS", "description": "C# Entity Component System Framework", "unity": "2020.3", - "version": "0.8.0", + "version": "0.8.1", "repository": { "type": "git", "url": "https://github.com/DCFApixels/DragonECS.git" diff --git a/src/Collections/EcsGroup.cs b/src/Collections/EcsGroup.cs index 6323e1c..51fd4ed 100644 --- a/src/Collections/EcsGroup.cs +++ b/src/Collections/EcsGroup.cs @@ -710,7 +710,7 @@ namespace DCFApixels.DragonECS #region Other public override string ToString() { - return $"group{{{string.Join(", ", _dense.Skip(1).Take(_count))}}}"; + return $"group{{{string.Join(", ", _dense.Skip(1).Take(_count).OrderBy(o => o))}}}"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int First() diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index abadc2a..2fb9ee4 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -14,7 +14,6 @@ namespace DCFApixels.DragonECS internal EcsWorld source; internal EcsMask mask; private bool _isInit; - #region Properties public EcsMask Mask => mask; public EcsWorld World => source; @@ -231,6 +230,7 @@ namespace DCFApixels.DragonECS } public static EcsMaskBit FromID(int id) { + short x = 10; return new EcsMaskBit(id >> DIV_SHIFT, 1 << (id & MOD_MASK)); //аналогично new EcsMaskBit(id / BITS, 1 << (id % BITS)) но быстрее } public override string ToString() @@ -408,16 +408,21 @@ namespace DCFApixels.DragonECS public ref struct Enumerator { private ReadOnlySpan.Enumerator _span; - private readonly EcsMaskBit[] _inc; - private readonly EcsMaskBit[] _exc; + private readonly EcsMaskBit[] _incChunckMasks; + private readonly EcsMaskBit[] _excChunckMasks; private readonly int[][] _entitiesComponentMasks; + private int minCount = 0; + public Enumerator(EcsSpan span, EcsMask mask) { _span = span.GetEnumerator(); - _inc = mask.incChunckMasks; - _exc = mask.excChunckMasks; + _incChunckMasks = mask.incChunckMasks; + _excChunckMasks = mask.excChunckMasks; _entitiesComponentMasks = span.World._entitiesComponentMasks; + + + } public int Current { @@ -431,17 +436,17 @@ namespace DCFApixels.DragonECS { int e = _span.Current; EcsMaskBit bit; - for (int i = 0, iMax = _inc.Length; i < iMax; i++) + for (int i = 0, iMax = _incChunckMasks.Length; i < iMax; i++) { - bit = _inc[i]; - //if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) == 0) goto skip; - if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) != bit.mask) goto skip; + bit = _incChunckMasks[i]; + if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) != bit.mask) + goto skip; } - for (int i = 0, iMax = _exc.Length; i < iMax; i++) + for (int i = 0, iMax = _excChunckMasks.Length; i < iMax; i++) { - bit = _exc[i]; - //if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) != 0) goto skip; - if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) == bit.mask) goto skip; + bit = _excChunckMasks[i]; + if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) > 0) + goto skip; } return true; skip: continue; diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index a071784..43ceec2 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -51,6 +51,7 @@ namespace DCFApixels.DragonECS public EcsWorld() : this(true) { } internal EcsWorld(bool isIndexable) { + const int POOLS_CAPACITY = 512; _poolsMediator = new PoolsMediator(this); _entitesCapacity = 512; @@ -64,7 +65,8 @@ namespace DCFApixels.DragonECS } _entityDispenser = new IntDispenser(0); - _pools = new IEcsPoolImplementation[512]; + _pools = new IEcsPoolImplementation[POOLS_CAPACITY]; + //_poolComponentCounts = new int[POOLS_CAPACITY]; ArrayUtility.Fill(_pools, _nullPool); _gens = new short[_entitesCapacity]; @@ -76,7 +78,9 @@ namespace DCFApixels.DragonECS _delEntBuffer = new int[_entitesCapacity]; _entitiesComponentMasks = new int[_entitesCapacity][]; for (int i = 0; i < _entitesCapacity; i++) + { _entitiesComponentMasks[i] = new int[_pools.Length / 32 + 1]; + } _delEntBufferMinCount = Math.Max(_delEntBuffer.Length >> DEL_ENT_BUFFER_SIZE_OFFSET, DEL_ENT_BUFFER_MIN_SIZE); @@ -329,32 +333,6 @@ namespace DCFApixels.DragonECS //public void CloneEntity(int fromEntityID, EcsWorld toWorld, int toEntityID) #endregion - #region Pools mediation - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void RegisterEntityComponent(int entityID, int componentTypeID, EcsMaskBit maskBit) - { - _componentCounts[entityID]++; - _entitiesComponentMasks[entityID][maskBit.chankIndex] |= maskBit.mask; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskBit maskBit) - { - var count = --_componentCounts[entityID]; - _entitiesComponentMasks[entityID][maskBit.chankIndex] &= ~maskBit.mask; - - if (count == 0 && _allEntites.Has(entityID)) - DelEntity(entityID); -#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS - if (count < 0) Throw.World_InvalidIncrementComponentsBalance(); -#endif - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool HasEntityComponent(int entityID, EcsMaskBit maskBit) - { - return (_entitiesComponentMasks[entityID][maskBit.chankIndex] & maskBit.mask) != maskBit.mask; - } - #endregion - #endregion #region DelEntBuffer @@ -521,40 +499,6 @@ namespace DCFApixels.DragonECS } } #endregion - - #region PoolsMediator - public readonly struct PoolsMediator - { - private readonly EcsWorld _world; - internal PoolsMediator(EcsWorld world) - { - if (world == null) - { - throw new ArgumentNullException(); - } - if (world._poolsMediator._world != null) - { - throw new MethodAccessException(); - } - _world = world; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void RegisterComponent(int entityID, int componentTypeID, EcsMaskBit maskBit) - { - _world.RegisterEntityComponent(entityID, componentTypeID, maskBit); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void UnregisterComponent(int entityID, int componentTypeID, EcsMaskBit maskBit) - { - _world.UnregisterEntityComponent(entityID, componentTypeID, maskBit); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool HasComponent(int entityID, EcsMaskBit maskBit) - { - return _world.HasEntityComponent(entityID, maskBit); - } - } - #endregion } #region Callbacks Interface diff --git a/src/EcsWorld.pools.cs b/src/EcsWorld.pools.cs index dd2a53c..f712602 100644 --- a/src/EcsWorld.pools.cs +++ b/src/EcsWorld.pools.cs @@ -12,7 +12,9 @@ namespace DCFApixels.DragonECS private SparseArray _componentIds = new SparseArray(); private int _poolsCount; internal IEcsPoolImplementation[] _pools; - private EcsNullPool _nullPool = EcsNullPool.instance; + //internal int[] _poolComponentCounts; + + private static EcsNullPool _nullPool = EcsNullPool.instance; #region ComponentInfo public int GetComponentID() => DeclareComponentType(EcsTypeCode.Get()); @@ -92,6 +94,7 @@ namespace DCFApixels.DragonECS { int oldCapacity = _pools.Length; Array.Resize(ref _pools, _pools.Length << 1); + //Array.Resize(ref _poolComponentCounts, _pools.Length); ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length); for (int i = 0; i < _entitesCapacity; i++) @@ -107,5 +110,63 @@ namespace DCFApixels.DragonECS return (TPool)_pools[componentTypeID]; } #endregion + + #region Pools mediation + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void RegisterEntityComponent(int entityID, int componentTypeID, EcsMaskBit maskBit) + { + //_poolComponentCounts[componentTypeID]++; + _componentCounts[entityID]++; + _entitiesComponentMasks[entityID][maskBit.chankIndex] |= maskBit.mask; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskBit maskBit) + { + //_poolComponentCounts[componentTypeID]--; + var count = --_componentCounts[entityID]; + _entitiesComponentMasks[entityID][maskBit.chankIndex] &= ~maskBit.mask; + + if (count == 0 && _allEntites.Has(entityID)) + DelEntity(entityID); +#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS + if (count < 0) Throw.World_InvalidIncrementComponentsBalance(); +#endif + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool HasEntityComponent(int entityID, EcsMaskBit maskBit) + { + return (_entitiesComponentMasks[entityID][maskBit.chankIndex] & maskBit.mask) != maskBit.mask; + } + #endregion + + #region PoolsMediator + public readonly struct PoolsMediator + { + private readonly EcsWorld _world; + internal PoolsMediator(EcsWorld world) + { + if (world == null || world._poolsMediator._world != null) + { + throw new MethodAccessException(); + } + _world = world; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RegisterComponent(int entityID, int componentTypeID, EcsMaskBit maskBit) + { + _world.RegisterEntityComponent(entityID, componentTypeID, maskBit); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void UnregisterComponent(int entityID, int componentTypeID, EcsMaskBit maskBit) + { + _world.UnregisterEntityComponent(entityID, componentTypeID, maskBit); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool HasComponent(int entityID, EcsMaskBit maskBit) + { + return _world.HasEntityComponent(entityID, maskBit); + } + } + #endregion } } diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs index 4ccffad..b9314d5 100644 --- a/src/Pools/EcsPoolBase.cs +++ b/src/Pools/EcsPoolBase.cs @@ -84,7 +84,7 @@ namespace DCFApixels.DragonECS public struct NullComponent { } public sealed class EcsNullPool : IEcsPoolImplementation { - public static EcsNullPool instance => new EcsNullPool(); + public static readonly EcsNullPool instance = new EcsNullPool(); #region Properties int IEcsPool.ComponentID => -1;