diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index d025f82..4bbfbed 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -113,9 +113,6 @@ namespace DCFApixels.DragonECS private EcsWorld _world; private EcsStaticMask.Builder _maskBuilder; - //private IEcsPool[] _poolsBuffer = new IEcsPool[8]; - //private int _poolsBufferCount; - #region Properties public IncludeMarker Inc { @@ -219,11 +216,6 @@ namespace DCFApixels.DragonECS private TPool CachePool() where TPool : IEcsPoolImplementation, new() { var pool = _world.GetPoolInstance(); - //if (_poolsBufferCount >= _poolsBuffer.Length) - //{ - // Array.Resize(ref _poolsBuffer, _poolsBuffer.Length << 1); - //} - //_poolsBuffer[_poolsBufferCount++] = pool; return pool; } private void IncludeImplicit(Type type) @@ -374,25 +366,25 @@ namespace DCFApixels.DragonECS #endregion } - #region EcsAspectExtensions - //public static class EcsAspectExtensions - //{ - // public static EcsAspect.Builder Inc(this EcsAspect.Builder self, ref TPool pool) where TPool : IEcsPoolImplementation, new() - // { - // pool = self.IncludePool(); - // return self; - // } - // public static EcsAspect.Builder Exc(this EcsAspect.Builder self, ref TPool pool) where TPool : IEcsPoolImplementation, new() - // { - // pool = self.ExcludePool(); - // return self; - // } - // public static EcsAspect.Builder Opt(this EcsAspect.Builder self, ref TPool pool) where TPool : IEcsPoolImplementation, new() - // { - // pool = self.OptionalPool(); - // return self; - // } - //} + #region EcsAspect.Builder.Extensions + public static class EcsAspectBuilderExtensions + { + public static EcsAspect.Builder Inc(this EcsAspect.Builder self, ref TPool pool) where TPool : IEcsPoolImplementation, new() + { + pool = self.IncludePool(); + return self; + } + public static EcsAspect.Builder Exc(this EcsAspect.Builder self, ref TPool pool) where TPool : IEcsPoolImplementation, new() + { + pool = self.ExcludePool(); + return self; + } + public static EcsAspect.Builder Opt(this EcsAspect.Builder self, ref TPool pool) where TPool : IEcsPoolImplementation, new() + { + pool = self.OptionalPool(); + return self; + } + } #endregion #region Constraint Markers diff --git a/src/EcsWorld.pools.cs b/src/EcsWorld.pools.cs index bf30c72..763e0c6 100644 --- a/src/EcsWorld.pools.cs +++ b/src/EcsWorld.pools.cs @@ -374,40 +374,38 @@ namespace DCFApixels.DragonECS { #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS ref var slot = ref _poolSlots[componentTypeID]; - if (slot.locked == false) + if (slot.lockedCounter == 0) { - slot.locked = true; - if (_lockedPoolCount == 0) - { - ReleaseDelEntityBufferAll(); - } + //очистка буффера, чтобы она рандомно не сработала в блоке блоикровки пула + ReleaseDelEntityBufferAll(); _lockedPoolCount++; - _pools[componentTypeID].OnLockedChanged_Debug(true); } + slot.lockedCounter++; + _pools[componentTypeID].OnLockedChanged_Debug(true); #endif } public void UnlockPool_Debug(int componentTypeID) { #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS ref var slot = ref _poolSlots[componentTypeID]; - if (slot.locked == true) + slot.lockedCounter--; + if (slot.lockedCounter <= 0) { - slot.locked = false; _lockedPoolCount--; - - if (_lockedPoolCount < 0) + if (_lockedPoolCount < 0 || slot.lockedCounter < 0) { _lockedPoolCount = 0; + slot.lockedCounter = 0; Throw.OpeningClosingMethodsBalanceError(); } - _pools[componentTypeID].OnLockedChanged_Debug(false); } + _pools[componentTypeID].OnLockedChanged_Debug(false); #endif } public bool CheckPoolLocked_Debug(int componentTypeID) { #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS - return _poolSlots[componentTypeID].locked; + return _poolSlots[componentTypeID].lockedCounter != 0; #else return false; #endif @@ -417,10 +415,10 @@ namespace DCFApixels.DragonECS #region Utils internal struct PoolSlot { - public int count; public long version; + public int count; #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS - public bool locked; + public int lockedCounter; #endif } public readonly ref struct GetPoolInstanceMarker diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index c347dc8..87c1ff0 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -3,6 +3,7 @@ using DCFApixels.DragonECS.PoolsCore; using System; using System.Collections; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Runtime.CompilerServices; #if ENABLE_IL2CPP @@ -46,7 +47,7 @@ namespace DCFApixels.DragonECS private bool _isHasComponentCopyHandler = EcsComponentCopyHandler.isHasHandler; #if !DISABLE_POOLS_EVENTS - private readonly List _listeners = new List(); + private readonly StructList _listeners = new StructList(2); private int _listenersCachedCount = 0; #endif private bool _isLocked; @@ -102,11 +103,12 @@ namespace DCFApixels.DragonECS } } _mediator.RegisterComponent(entityID, _componentTypeID, _maskBit); - EnableComponent(ref _items[itemIndex]); + ref T result = ref _items[itemIndex]; + EnableComponent(ref result); #if !DISABLE_POOLS_EVENTS _listeners.InvokeOnAddAndGet(entityID, _listenersCachedCount); #endif - return ref _items[itemIndex]; + return ref result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref T Get(int entityID) @@ -284,7 +286,7 @@ namespace DCFApixels.DragonECS public void RemoveListener(IEcsPoolEventListener listener) { if (listener == null) { EcsPoolThrowHelper.ThrowNullListener(); } - if (_listeners.Remove(listener)) + if (_listeners.RemoveWithOrder(listener)) { _listenersCachedCount--; } @@ -343,7 +345,8 @@ namespace DCFApixels.DragonECS public static implicit operator EcsPool(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance>(); } #endregion } - public static class EcsPoolExt + + public static class EcsPoolExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsPool GetPool(this EcsWorld self) where TComponent : struct, IEcsComponent @@ -356,20 +359,44 @@ namespace DCFApixels.DragonECS return self.GetPoolInstanceUnchecked>(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static EcsPool Inc(this EcsAspect.Builder self) where TComponent : struct, IEcsComponent + { + return self.IncludePool>(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static EcsPool Exc(this EcsAspect.Builder self) where TComponent : struct, IEcsComponent + { + return self.ExcludePool>(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static EcsPool Opt(this EcsAspect.Builder self) where TComponent : struct, IEcsComponent + { + return self.OptionalPool>(); + } + + #region Obsolete + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Inc) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsPool Include(this EcsAspect.Builder self) where TComponent : struct, IEcsComponent { return self.IncludePool>(); } + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Exc) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsPool Exclude(this EcsAspect.Builder self) where TComponent : struct, IEcsComponent { return self.ExcludePool>(); } + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Opt) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsPool Optional(this EcsAspect.Builder self) where TComponent : struct, IEcsComponent { return self.OptionalPool>(); } + #endregion } } diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs index 616de39..de4b7c0 100644 --- a/src/Pools/EcsPoolBase.cs +++ b/src/Pools/EcsPoolBase.cs @@ -295,6 +295,34 @@ namespace DCFApixels.DragonECS { for (int i = 0; i < cachedCount; i++) self[i].OnDel(entityID); } + + // + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void InvokeOnAdd(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, int cachedCount) + { + for (int i = 0; i < cachedCount; i++) + { + self[i].OnAdd(entityID); + self[i].OnGet(entityID); + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void InvokeOnGet(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, int cachedCount) + { + for (int i = 0; i < cachedCount; i++) self[i].OnDel(entityID); + } } #endif #endregion diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index 6859e42..5a1118f 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -4,7 +4,8 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Diagnostics; - +using DCFApixels.DragonECS.Internal; +using System.ComponentModel; #if (DEBUG && !DISABLE_DEBUG) using System.Reflection; #endif @@ -41,7 +42,7 @@ namespace DCFApixels.DragonECS private int _count = 0; #if !DISABLE_POOLS_EVENTS - private List _listeners = new List(); + private StructList _listeners = new StructList(2); private int _listenersCachedCount = 0; #endif private bool _isLocked; @@ -274,7 +275,7 @@ namespace DCFApixels.DragonECS public void RemoveListener(IEcsPoolEventListener listener) { if (listener == null) { EcsPoolThrowHelper.ThrowNullListener(); } - if (_listeners.Remove(listener)) + if (_listeners.RemoveWithOrder(listener)) { _listenersCachedCount--; } @@ -294,7 +295,8 @@ namespace DCFApixels.DragonECS public static implicit operator EcsTagPool(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance>(); } #endregion } - public static class EcsTagPoolExt + + public static class EcsTagPoolExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsTagPool GetPool(this EcsWorld self) where TTagComponent : struct, IEcsTagComponent @@ -307,16 +309,39 @@ namespace DCFApixels.DragonECS return self.GetPoolInstanceUnchecked>(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static EcsTagPool Inc(this EcsAspect.Builder self) where TTagComponent : struct, IEcsTagComponent + { + return self.IncludePool>(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static EcsTagPool Exc(this EcsAspect.Builder self) where TTagComponent : struct, IEcsTagComponent + { + return self.ExcludePool>(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static EcsTagPool Opt(this EcsAspect.Builder self) where TTagComponent : struct, IEcsTagComponent + { + return self.OptionalPool>(); + } + + #region Obsolete + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Inc) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsTagPool Include(this EcsAspect.Builder self) where TTagComponent : struct, IEcsTagComponent { return self.IncludePool>(); } + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Exc) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsTagPool Exclude(this EcsAspect.Builder self) where TTagComponent : struct, IEcsTagComponent { return self.ExcludePool>(); } + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Opt) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsTagPool Optional(this EcsAspect.Builder self) where TTagComponent : struct, IEcsTagComponent { @@ -325,31 +350,42 @@ namespace DCFApixels.DragonECS //--------------------------------------------------- + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(GetPool) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsTagPool GetTagPool(this EcsWorld self) where TTagComponent : struct, IEcsTagComponent { return self.GetPoolInstance>(); } + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(GetPoolUnchecked) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsTagPool GetTagPoolUnchecked(this EcsWorld self) where TTagComponent : struct, IEcsTagComponent { return self.GetPoolInstanceUnchecked>(); } + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Inc) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsTagPool IncludeTag(this EcsAspect.Builder self) where TTagComponent : struct, IEcsTagComponent { return self.IncludePool>(); } + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Exc) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsTagPool ExcludeTag(this EcsAspect.Builder self) where TTagComponent : struct, IEcsTagComponent { return self.ExcludePool>(); } + [Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Opt) + "()")] + [EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EcsTagPool OptionalTag(this EcsAspect.Builder self) where TTagComponent : struct, IEcsTagComponent { return self.OptionalPool>(); } + #endregion } }