diff --git a/src/Collections/EcsGroup.cs b/src/Collections/EcsGroup.cs index 7334897..5d70cfe 100644 --- a/src/Collections/EcsGroup.cs +++ b/src/Collections/EcsGroup.cs @@ -400,7 +400,7 @@ namespace DCFApixels.DragonECS { if (++_count >= _dense.Length) { - Array.Resize(ref _dense, ArrayUtility.NormalizeSizeToPowerOfTwo(_count << 1)); + Array.Resize(ref _dense, ArrayUtility.NextPow2(_count << 1)); } _dense[_count] = entityID; @@ -531,7 +531,7 @@ namespace DCFApixels.DragonECS { if (minSize >= _dense.Length) { - Array.Resize(ref _dense, ArrayUtility.NormalizeSizeToPowerOfTwo_ClampOverflow(minSize)); + Array.Resize(ref _dense, ArrayUtility.NextPow2_ClampOverflow(minSize)); } } @@ -618,7 +618,7 @@ namespace DCFApixels.DragonECS { if (dynamicBuffer.Length < _count) { - Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_count)); + Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_count)); } int i = 0; foreach (var e in this) diff --git a/src/Collections/EcsSpan.cs b/src/Collections/EcsSpan.cs index 58bc198..48c26c4 100644 --- a/src/Collections/EcsSpan.cs +++ b/src/Collections/EcsSpan.cs @@ -97,7 +97,7 @@ namespace DCFApixels.DragonECS { if (dynamicBuffer.Length < _values.Length) { - Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_values.Length)); + Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_values.Length)); } int i = 0; foreach (var e in this) @@ -246,7 +246,7 @@ namespace DCFApixels.DragonECS { if (dynamicBuffer.Length < _source.Count) { - Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_source.Count)); + Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_source.Count)); } int i = 0; foreach (var e in this) diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index e4d6ff9..25015ad 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -198,12 +198,12 @@ namespace DCFApixels.DragonECS _poolsMediator = new PoolsMediator(this); - int poolsCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.PoolsCapacity); + int poolsCapacity = ArrayUtility.NextPow2(config.PoolsCapacity); _pools = new IEcsPoolImplementation[poolsCapacity]; _poolSlots = new PoolSlot[poolsCapacity]; ArrayUtility.Fill(_pools, _nullPool); - int entitiesCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.EntitiesCapacity); + int entitiesCapacity = ArrayUtility.NextPow2(config.EntitiesCapacity); _entityDispenser = new IdDispenser(entitiesCapacity, 0, OnEntityDispenserResized); _executorCoures = new Dictionary<(Type, object), IQueryExecutorImplementation>(config.PoolComponentsCapacity); diff --git a/src/Internal/ArrayUtility.cs b/src/Internal/ArrayUtility.cs index 4927430..33dc2a0 100644 --- a/src/Internal/ArrayUtility.cs +++ b/src/Internal/ArrayUtility.cs @@ -92,58 +92,33 @@ namespace DCFApixels.DragonECS.Internal Array.Copy(array, array.Length - rightHeadLength, result, array.Length - rightHeadLength, rightHeadLength); // copy right head array = result; } - private static int GetHighBitNumber(uint bits) - { - if (bits == 0) - { - return -1; - } - int bit = 0; - if ((bits & 0xFFFF0000) != 0) - { - bits >>= 16; - bit |= 16; - } - if ((bits & 0xFF00) != 0) - { - bits >>= 8; - bit |= 8; - } - if ((bits & 0xF0) != 0) - { - bits >>= 4; - bit |= 4; - } - if ((bits & 0xC) != 0) - { - bits >>= 2; - bit |= 2; - } - if ((bits & 0x2) != 0) - { - bit |= 1; - } - return bit; - } - public static int NormalizeSizeToPowerOfTwo(int minSize) + + public static int NextPow2(int v) { unchecked { - return 1 << (GetHighBitNumber((uint)minSize - 1u) + 1); + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + return ++v; } } - public static int NormalizeSizeToPowerOfTwo_ClampOverflow(int minSize) + public static int NextPow2_ClampOverflow(int v) { unchecked { - int hibit = (GetHighBitNumber((uint)minSize - 1u) + 1); - if (hibit >= 32) + const int NO_SIGN_HIBIT = 0x40000000; + if ((v & NO_SIGN_HIBIT) != 0) { return int.MaxValue; } - return 1 << hibit; + return NextPow2(v); } } + public static void Fill(T[] array, T value, int startIndex = 0, int length = -1) { if (length < 0) diff --git a/src/Internal/IdDispenser.cs b/src/Internal/IdDispenser.cs index 3ac1a83..1d4aa21 100644 --- a/src/Internal/IdDispenser.cs +++ b/src/Internal/IdDispenser.cs @@ -247,7 +247,7 @@ namespace DCFApixels.DragonECS.Internal [MethodImpl(MethodImplOptions.NoInlining)] private void Upsize_Internal(int minSize) { - Resize(ArrayUtility.NormalizeSizeToPowerOfTwo_ClampOverflow(minSize)); + Resize(ArrayUtility.NextPow2_ClampOverflow(minSize)); } private void Resize(int newSize) { diff --git a/src/Internal/StructList.cs b/src/Internal/StructList.cs index d7ad9aa..7488304 100644 --- a/src/Internal/StructList.cs +++ b/src/Internal/StructList.cs @@ -26,7 +26,7 @@ namespace DCFApixels.DragonECS.Internal set { if (value <= _items.Length) { return; } - value = ArrayUtility.NormalizeSizeToPowerOfTwo(value); + value = ArrayUtility.NextPow2(value); Array.Resize(ref _items, value); } } @@ -53,7 +53,7 @@ namespace DCFApixels.DragonECS.Internal [MethodImpl(MethodImplOptions.AggressiveInlining)] public StructList(int capacity) { - _items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(capacity)]; + _items = new T[ArrayUtility.NextPow2(capacity)]; _count = 0; } diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index cb4bb09..e7a1218 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -266,7 +266,7 @@ namespace DCFApixels.DragonECS _maskBit = EcsMaskChunck.FromID(componentTypeID); _mapping = new int[world.Capacity]; - _items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(world.Configs.GetWorldConfigOrDefault().PoolComponentsCapacity)]; + _items = new T[ArrayUtility.NextPow2(world.Configs.GetWorldConfigOrDefault().PoolComponentsCapacity)]; _recycledItems = new int[world.Configs.GetWorldConfigOrDefault().PoolRecycledComponentsCapacity]; } void IEcsPoolImplementation.OnWorldResize(int newSize)