fixes/optimization

This commit is contained in:
Mikhail 2026-03-17 14:52:19 +08:00
parent f0d9a806ff
commit 37718d354a
5 changed files with 390 additions and 166 deletions

View File

@ -322,7 +322,7 @@ namespace DCFApixels.DragonECS
} }
namespace DCFApixels.DragonECS.Core namespace DCFApixels.DragonECS.Core
{ {
#if ENABLE_IL2CPP #if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices; using Unity.IL2CPP.CompilerServices;
[Il2CppSetOption(Option.NullChecks, false)] [Il2CppSetOption(Option.NullChecks, false)]
@ -385,6 +385,7 @@ namespace DCFApixels.DragonECS.Core
#endregion #endregion
#region Constructors #region Constructors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal EcsUnsafeSpan(short worldID, int* array, int length) internal EcsUnsafeSpan(short worldID, int* array, int length)
{ {
_worldID = worldID; _worldID = worldID;

View File

@ -17,51 +17,53 @@ namespace DCFApixels.DragonECS.Core.Internal
#endif #endif
internal static unsafe class SortHalper internal static unsafe class SortHalper
{ {
internal static StructComparison<T> ToStruct<T>(this Comparison<T> self) #region Span
{ [MethodImpl(MethodImplOptions.AggressiveInlining)]
return new StructComparison<T>(self);
}
internal static StructComparer<T> ToStruct<T>(this Comparer<T> self)
{
return new StructComparer<T>(self);
}
public static void Sort<T>(Span<T> span) public static void Sort<T>(Span<T> span)
{ {
var c = Comparer<T>.Default.ToStruct(); var c = new ComparerWrapper<T>(Comparer<T>.Default);
SortHalper<T, StructComparer<T>>.Sort(span, ref c); SortHalper<T, ComparerWrapper<T>>.Sort(span, ref c);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Sort<T>(Span<T> span, bool _ = false)
where T : IComparable<T>
{
var c = new ComparableWrapper<T>();
SortHalper<T, ComparableWrapper<T>>.Sort(span, ref c);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Sort<T>(Span<T> span, Comparer<T> comparer) public static void Sort<T>(Span<T> span, Comparer<T> comparer)
{ {
var c = comparer.ToStruct(); var c = new ComparerWrapper<T>(comparer);
SortHalper<T, StructComparer<T>>.Sort(span, ref c); SortHalper<T, ComparerWrapper<T>>.Sort(span, ref c);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Sort<T>(Span<T> span, Comparison<T> comparison) public static void Sort<T>(Span<T> span, Comparison<T> comparison)
{ {
var c = comparison.ToStruct(); var c = new ComparisonWrapper<T>(comparison);
SortHalper<T, StructComparison<T>>.Sort(span, ref c); SortHalper<T, ComparisonWrapper<T>>.Sort(span, ref c);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Sort<T, TComparer>(Span<T> span, ref TComparer comparer) public static void Sort<T, TComparer>(Span<T> span, ref TComparer comparer)
where TComparer : struct, IComparer<T> where TComparer : struct, IComparer<T>
{ {
SortHalper<T, TComparer>.Sort(span, ref comparer); SortHalper<T, TComparer>.Sort(span, ref comparer);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Sort<T, TComparer>(Span<T> span, TComparer comparer) public static void Sort<T, TComparer>(Span<T> span, TComparer comparer)
where TComparer : struct, IComparer<T> where TComparer : struct, IComparer<T>
{ {
SortHalper<T, TComparer>.Sort(span, ref comparer); SortHalper<T, TComparer>.Sort(span, ref comparer);
} }
#endregion
#region Utils
// Таблица для De Bruijn-умножения (позиция старшего бита для чисел 0..31) // Таблица для De Bruijn-умножения (позиция старшего бита для чисел 0..31)
private const int Log2DeBruijn32_Length = 32; private const int Log2DeBruijn32_Length = 32;
private static readonly uint* Log2DeBruijn32 = MemoryAllocator.From(new uint[Log2DeBruijn32_Length] private static readonly uint* Log2DeBruijn32 = MemoryAllocator.From(new uint[Log2DeBruijn32_Length]
{ {
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
15, 17, 24, 7, 19, 27, 23, 6, 26, 5,
4, 31
//0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
//8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
}).Ptr; }).Ptr;
/// <summary>32-битный логарифм по основанию 2 (округление вниз). Для value = 0 возвращает 0.</summary> /// <summary>32-битный логарифм по основанию 2 (округление вниз). Для value = 0 возвращает 0.</summary>
@ -98,34 +100,7 @@ namespace DCFApixels.DragonECS.Core.Internal
return 32 + Log2(high); return 32 + Log2(high);
} }
} }
} #endregion
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
internal readonly struct StructComparison<T> : IComparer<T>
{
public readonly Comparison<T> Comparison;
public StructComparison(Comparison<T> comparison)
{
Comparison = comparison;
}
public int Compare(T x, T y)
{
return Comparison(x, y);
}
}
internal readonly struct StructComparer<T> : IComparer<T>
{
public readonly Comparer<T> Comparer;
public StructComparer(Comparer<T> comparer)
{
Comparer = comparer;
}
public int Compare(T x, T y)
{
return Comparer.Compare(x, y);
}
} }
// a > b = return > 0 // a > b = return > 0
// int Compare(T a, T b); // int Compare(T a, T b);
@ -152,13 +127,6 @@ namespace DCFApixels.DragonECS.Core.Internal
IntrospectiveSort(keys, ref comparer); IntrospectiveSort(keys, ref comparer);
} }
public static int BinarySearch(T[] array, int index, int length, T value, ref TComparer comparer) public static int BinarySearch(T[] array, int index, int length, T value, ref TComparer comparer)
{
return InternalBinarySearch(array, index, length, value, ref comparer);
}
#endregion
#region Internal
internal static int InternalBinarySearch(T[] array, int index, int length, T value, ref TComparer comparer)
{ {
Debug.Assert(array != null, "Check the arguments in the caller!"); Debug.Assert(array != null, "Check the arguments in the caller!");
Debug.Assert(index >= 0 && length >= 0 && (array.Length - index >= length), "Check the arguments in the caller!"); Debug.Assert(index >= 0 && length >= 0 && (array.Length - index >= length), "Check the arguments in the caller!");
@ -183,27 +151,9 @@ namespace DCFApixels.DragonECS.Core.Internal
return ~lo; return ~lo;
} }
#endregion
private static void SwapIfGreater(Span<T> keys, ref TComparer comparer, int i, int j) #region Internal
{
Debug.Assert(i != j);
if (comparer.Compare(keys[i], keys[j]) > 0)
{
T key = keys[i];
keys[i] = keys[j];
keys[j] = key;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Swap(Span<T> a, int i, int j)
{
Debug.Assert(i != j);
T t = a[i];
a[i] = a[j];
a[j] = t;
}
internal static void IntrospectiveSort(Span<T> keys, ref TComparer comparer) internal static void IntrospectiveSort(Span<T> keys, ref TComparer comparer)
{ {
//Debug.Assert(comparer != null); //Debug.Assert(comparer != null);
@ -301,8 +251,8 @@ namespace DCFApixels.DragonECS.Core.Internal
private static void HeapSort(Span<T> keys, ref TComparer comparer) private static void HeapSort(Span<T> keys, ref TComparer comparer)
{ {
//Debug.Assert(comparer != null);
Debug.Assert(!keys.IsEmpty); Debug.Assert(!keys.IsEmpty);
//Debug.Assert(comparer != null);
int n = keys.Length; int n = keys.Length;
for (int i = n >> 1; i >= 1; i--) for (int i = n >> 1; i >= 1; i--)
@ -357,5 +307,325 @@ namespace DCFApixels.DragonECS.Core.Internal
} }
} }
#endregion #endregion
#region Swaps
private static void SwapIfGreater(Span<T> keys, ref TComparer comparer, int i, int j)
{
Debug.Assert(i != j);
if (comparer.Compare(keys[i], keys[j]) > 0)
{
T key = keys[i];
keys[i] = keys[j];
keys[j] = key;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Swap(Span<T> a, int i, int j)
{
Debug.Assert(i != j);
T t = a[i];
a[i] = a[j];
a[j] = t;
}
#endregion
} }
#region Wrappers
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
internal readonly struct ComparableWrapper<T> : IComparer<T>
where T : IComparable<T>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Compare(T x, T y) { return x.CompareTo(y); }
}
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
internal readonly struct ComparisonWrapper<T> : IComparer<T>
{
public readonly Comparison<T> Comparison;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ComparisonWrapper(Comparison<T> comparison)
{
Comparison = comparison;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Compare(T x, T y)
{
return Comparison(x, y);
}
}
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
internal readonly struct ComparerWrapper<T> : IComparer<T>
{
public readonly Comparer<T> Comparer;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ComparerWrapper(Comparer<T> comparer)
{
Comparer = comparer;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Compare(T x, T y)
{
return Comparer.Compare(x, y);
}
}
#endregion
} }
//namespace DCFApixels.DragonECS.Core.Internal
//{
// internal interface IStructComparer<T> : IComparer<T>
// {
// // a > b = return > 0
// // int Compare(T a, T b);
// }
//
//#if ENABLE_IL2CPP
// [Il2CppSetOption(Option.NullChecks, false)]
// [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
//#endif
// internal static class ArraySortHalperX<T>
// {
// private const int IntrosortSizeThreshold = 16;
//
// #region IStructComparer
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static void SwapIfGreater<TComparer>(T[] items, ref TComparer comparer, int i, int j) where TComparer : IStructComparer<T>
// {
// if (comparer.Compare(items[i], items[j]) > 0)
// {
// T key = items[i];
// items[i] = items[j];
// items[j] = key;
// }
// }
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static void InsertionSort<TComparer>(T[] items, ref TComparer comparer) where TComparer : IStructComparer<T>
// {
// for (int i = 0; i < items.Length - 1; i++)
// {
// T t = items[i + 1];
//
// int j = i;
// while (j >= 0 && comparer.Compare(t, items[j]) < 0)
// {
// items[j + 1] = items[j];
// j--;
// }
//
// items[j + 1] = t;
// }
// }
//
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static void Sort<TComparer>(T[] items, ref TComparer comparer) where TComparer : IStructComparer<T>
// {
// int length = items.Length;
// if (length == 1)
// {
// return;
// }
//
// if (length <= IntrosortSizeThreshold)
// {
//
// if (length == 2)
// {
// SwapIfGreater(items, ref comparer, 0, 1);
// return;
// }
//
// if (length == 3)
// {
// SwapIfGreater(items, ref comparer, 0, 1);
// SwapIfGreater(items, ref comparer, 0, 2);
// SwapIfGreater(items, ref comparer, 1, 2);
// return;
// }
//
// InsertionSort(items, ref comparer);
// return;
// }
//
// IStructComparer<T> packed = comparer;
// Array.Sort(items, 0, items.Length, packed);
// comparer = (TComparer)packed;
// }
// #endregion
//
// #region Comparison
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static void SwapIfGreater(T[] items, Comparison<T> comparison, int i, int j)
// {
// if (comparison(items[i], items[j]) > 0)
// {
// T key = items[i];
// items[i] = items[j];
// items[j] = key;
// }
// }
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static void InsertionSort(T[] items, int length, Comparison<T> comparison)
// {
// for (int i = 0; i < length - 1; i++)
// {
// T t = items[i + 1];
//
// int j = i;
// while (j >= 0 && comparison(t, items[j]) < 0)
// {
// items[j + 1] = items[j];
// j--;
// }
//
// items[j + 1] = t;
// }
// }
//
//#if ENABLE_IL2CPP
// [Il2CppSetOption(Option.NullChecks, false)]
// [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
//#endif
// private class ComparisonHach : IComparer<T>
// {
// public static readonly ComparisonHach Instance = new ComparisonHach();
// public Comparison<T> comparison;
// private ComparisonHach() { }
// public int Compare(T x, T y) { return comparison(x, y); }
// }
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static void Sort(T[] items, Comparison<T> comparison)
// {
// Sort(items, comparison, items.Length);
// }
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static void Sort(T[] items, Comparison<T> comparison, int length)
// {
// if (length <= IntrosortSizeThreshold)
// {
// if (length == 1)
// {
// return;
// }
// if (length == 2)
// {
// SwapIfGreater(items, comparison, 0, 1);
// return;
// }
// if (length == 3)
// {
// SwapIfGreater(items, comparison, 0, 1);
// SwapIfGreater(items, comparison, 0, 2);
// SwapIfGreater(items, comparison, 1, 2);
// return;
// }
// InsertionSort(items, length, comparison);
// return;
// }
// ComparisonHach.Instance.comparison = comparison;
// Array.Sort(items, 0, length, ComparisonHach.Instance);
// }
// #endregion
// }
//
//#if ENABLE_IL2CPP
// [Il2CppSetOption(Option.NullChecks, false)]
// [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
//#endif
// internal static unsafe class UnsafeArraySortHalperX<T> where T : unmanaged
// {
// private const int IntrosortSizeThreshold = 16;
//
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static void SwapIfGreater<TComparer>(T* items, ref TComparer comparer, int i, int j) where TComparer : IStructComparer<T>
// {
// if (comparer.Compare(items[i], items[j]) > 0)
// {
// T key = items[i];
// items[i] = items[j];
// items[j] = key;
// }
// }
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static void InsertionSort_Unchecked<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IStructComparer<T>
// {
// for (int i = 0; i < length - 1; i++)
// {
// T t = items[i + 1];
//
// int j = i;
// while (j >= 0 && comparer.Compare(t, items[j]) < 0)
// {
// items[j + 1] = items[j];
// j--;
// }
//
// items[j + 1] = t;
// }
// }
// public static void InsertionSort<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IStructComparer<T>
// {
// if (length == 1)
// {
// return;
// }
//
// if (length == 2)
// {
// SwapIfGreater(items, ref comparer, 0, 1);
// return;
// }
//
// if (length == 3)
// {
// SwapIfGreater(items, ref comparer, 0, 1);
// SwapIfGreater(items, ref comparer, 0, 2);
// SwapIfGreater(items, ref comparer, 1, 2);
// return;
// }
//
// InsertionSort_Unchecked(items, length, ref comparer);
// }
// }
//}

View File

@ -53,7 +53,7 @@ namespace DCFApixels.DragonECS
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
private StructList<IEcsPoolEventListener> _listeners = new StructList<IEcsPoolEventListener>(2); private StructList<IEcsPoolEventListener> _listeners = new StructList<IEcsPoolEventListener>(2);
private int _listenersCachedCount = 0; private bool _hasAnyListener = false;
#endif #endif
private bool _isLocked; private bool _isLocked;
@ -155,7 +155,7 @@ namespace DCFApixels.DragonECS
ref T result = ref _items[itemIndex]; ref T result = ref _items[itemIndex];
EcsComponentLifecycle<T>.OnAdd( _isCustomLifecycle, _customLifecycle, ref result, _worldID, entityID); EcsComponentLifecycle<T>.OnAdd( _isCustomLifecycle, _customLifecycle, ref result, _worldID, entityID);
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
_listeners.InvokeOnAddAndGet(entityID, _listenersCachedCount); if (_hasAnyListener) { _listeners.InvokeOnAddAndGet(entityID); }
#endif #endif
return ref result; return ref result;
} }
@ -166,7 +166,7 @@ namespace DCFApixels.DragonECS
if (!Has(entityID)) { EcsPoolThrowHelper.ThrowNotHaveComponent<T>(entityID); } if (!Has(entityID)) { EcsPoolThrowHelper.ThrowNotHaveComponent<T>(entityID); }
#endif #endif
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
_listeners.InvokeOnGet(entityID, _listenersCachedCount); if (_hasAnyListener) { _listeners.InvokeOnGet(entityID); }
#endif #endif
return ref _items[_mapping[entityID]]; return ref _items[_mapping[entityID]];
} }
@ -205,13 +205,13 @@ namespace DCFApixels.DragonECS
} }
} }
_mediator.RegisterComponent(entityID, _componentTypeID, _maskBit); _mediator.RegisterComponent(entityID, _componentTypeID, _maskBit);
EcsComponentLifecycle<T>.OnAdd( _isCustomLifecycle, _customLifecycle, ref _items[itemIndex], _worldID, entityID); EcsComponentLifecycle<T>.OnAdd(_isCustomLifecycle, _customLifecycle, ref _items[itemIndex], _worldID, entityID);
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
_listeners.InvokeOnAdd(entityID, _listenersCachedCount); if (_hasAnyListener) { _listeners.InvokeOnAdd(entityID); }
#endif #endif
} //Add block end } //Add block end
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
_listeners.InvokeOnGet(entityID, _listenersCachedCount); if (_hasAnyListener) { _listeners.InvokeOnGet(entityID); }
#endif #endif
return ref _items[itemIndex]; return ref _items[itemIndex];
} }
@ -241,7 +241,7 @@ namespace DCFApixels.DragonECS
_itemsCount--; _itemsCount--;
_mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit); _mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit);
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
_listeners.InvokeOnDel(entityID, _listenersCachedCount); if (_hasAnyListener) { _listeners.InvokeOnDel(entityID); }
#endif #endif
} }
public void TryDel(int entityID) public void TryDel(int entityID)
@ -287,7 +287,7 @@ namespace DCFApixels.DragonECS
itemIndex = 0; itemIndex = 0;
_mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit); _mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit);
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
_listeners.InvokeOnDel(entityID, _listenersCachedCount); if (_hasAnyListener) { _listeners.InvokeOnDel(entityID); }
#endif #endif
} }
_itemsCount = 0; _itemsCount = 0;
@ -334,14 +334,14 @@ namespace DCFApixels.DragonECS
{ {
if (listener == null) { EcsPoolThrowHelper.ThrowNullListener(); } if (listener == null) { EcsPoolThrowHelper.ThrowNullListener(); }
_listeners.Add(listener); _listeners.Add(listener);
_listenersCachedCount++; _hasAnyListener = _listeners.Count > 0;
} }
public void RemoveListener(IEcsPoolEventListener listener) public void RemoveListener(IEcsPoolEventListener listener)
{ {
if (listener == null) { EcsPoolThrowHelper.ThrowNullListener(); } if (listener == null) { EcsPoolThrowHelper.ThrowNullListener(); }
if (_listeners.RemoveWithOrder(listener)) if (_listeners.RemoveWithOrder(listener))
{ {
_listenersCachedCount--; _hasAnyListener = _listeners.Count > 0;
} }
} }
#endif #endif

View File

@ -296,67 +296,11 @@ namespace DCFApixels.DragonECS
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InvokeOnAdd(this List<IEcsPoolEventListener> self, int entityID) public static void InvokeOnAdd(this List<IEcsPoolEventListener> self, int entityID)
{
self.InvokeOnAdd(entityID, self.Count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InvokeOnAdd(this List<IEcsPoolEventListener> 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<IEcsPoolEventListener> self, int entityID)
{
self.InvokeOnAddAndGet(entityID, self.Count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InvokeOnAddAndGet(this List<IEcsPoolEventListener> 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<IEcsPoolEventListener> self, int entityID)
{
self.InvokeOnGet(entityID, self.Count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InvokeOnGet(this List<IEcsPoolEventListener> 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<IEcsPoolEventListener> self, int entityID)
{
self.InvokeOnDel(entityID, self.Count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InvokeOnDel(this List<IEcsPoolEventListener> self, int entityID, int cachedCount)
{
for (int i = 0; i < cachedCount; i++) { self[i].OnDel(entityID); }
}
//
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InvokeOnAdd(ref this StructList<IEcsPoolEventListener> self, int entityID)
{ {
for (int i = 0; i < self.Count; i++) { self[i].OnAdd(entityID); } for (int i = 0; i < self.Count; i++) { self[i].OnAdd(entityID); }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InvokeOnAdd(ref this StructList<IEcsPoolEventListener> self, int entityID, int cachedCount) public static void InvokeOnAddAndGet(this List<IEcsPoolEventListener> self, int entityID)
{
for (int i = 0; i < cachedCount; i++) { self[i].OnAdd(entityID); }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InvokeOnAddAndGet(ref this StructList<IEcsPoolEventListener> self, int entityID)
{ {
for (int i = 0; i < self.Count; i++) for (int i = 0; i < self.Count; i++)
{ {
@ -365,34 +309,43 @@ namespace DCFApixels.DragonECS
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InvokeOnAddAndGet(ref this StructList<IEcsPoolEventListener> self, int entityID, int cachedCount) public static void InvokeOnGet(this List<IEcsPoolEventListener> self, int entityID)
{ {
for (int i = 0; i < cachedCount; i++) for (int i = 1; i < self.Count; i++) { self[i].OnGet(entityID); }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InvokeOnDel(this List<IEcsPoolEventListener> self, int entityID)
{
for (int i = 0; i < self.Count; i++) { self[i].OnDel(entityID); }
}
//
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InvokeOnAdd(this StructList<IEcsPoolEventListener> self, int entityID)
{
for (int i = 0; i < self.Count; i++) { self[i].OnAdd(entityID); }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InvokeOnAddAndGet(this StructList<IEcsPoolEventListener> self, int entityID)
{
for (int i = 0; i < self.Count; i++)
{ {
self[i].OnAdd(entityID); self[i].OnAdd(entityID);
self[i].OnGet(entityID); self[i].OnGet(entityID);
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InvokeOnGet(ref this StructList<IEcsPoolEventListener> self, int entityID) internal static void InvokeOnGet(this StructList<IEcsPoolEventListener> self, int entityID)
{ {
for (int i = 1; i < self.Count; i++) { self[i].OnGet(entityID); } for (int i = 0; i < self.Count; i++) { self[i].OnGet(entityID); }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InvokeOnGet(ref this StructList<IEcsPoolEventListener> self, int entityID, int cachedCount) internal static void InvokeOnDel(this StructList<IEcsPoolEventListener> self, int entityID)
{
for (int i = 1; i < cachedCount; i++) { self[i].OnGet(entityID); }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InvokeOnDel(ref this StructList<IEcsPoolEventListener> self, int entityID)
{ {
for (int i = 0; i < self.Count; i++) { self[i].OnDel(entityID); } for (int i = 0; i < self.Count; i++) { self[i].OnDel(entityID); }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void InvokeOnDel(ref this StructList<IEcsPoolEventListener> self, int entityID, int cachedCount)
{
for (int i = 0; i < cachedCount; i++) { self[i].OnDel(entityID); }
}
} }
#endif #endif
#endregion #endregion

View File

@ -44,7 +44,7 @@ namespace DCFApixels.DragonECS
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
private StructList<IEcsPoolEventListener> _listeners = new StructList<IEcsPoolEventListener>(2); private StructList<IEcsPoolEventListener> _listeners = new StructList<IEcsPoolEventListener>(2);
private int _listenersCachedCount = 0; private bool _hasAnyListener = false;
#endif #endif
private bool _isLocked; private bool _isLocked;
@ -127,7 +127,7 @@ namespace DCFApixels.DragonECS
_mapping[entityID] = true; _mapping[entityID] = true;
_mediator.RegisterComponent(entityID, _componentTypeID, _maskBit); _mediator.RegisterComponent(entityID, _componentTypeID, _maskBit);
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
_listeners.InvokeOnAdd(entityID, _listenersCachedCount); if (_hasAnyListener) { _listeners.InvokeOnAdd(entityID); }
#endif #endif
} }
public void TryAdd(int entityID) public void TryAdd(int entityID)
@ -155,7 +155,7 @@ namespace DCFApixels.DragonECS
_count--; _count--;
_mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit); _mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit);
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
_listeners.InvokeOnDel(entityID, _listenersCachedCount); if (_hasAnyListener) { _listeners.InvokeOnDel(entityID); }
#endif #endif
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -225,7 +225,7 @@ namespace DCFApixels.DragonECS
_mapping[entityID] = false; _mapping[entityID] = false;
_mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit); _mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit);
#if !DRAGONECS_DISABLE_POOLS_EVENTS #if !DRAGONECS_DISABLE_POOLS_EVENTS
_listeners.InvokeOnDel(entityID, _listenersCachedCount); if (_hasAnyListener) { _listeners.InvokeOnDel(entityID); }
#endif #endif
} }
} }
@ -295,14 +295,14 @@ namespace DCFApixels.DragonECS
{ {
if (listener == null) { EcsPoolThrowHelper.ThrowNullListener(); } if (listener == null) { EcsPoolThrowHelper.ThrowNullListener(); }
_listeners.Add(listener); _listeners.Add(listener);
_listenersCachedCount++; _hasAnyListener = _listeners.Count > 0;
} }
public void RemoveListener(IEcsPoolEventListener listener) public void RemoveListener(IEcsPoolEventListener listener)
{ {
if (listener == null) { EcsPoolThrowHelper.ThrowNullListener(); } if (listener == null) { EcsPoolThrowHelper.ThrowNullListener(); }
if (_listeners.RemoveWithOrder(listener)) if (_listeners.RemoveWithOrder(listener))
{ {
_listenersCachedCount--; _hasAnyListener = _listeners.Count > 0;
} }
} }
#endif #endif