diff --git a/DragonECS.csproj b/DragonECS.csproj index ec34c10..44dcf4f 100644 --- a/DragonECS.csproj +++ b/DragonECS.csproj @@ -10,7 +10,7 @@ DCFApixels.DragonECS DragonECS - 0.9.16 + 0.9.20 DCFApixels ECS Framework for Game Engines with C# and .Net Platform DCFApixels diff --git a/package.json b/package.json index a376ddc..e596002 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "displayName": "DragonECS", "description": "C# Entity Component System Framework", "unity": "2020.3", - "version": "0.9.16", + "version": "0.9.20", "repository": { "type": "git", "url": "https://github.com/DCFApixels/DragonECS.git" diff --git a/src/Collections/EcsGroup.cs b/src/Collections/EcsGroup.cs index b7b2cce..ee7fd30 100644 --- a/src/Collections/EcsGroup.cs +++ b/src/Collections/EcsGroup.cs @@ -442,7 +442,7 @@ namespace DCFApixels.DragonECS { if (++_count >= _dense.Length) { - Array.Resize(ref _dense, ArrayUtility.NextPow2(_count << 1)); + Array.Resize(ref _dense, ArrayUtility.NextPow2(_count)); } _dense[_count] = entityID; @@ -576,7 +576,7 @@ namespace DCFApixels.DragonECS { if (minSize >= _dense.Length) { - Array.Resize(ref _dense, ArrayUtility.NextPow2_ClampOverflow(minSize)); + Array.Resize(ref _dense, ArrayUtility.CeilPow2_ClampOverflow(minSize)); } } @@ -663,7 +663,7 @@ namespace DCFApixels.DragonECS { if (dynamicBuffer.Length < _count) { - Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_count)); + Array.Resize(ref dynamicBuffer, ArrayUtility.CeilPow2(_count)); } int i = 0; foreach (var e in this) diff --git a/src/Collections/EcsSpan.cs b/src/Collections/EcsSpan.cs index 86a0ce2..d68ee27 100644 --- a/src/Collections/EcsSpan.cs +++ b/src/Collections/EcsSpan.cs @@ -98,7 +98,7 @@ namespace DCFApixels.DragonECS { if (dynamicBuffer.Length < _values.Length) { - Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_values.Length)); + Array.Resize(ref dynamicBuffer, ArrayUtility.CeilPow2(_values.Length)); } int i = 0; foreach (var e in this) @@ -247,7 +247,7 @@ namespace DCFApixels.DragonECS { if (dynamicBuffer.Length < _source.Count) { - Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_source.Count)); + Array.Resize(ref dynamicBuffer, ArrayUtility.CeilPow2(_source.Count)); } int i = 0; foreach (var e in this) diff --git a/src/DebugUtils/EcsDebug.cs b/src/DebugUtils/EcsDebug.cs index 6e525a4..838ae2c 100644 --- a/src/DebugUtils/EcsDebug.cs +++ b/src/DebugUtils/EcsDebug.cs @@ -525,7 +525,7 @@ namespace DCFApixels.DragonECS.Core { if (id >= _stopwatchs.Length) { - Array.Resize(ref _stopwatchs, id << 1); + Array.Resize(ref _stopwatchs, ArrayUtility.NextPow2(id)); } _stopwatchs[id] = new MarkerData(new System.Diagnostics.Stopwatch(), name, id); } diff --git a/src/EcsMask.cs b/src/EcsMask.cs index 3521ad0..2aa5376 100644 --- a/src/EcsMask.cs +++ b/src/EcsMask.cs @@ -75,7 +75,7 @@ namespace DCFApixels.DragonECS get { return _anys; } } public EcsMaskFlags Flags - { + { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _flags; } } @@ -876,7 +876,7 @@ namespace DCFApixels.DragonECS } } - if(_sortAnyChunckBuffer.Length != 0) + if (_sortAnyChunckBuffer.Length != 0) { for (int i = 0; i < _sortAnyChunckBuffer.Length; i++) { diff --git a/src/EcsPipeline.Builder.cs b/src/EcsPipeline.Builder.cs index 64b6309..e06c7ae 100644 --- a/src/EcsPipeline.Builder.cs +++ b/src/EcsPipeline.Builder.cs @@ -245,7 +245,7 @@ namespace DCFApixels.DragonECS Configs.Instance.Set(config.Key, config.Value); } Layers.MergeWith(other.Layers); - + foreach (ref readonly SystemNode otherRecord in new LinkedListCountIterator(_systemNodes, _systemNodesCount, _startIndex)) { AddNode_Internal(otherRecord.system, otherRecord.layerName, otherRecord.sortOrder, otherRecord.isUnique); @@ -351,7 +351,7 @@ namespace DCFApixels.DragonECS //} } - + IEcsProcess[] allSystems = new IEcsProcess[allSystemsLength]; { int i = 0; diff --git a/src/EcsStaticMask.cs b/src/EcsStaticMask.cs index 840ac11..b34bb38 100644 --- a/src/EcsStaticMask.cs +++ b/src/EcsStaticMask.cs @@ -457,9 +457,9 @@ namespace DCFApixels.DragonECS combinedIncs = combinerBuilder._incsSet; combinedExcs = combinerBuilder._excsSet; combinedAnys = combinerBuilder._anysSet; - combinedIncs.Union(_incsSet); - combinedExcs.Union(_excsSet); - combinedAnys.Union(_anysSet); + combinedIncs.UnionWith(_incsSet); + combinedExcs.UnionWith(_excsSet); + combinedAnys.UnionWith(_anysSet); if (_sortedCombinedChecker == false) { diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 3425c50..2ce52bb 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -182,7 +182,11 @@ namespace DCFApixels.DragonECS if (worldID < 0 || (worldID == NULL_WORLD_ID && nullWorld == false)) { - worldID = (short)_worldIdDispenser.UseFree(); + int newID = _worldIdDispenser.UseFree(); +#if DEBUG && DRAGONECS_DEEP_DEBUG + if (newID > short.MaxValue) { Throw.DeepDebugException(); } +#endif + worldID = (short)newID; } else { @@ -201,12 +205,12 @@ namespace DCFApixels.DragonECS _poolsMediator = new PoolsMediator(this); - int poolsCapacity = ArrayUtility.NextPow2(config.PoolsCapacity); + int poolsCapacity = ArrayUtility.CeilPow2Safe(config.PoolsCapacity); _pools = new IEcsPoolImplementation[poolsCapacity]; _poolSlots = new PoolSlot[poolsCapacity]; ArrayUtility.Fill(_pools, _nullPool); - int entitiesCapacity = ArrayUtility.NextPow2(config.EntitiesCapacity); + int entitiesCapacity = ArrayUtility.CeilPow2Safe(config.EntitiesCapacity); _entityDispenser = new IdDispenser(entitiesCapacity, 0, OnEntityDispenserResized); _executorCoures = new Dictionary<(Type, object), IQueryExecutorImplementation>(config.PoolComponentsCapacity); @@ -566,12 +570,12 @@ namespace DCFApixels.DragonECS count++; } } - if(count == 0) + if (count == 0) { return false; } } - + return true; } bool deepDebug = IsMatchesMaskDeepDebug(mask, entityID); @@ -1105,7 +1109,7 @@ namespace DCFApixels.DragonECS public ReadOnlySpan GetComponentsFor(int entityID) { int count = GetComponentTypeIDsFor_Internal(entityID, ref _componentIDsBuffer); - ArrayUtility.UpsizeWithoutCopy(ref _componentIDsBuffer, count); + ArrayUtility.UpsizeWithoutCopy(ref _componentsBuffer, count); for (int i = 0; i < count; i++) { diff --git a/src/EcsWorld.static.cs b/src/EcsWorld.static.cs index 9d85021..033321a 100644 --- a/src/EcsWorld.static.cs +++ b/src/EcsWorld.static.cs @@ -202,7 +202,7 @@ namespace DCFApixels.DragonECS if (_items.Length <= itemIndex) { - Array.Resize(ref _items, _items.Length << 1); + Array.Resize(ref _items, ArrayUtility.NextPow2(itemIndex)); } #if DEBUG @@ -234,14 +234,21 @@ namespace DCFApixels.DragonECS Array.Resize(ref _mapping, _worlds.Length); } ref short itemIndex = ref _mapping[worldID]; +#if DEBUG && DRAGONECS_DEEP_DEBUG + if (itemIndex >= _worlds.Length) + { + Throw.UndefinedException(); + } +#endif if (itemIndex != 0) { _interface.OnDestroy(ref _items[itemIndex], _worlds[worldID]); if (_recycledItemsCount >= _recycledItems.Length) { - Array.Resize(ref _recycledItems, _recycledItems.Length << 1); + Array.Resize(ref _recycledItems, ArrayUtility.NextPow2(_recycledItemsCount)); } _recycledItems[_recycledItemsCount++] = itemIndex; + _items[itemIndex] = default; itemIndex = 0; } } diff --git a/src/Executors/MaskQueryExecutor.cs b/src/Executors/MaskQueryExecutor.cs index 9008aad..e835c66 100644 --- a/src/Executors/MaskQueryExecutor.cs +++ b/src/Executors/MaskQueryExecutor.cs @@ -157,7 +157,7 @@ namespace DCFApixels.DragonECS.Core var slots = _world._poolSlots; for (int i = 1; i < _count; i++) { - if(_versions[i] == slots[_componentIDs[i]].version) + if (_versions[i] == slots[_componentIDs[i]].version) { return false; } diff --git a/src/Injections/Injector.cs b/src/Injections/Injector.cs index 8786867..df558b0 100644 --- a/src/Injections/Injector.cs +++ b/src/Injections/Injector.cs @@ -16,7 +16,7 @@ namespace DCFApixels.DragonECS private readonly Dictionary _nodes = new Dictionary(32); private ReadOnlySpan GetNodes(Type type) { - if(_branches.TryGetValue(type, out InjectionBranch branch)) + if (_branches.TryGetValue(type, out InjectionBranch branch)) { return branch.Nodes; } @@ -34,7 +34,7 @@ namespace DCFApixels.DragonECS private ReadOnlySpan EndReadHistory_Internal(int startIndex) { _injectionTempHistoryReadersCount--; - if(_injectionTempHistoryReadersCount < 0) + if (_injectionTempHistoryReadersCount < 0) { Throw.OpeningClosingMethodsBalanceError(); } @@ -45,7 +45,7 @@ namespace DCFApixels.DragonECS } return result; } - public readonly struct InjectionHistorySpanReader + public readonly struct InjectionHistorySpanReader { private readonly Injector _injector; private readonly int _startIndex; diff --git a/src/Internal/Allocators/MemoryAllocator.cs b/src/Internal/Allocators/MemoryAllocator.cs index d833d90..c0f2afc 100644 --- a/src/Internal/Allocators/MemoryAllocator.cs +++ b/src/Internal/Allocators/MemoryAllocator.cs @@ -61,7 +61,7 @@ namespace DCFApixels.DragonECS.Core.Internal { if (_debugInfos.Length <= _idDispenser.Count) { - Array.Resize(ref _debugInfos, _debugInfos.Length << 1); + Array.Resize(ref _debugInfos, ArrayUtility.NextPow2(_idDispenser.Count)); } id = _idDispenser.UseFree(); } diff --git a/src/Internal/ArrayUtility.cs b/src/Internal/ArrayUtility.cs index 7d2f7ac..1dbbb2d 100644 --- a/src/Internal/ArrayUtility.cs +++ b/src/Internal/ArrayUtility.cs @@ -144,7 +144,19 @@ namespace DCFApixels.DragonECS.Core.Internal array = result; } + public static int NextPow2Safe(int v, int min = 4) + { + return NextPow2(v < min ? min : v); + } public static int NextPow2(int v) + { + return CeilPow2(v | 1); + } + public static int CeilPow2Safe(int v, int min = 4) + { + return CeilPow2(v < min ? min : v); + } + public static int CeilPow2(int v) { unchecked { @@ -157,7 +169,7 @@ namespace DCFApixels.DragonECS.Core.Internal return ++v; } } - public static int NextPow2_ClampOverflow(int v) + public static int CeilPow2_ClampOverflow(int v) { unchecked { @@ -166,7 +178,7 @@ namespace DCFApixels.DragonECS.Core.Internal { return int.MaxValue; } - return NextPow2(v); + return CeilPow2(v); } } @@ -205,19 +217,18 @@ namespace DCFApixels.DragonECS.Core.Internal Array.Resize(ref array, minSize); } } - public static void UpsizeToNextPow2(ref T[] array, int minSize) - { - if (array == null) - { - minSize = NextPow2(minSize); - array = new T[minSize]; - } - else if (minSize > array.Length) - { - minSize = NextPow2(minSize); - Array.Resize(ref array, minSize); - } - } + //public static void UpsizeToCeilPow2(ref T[] array, int newSize, int minSize = 4) + //{ + // newSize = CeilPow2(newSize < minSize ? minSize : newSize); + // if (array == null) + // { + // array = new T[newSize]; + // } + // else if (newSize > array.Length) + // { + // Array.Resize(ref array, newSize); + // } + //} } internal readonly struct EnumerableInt : IEnumerable { diff --git a/src/Internal/IdDispenser.cs b/src/Internal/IdDispenser.cs index 97ae478..d0b531e 100644 --- a/src/Internal/IdDispenser.cs +++ b/src/Internal/IdDispenser.cs @@ -248,7 +248,7 @@ namespace DCFApixels.DragonECS.Core.Internal [MethodImpl(MethodImplOptions.NoInlining)] private void Upsize_Internal(int minSize) { - Resize(ArrayUtility.NextPow2_ClampOverflow(minSize)); + Resize(ArrayUtility.CeilPow2_ClampOverflow(minSize)); } private void Resize(int newSize) { diff --git a/src/Internal/StructList.cs b/src/Internal/StructList.cs index 4331c09..497cc92 100644 --- a/src/Internal/StructList.cs +++ b/src/Internal/StructList.cs @@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS.Core.Internal set { if (value <= _items.Length) { return; } - value = ArrayUtility.NextPow2(value); + value = ArrayUtility.CeilPow2Safe(value); Array.Resize(ref _items, value); } } @@ -64,7 +64,7 @@ namespace DCFApixels.DragonECS.Core.Internal [MethodImpl(MethodImplOptions.AggressiveInlining)] public StructList(int capacity) { - _items = new T[ArrayUtility.NextPow2(capacity)]; + _items = new T[ArrayUtility.CeilPow2Safe(capacity)]; _count = 0; } #endregion @@ -226,7 +226,7 @@ namespace DCFApixels.DragonECS.Core.Internal [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Recreate(int newSize) { - _items = new T[ArrayUtility.NextPow2(newSize)]; + _items = new T[ArrayUtility.CeilPow2Safe(newSize)]; _count = 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index 8e11780..943d6c7 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -94,7 +94,7 @@ namespace DCFApixels.DragonECS public EcsPool() { } public EcsPool(int capacity, int recycledCapacity = -1) { - capacity = ArrayUtility.NextPow2(capacity); + capacity = ArrayUtility.CeilPow2Safe(capacity); if (recycledCapacity < 0) { recycledCapacity = capacity / 2; @@ -113,7 +113,7 @@ namespace DCFApixels.DragonECS var worldConfig = world.Configs.GetWorldConfigOrDefault(); if (_items == null) { - _items = new T[ArrayUtility.NextPow2(worldConfig.PoolComponentsCapacity)]; + _items = new T[ArrayUtility.CeilPow2Safe(worldConfig.PoolComponentsCapacity)]; } if (_recycledItems == null) { @@ -128,8 +128,8 @@ namespace DCFApixels.DragonECS { ref int itemIndex = ref _mapping[entityID]; #if DEBUG - if (entityID == EcsConsts.NULL_ENTITY_ID) { Throw.Ent_ThrowIsNotAlive(_source, entityID); } - if (_source.IsUsed(entityID) == false) { Throw.Ent_ThrowIsNotAlive(_source, entityID); } + if (entityID == EcsConsts.NULL_ENTITY_ID) { EcsPoolThrowHelper.ThrowEntityIsNotAlive(_source, entityID); } + if (_source.IsUsed(entityID) == false) { EcsPoolThrowHelper.ThrowEntityIsNotAlive(_source, entityID); } if (itemIndex > 0) { EcsPoolThrowHelper.ThrowAlreadyHasComponent(entityID); } if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } #elif DRAGONECS_STABILITY_MODE @@ -146,7 +146,7 @@ namespace DCFApixels.DragonECS itemIndex = ++_itemsCount; if (itemIndex >= _items.Length) { - Array.Resize(ref _items, _items.Length << 1); + Array.Resize(ref _items, ArrayUtility.NextPow2(itemIndex)); } } _mediator.RegisterComponent(entityID, _componentTypeID, _maskBit); @@ -179,7 +179,7 @@ namespace DCFApixels.DragonECS public ref T TryAddOrGet(int entityID) { #if DEBUG - if (entityID == EcsConsts.NULL_ENTITY_ID) { Throw.Ent_ThrowIsNotAlive(_source, entityID); } + if (entityID == EcsConsts.NULL_ENTITY_ID) { EcsPoolThrowHelper.ThrowEntityIsNotAlive(_source, entityID); } #endif ref int itemIndex = ref _mapping[entityID]; if (itemIndex <= 0) @@ -199,7 +199,7 @@ namespace DCFApixels.DragonECS itemIndex = ++_itemsCount; if (itemIndex >= _items.Length) { - Array.Resize(ref _items, _items.Length << 1); + Array.Resize(ref _items, ArrayUtility.NextPow2(itemIndex)); } } _mediator.RegisterComponent(entityID, _componentTypeID, _maskBit); @@ -222,7 +222,7 @@ namespace DCFApixels.DragonECS { ref int itemIndex = ref _mapping[entityID]; #if DEBUG - if (entityID == EcsConsts.NULL_ENTITY_ID) { Throw.Ent_ThrowIsNotAlive(_source, entityID); } + if (entityID == EcsConsts.NULL_ENTITY_ID) { EcsPoolThrowHelper.ThrowEntityIsNotAlive(_source, entityID); } if (itemIndex <= 0) { EcsPoolThrowHelper.ThrowNotHaveComponent(entityID); } if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } #elif DRAGONECS_STABILITY_MODE @@ -232,7 +232,7 @@ namespace DCFApixels.DragonECS DisableComponent(ref _items[itemIndex]); if (_recycledItemsCount >= _recycledItems.Length) { - Array.Resize(ref _recycledItems, _recycledItems.Length << 1); + Array.Resize(ref _recycledItems, ArrayUtility.NextPow2Safe(_recycledItemsCount)); } _recycledItems[_recycledItemsCount++] = itemIndex; itemIndex = 0; diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs index 8d4d93a..d7423e6 100644 --- a/src/Pools/EcsPoolBase.cs +++ b/src/Pools/EcsPoolBase.cs @@ -45,6 +45,11 @@ namespace DCFApixels.DragonECS.PoolsCore throw new ArgumentException($"Entity({entityID}) has no component {EcsDebugUtility.GetGenericTypeName()}."); } [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowEntityIsNotAlive(EcsWorld world, int entityID) + { + Throw.Ent_ThrowIsNotAlive((world, entityID)); + } + [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowAlreadyHasComponent(Type type, int entityID) { throw new ArgumentException($"Entity({entityID}) already has component {EcsDebugUtility.GetGenericTypeName(type)}."); @@ -316,7 +321,7 @@ namespace DCFApixels.DragonECS self.InvokeOnGet(entityID, self.Count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void InvokeOnGet(this List self, int entityID, int cachedCount) + public static void InvokeOnGet(this List self, int entityID, int cachedCount) { for (int i = 1; i < cachedCount; i++) { self[i].OnGet(entityID); } } @@ -336,17 +341,17 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void InvokeOnAdd(this StructList self, int entityID) + internal static void InvokeOnAdd(ref this StructList self, int entityID) { for (int i = 0; i < self.Count; i++) { self[i].OnAdd(entityID); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void InvokeOnAdd(this StructList self, int entityID, int cachedCount) + internal static void InvokeOnAdd(ref this StructList self, int entityID, int cachedCount) { for (int i = 0; i < cachedCount; i++) { self[i].OnAdd(entityID); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void InvokeOnAddAndGet(this StructList self, int entityID) + internal static void InvokeOnAddAndGet(ref this StructList self, int entityID) { for (int i = 0; i < self.Count; i++) { @@ -355,7 +360,7 @@ namespace DCFApixels.DragonECS } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void InvokeOnAddAndGet(this StructList self, int entityID, int cachedCount) + internal static void InvokeOnAddAndGet(ref this StructList self, int entityID, int cachedCount) { for (int i = 0; i < cachedCount; i++) { @@ -364,22 +369,22 @@ namespace DCFApixels.DragonECS } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void InvokeOnGet(this StructList self, int entityID) + internal static void InvokeOnGet(ref this StructList self, int entityID) { for (int i = 1; i < self.Count; i++) { self[i].OnGet(entityID); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void InvokeOnGet(this StructList self, int entityID, int cachedCount) + internal static void InvokeOnGet(ref this StructList self, int entityID, int cachedCount) { for (int i = 1; i < cachedCount; i++) { self[i].OnGet(entityID); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void InvokeOnDel(this StructList self, int entityID) + internal static void InvokeOnDel(ref this StructList self, int entityID) { for (int i = 0; i < self.Count; i++) { self[i].OnDel(entityID); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void InvokeOnDel(this StructList self, int entityID, int cachedCount) + internal static void InvokeOnDel(ref this StructList self, int entityID, int cachedCount) { for (int i = 0; i < cachedCount; i++) { self[i].OnDel(entityID); } } diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index 885184c..536fe9c 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -116,7 +116,7 @@ namespace DCFApixels.DragonECS public void Add(int entityID) { #if DEBUG - if (_source.IsUsed(entityID) == false) { Throw.Ent_ThrowIsNotAlive(_source, entityID); } + if (_source.IsUsed(entityID) == false) { EcsPoolThrowHelper.ThrowEntityIsNotAlive(_source, entityID); } if (Has(entityID)) { EcsPoolThrowHelper.ThrowAlreadyHasComponent(entityID); } if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } #elif DRAGONECS_STABILITY_MODE