diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index 9aa669d..af53d08 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -266,7 +266,7 @@ namespace DCFApixels.DragonECS #endregion private ReadOnlySpan.Enumerator _span; - private readonly int[][] _entitiesComponentMasks; + private readonly int[] _entityComponentMasks; private static EcsMaskChunck* _preSortedIncBuffer; private static EcsMaskChunck* _preSortedExcBuffer; @@ -274,16 +274,19 @@ namespace DCFApixels.DragonECS private UnsafeArray _sortIncChunckBuffer; private UnsafeArray _sortExcChunckBuffer; + private readonly int _entityComponentMaskLength; //private EcsAspect aspect; public unsafe Enumerator(EcsSpan span, EcsAspect aspect) { //this.aspect = aspect; _span = span.GetEnumerator(); - _entitiesComponentMasks = aspect.World._entitiesComponentMasks; + _entityComponentMasks = aspect.World._entityComponentMasks; _sortIncChunckBuffer = aspect._sortIncChunckBuffer; _sortExcChunckBuffer = aspect._sortExcChunckBuffer; + _entityComponentMaskLength = aspect.World._entityComponentMaskLength; + #region Sort UnsafeArray _sortIncBuffer = aspect._sortIncBuffer; UnsafeArray _sortExcBuffer = aspect._sortExcBuffer; @@ -374,13 +377,13 @@ namespace DCFApixels.DragonECS for (int i = 0; i < _sortIncChunckBuffer.Length; i++) { var bit = _sortIncChunckBuffer.ptr[i]; - if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) != bit.mask) + if ((_entityComponentMasks[e * _entityComponentMaskLength + bit.chankIndex] & bit.mask) != bit.mask) goto skip; } for (int i = 0; i < _sortExcChunckBuffer.Length; i++) { var bit = _sortExcChunckBuffer.ptr[i]; - if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) > 0) + if ((_entityComponentMasks[e * _entityComponentMaskLength + bit.chankIndex] & bit.mask) > 0) goto skip; } return true; diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 311bf7e..cea146b 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -22,7 +22,9 @@ namespace DCFApixels.DragonECS private int _delEntBufferCount = 0; private bool _isEnableAutoReleaseDelEntBuffer = true; - internal int[][] _entitiesComponentMasks = Array.Empty(); + internal int _entityComponentMaskLength; + internal int[] _entityComponentMasks = Array.Empty(); + private const int COMPONENT_MATRIX_MASK_BITSIZE = 32; private long _version = 0; @@ -255,14 +257,25 @@ namespace DCFApixels.DragonECS return *(entlong*)&x; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsAlive(int entityID, short gen) { return _gens[entityID] == gen; } - + public bool IsAlive(int entityID, short gen) + { + return _gens[entityID] == gen; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool IsUsed(int entityID) { return _gens[entityID] >= 0; } + public bool IsUsed(int entityID) + { + return _gens[entityID] >= 0; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public short GetGen(int entityID) { return _gens[entityID]; } + public short GetGen(int entityID) + { + return _gens[entityID]; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public short GetComponentsCount(int entityID) { return _componentCounts[entityID]; } + public short GetComponentsCount(int entityID) + { + return _componentCounts[entityID]; + } public bool IsMatchesMask(EcsMask mask, int entityID) { @@ -292,10 +305,6 @@ namespace DCFApixels.DragonECS } } } - //public void Densify() - //{ - // _entityDispenser.Sort(); - //} #endregion #region Copy/Clone @@ -367,7 +376,8 @@ namespace DCFApixels.DragonECS { ReleaseDelEntityBuffer(_delEntBufferCount); } - public void ReleaseDelEntityBuffer(int count) + //private UnsafeArray _delBufferFilter = new UnsafeArray(8); + public unsafe void ReleaseDelEntityBuffer(int count) { if (_delEntBufferCount <= 0) { @@ -376,15 +386,15 @@ namespace DCFApixels.DragonECS unchecked { _version++; } count = Math.Clamp(count, 0, _delEntBufferCount); _delEntBufferCount -= count; - ReadOnlySpan buffser = new ReadOnlySpan(_delEntBuffer, _delEntBufferCount, count); + ReadOnlySpan buffer = new ReadOnlySpan(_delEntBuffer, _delEntBufferCount, count); for (int i = 0; i < _poolsCount; i++) { - _pools[i].OnReleaseDelEntityBuffer(buffser); + _pools[i].OnReleaseDelEntityBuffer(buffer); } - _listeners.InvokeOnReleaseDelEntityBuffer(buffser); - for (int i = 0; i < buffser.Length; i++) + _listeners.InvokeOnReleaseDelEntityBuffer(buffer); + for (int i = 0; i < buffer.Length; i++) { - int e = buffser[i]; + int e = buffer[i]; _entityDispenser.Release(e); unchecked { _gens[e]++; }//up gen _gens[e] |= DEATH_GEN_BIT; @@ -408,14 +418,10 @@ namespace DCFApixels.DragonECS Array.Resize(ref _gens, newSize); Array.Resize(ref _componentCounts, newSize); Array.Resize(ref _delEntBuffer, newSize); - Array.Resize(ref _entitiesComponentMasks, newSize); + _entityComponentMaskLength = _pools.Length / COMPONENT_MATRIX_MASK_BITSIZE + 1; + Array.Resize(ref _entityComponentMasks, newSize * _entityComponentMaskLength); ArrayUtility.Fill(_gens, DEATH_GEN_BIT, _entitiesCapacity); - int maskLength = _pools.Length / 32 + 1; - for (int i = _entitiesCapacity; i < newSize; i++) - { - _entitiesComponentMasks[i] = new int[maskLength]; - } _entitiesCapacity = newSize; diff --git a/src/EcsWorld.pools.cs b/src/EcsWorld.pools.cs index 93e88bd..09fca4a 100644 --- a/src/EcsWorld.pools.cs +++ b/src/EcsWorld.pools.cs @@ -136,10 +136,35 @@ namespace DCFApixels.DragonECS Array.Resize(ref _poolComponentCounts, _pools.Length); ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length); - for (int i = 0; i < _entitiesCapacity; i++) + //for (int i = 0; i < _entitiesCapacity; i++) + //{ + // //Array.Resize(ref _entityComponentMasks[i], _pools.Length / 32 + 1); + //} + + int newEntityComponentMaskLength = _pools.Length / COMPONENT_MATRIX_MASK_BITSIZE + 1; + int dif = newEntityComponentMaskLength - _entityComponentMaskLength; + if (dif > 0) { - Array.Resize(ref _entitiesComponentMasks[i], _pools.Length / 32 + 1); + int[] newEntityComponentMasks = new int[_entitiesCapacity * newEntityComponentMaskLength]; + int indxMax = _entityComponentMaskLength * _entitiesCapacity; + int indx = 0; + int newIndx = 0; + int nextIndx = _entityComponentMaskLength; + while (indx < indxMax) + { + while (indx < nextIndx) + { + newEntityComponentMasks[newIndx] = _entityComponentMasks[indx]; + indx++; + newIndx++; + } + newIndx += dif; + nextIndx += _entityComponentMaskLength; + } + _entityComponentMaskLength = newEntityComponentMaskLength; + _entityComponentMasks = newEntityComponentMasks; } + } if (_pools[componentTypeID] != _nullPool) @@ -160,14 +185,14 @@ namespace DCFApixels.DragonECS { _poolComponentCounts[componentTypeID]++; _componentCounts[entityID]++; - _entitiesComponentMasks[entityID][maskBit.chankIndex] |= maskBit.mask; + _entityComponentMasks[entityID * _entityComponentMaskLength + maskBit.chankIndex] |= maskBit.mask; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit) { _poolComponentCounts[componentTypeID]--; var count = --_componentCounts[entityID]; - _entitiesComponentMasks[entityID][maskBit.chankIndex] &= ~maskBit.mask; + _entityComponentMasks[entityID * _entityComponentMaskLength + maskBit.chankIndex] &= ~maskBit.mask; if (count == 0 && IsUsed(entityID)) { @@ -180,7 +205,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool HasEntityComponent(int entityID, EcsMaskChunck maskBit) { - return (_entitiesComponentMasks[entityID][maskBit.chankIndex] & maskBit.mask) != maskBit.mask; + return (_entityComponentMasks[entityID * _entityComponentMaskLength + maskBit.chankIndex] & maskBit.mask) != maskBit.mask; } #endregion