diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index acc27b6..921fe8a 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -26,6 +26,7 @@ namespace DCFApixels.DragonECS private bool _isHasComponentCopyHandler = EcsComponentCopyHandler.isHasHandler; private List _listeners = new List(); + private int _listenersCachedCount = 0; private EcsWorld.PoolsMediator _mediator; @@ -78,7 +79,7 @@ namespace DCFApixels.DragonECS } _mediator.RegisterComponent(entityID, _componentTypeID, _maskBit); EnableComponent(ref _items[itemIndex]); - _listeners.InvokeOnAddAndGet(entityID); + _listeners.InvokeOnAddAndGet(entityID, _listenersCachedCount); return ref _items[itemIndex]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -87,7 +88,7 @@ namespace DCFApixels.DragonECS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent(entityID); } #endif - _listeners.InvokeOnGet(entityID); + _listeners.InvokeOnGet(entityID, _listenersCachedCount); return ref _items[_mapping[entityID]]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -118,9 +119,9 @@ namespace DCFApixels.DragonECS } _mediator.RegisterComponent(entityID, _componentTypeID, _maskBit); EnableComponent(ref _items[itemIndex]); - _listeners.InvokeOnAdd(entityID); + _listeners.InvokeOnAdd(entityID, _listenersCachedCount); } - _listeners.InvokeOnGet(entityID); + _listeners.InvokeOnGet(entityID, _listenersCachedCount); return ref _items[itemIndex]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -143,7 +144,7 @@ namespace DCFApixels.DragonECS itemIndex = 0; _itemsCount--; _mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit); - _listeners.InvokeOnDel(entityID); + _listeners.InvokeOnDel(entityID, _listenersCachedCount); } public void TryDel(int entityID) { @@ -178,7 +179,7 @@ namespace DCFApixels.DragonECS DisableComponent(ref _items[itemIndex]); itemIndex = 0; _mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit); - _listeners.InvokeOnDel(entityID); + _listeners.InvokeOnDel(entityID, _listenersCachedCount); } } #endregion @@ -230,11 +231,15 @@ namespace DCFApixels.DragonECS { if (listener == null) { throw new ArgumentNullException("listener is null"); } _listeners.Add(listener); + _listenersCachedCount++; } public void RemoveListener(IEcsPoolEventListener listener) { if (listener == null) { throw new ArgumentNullException("listener is null"); } - _listeners.Remove(listener); + if (_listeners.Remove(listener)) + { + _listenersCachedCount--; + } } #endregion diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs index eb9391c..2f03486 100644 --- a/src/Pools/EcsPoolBase.cs +++ b/src/Pools/EcsPoolBase.cs @@ -202,26 +202,49 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void InvokeOnAdd(this List self, int entityID) { - for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnAdd(entityID); + self.InvokeOnAdd(entityID, self.Count); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnAdd(this List self, int entityID, int cachedCount) + { + for (int i = 0; i < cachedCount; i++) self[i].OnAdd(entityID); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void InvokeOnAddAndGet(this List self, int entityID) { - for (int i = 0, iMax = self.Count; i < iMax; i++) + self.InvokeOnAddAndGet(entityID, self.Count); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnAddAndGet(this List self, int entityID, int cachedCount) + { + for (int i = 0; i < cachedCount; i++) { self[i].OnAdd(entityID); self[i].OnGet(entityID); } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void InvokeOnGet(this List self, int entityID) { - for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnGet(entityID); + self.InvokeOnGet(entityID, self.Count); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void InvokeOnGet(this List self, int entityID, int cachedCount) + { + for (int i = 1; i < cachedCount; i++) self[i].OnGet(entityID); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void InvokeOnDel(this List self, int entityID) { - for (int i = 0, iMax = self.Count; i < iMax; i++) self[i].OnDel(entityID); + self.InvokeOnDel(entityID, self.Count); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InvokeOnDel(this List self, int entityID, int cachedCount) + { + for (int i = 0; i < cachedCount; i++) self[i].OnDel(entityID); } } #endregion diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index 3558791..c39c5c8 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -17,6 +17,7 @@ namespace DCFApixels.DragonECS private int _count = 0; private List _listeners = new List(); + private int _listenersCachedCount = 0; private T _fakeComponent; private EcsWorld.PoolsMediator _mediator; @@ -72,7 +73,7 @@ namespace DCFApixels.DragonECS _count++; _mapping[entityID] = true; _mediator.RegisterComponent(entityID, _componentTypeID, _maskBit); - _listeners.InvokeOnAdd(entityID); + _listeners.InvokeOnAdd(entityID, _listenersCachedCount); } public void TryAdd(int entityID) { @@ -94,7 +95,7 @@ namespace DCFApixels.DragonECS _mapping[entityID] = false; _count--; _mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit); - _listeners.InvokeOnDel(entityID); + _listeners.InvokeOnDel(entityID, _listenersCachedCount); } public void TryDel(int entityID) { @@ -154,7 +155,7 @@ namespace DCFApixels.DragonECS { _mapping[entityID] = false; _mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit); - _listeners.InvokeOnDel(entityID); + _listeners.InvokeOnDel(entityID, _listenersCachedCount); } } #endregion @@ -229,11 +230,15 @@ namespace DCFApixels.DragonECS { if (listener == null) { throw new ArgumentNullException("listener is null"); } _listeners.Add(listener); + _listenersCachedCount++; } public void RemoveListener(IEcsPoolEventListener listener) { if (listener == null) { throw new ArgumentNullException("listener is null"); } - _listeners.Remove(listener); + if (_listeners.Remove(listener)) + { + _listenersCachedCount--; + } } #endregion