fix IdDispenser

This commit is contained in:
Mikhail 2024-02-14 15:00:07 +08:00
parent 3618e75677
commit 3fed9886fe

View File

@ -10,8 +10,6 @@ namespace DCFApixels.DragonECS.Internal
[DebuggerTypeProxy(typeof(DebuggerProxy))] [DebuggerTypeProxy(typeof(DebuggerProxy))]
public class IdDispenser : IEnumerable<int>, IReadOnlyCollection<int> public class IdDispenser : IEnumerable<int>, IReadOnlyCollection<int>
{ {
private const int FREE_FLAG_BIT = ~INDEX_MASK;
private const int INDEX_MASK = 0x7FFF_FFFF;
private const int MIN_SIZE = 4; private const int MIN_SIZE = 4;
private int[] _dense = Array.Empty<int>(); private int[] _dense = Array.Empty<int>();
@ -59,7 +57,6 @@ namespace DCFApixels.DragonECS.Internal
CheckOrResize(ptr); CheckOrResize(ptr);
int id = _dense[ptr]; int id = _dense[ptr];
Move_FromFree_ToUsed(id); Move_FromFree_ToUsed(id);
SetFlag_Used(id);
return id; return id;
} }
/// <summary>Marks as used a free or reserved id, after this id cannot be retrieved via UseFree.</summary> /// <summary>Marks as used a free or reserved id, after this id cannot be retrieved via UseFree.</summary>
@ -74,7 +71,6 @@ namespace DCFApixels.DragonECS.Internal
} }
#endif #endif
Move_FromFree_ToUsed(id); Move_FromFree_ToUsed(id);
SetFlag_Used(id);
} }
public void Release(int id) //+ public void Release(int id) //+
@ -88,7 +84,6 @@ namespace DCFApixels.DragonECS.Internal
} }
#endif #endif
Move_FromUsed_ToFree(id); Move_FromUsed_ToFree(id);
SetFlag_Free(id);
} }
#endregion #endregion
@ -130,7 +125,7 @@ namespace DCFApixels.DragonECS.Internal
_usedCount = 0; _usedCount = 0;
for (int i = 0; i < _size; i++) for (int i = 0; i < _size; i++)
{ {
_sparse[i] = SetFlag_Free_For(i); _sparse[i] = i;
_dense[i] = i; _dense[i] = i;
} }
SetNullID(_nullID); SetNullID(_nullID);
@ -141,12 +136,12 @@ namespace DCFApixels.DragonECS.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsFree(int id) public bool IsFree(int id)
{ {
return _sparse[id] < 0; return _sparse[id] >= _usedCount;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsUsed(int id) public bool IsUsed(int id)
{ {
return _sparse[id] >= 0; return _sparse[id] < _usedCount;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsNullID(int id) public bool IsNullID(int id)
@ -161,16 +156,16 @@ namespace DCFApixels.DragonECS.Internal
{ {
int usedIndex = 0; int usedIndex = 0;
int freeIndex = _usedCount; int freeIndex = _usedCount;
for (int i = 0; i < _size; i++) for (int i = 1; i < _size; i++)
{ {
if (_sparse[i] > 0) if (_sparse[i] < _usedCount)
{ {
_sparse[i] = usedIndex; _sparse[i] = usedIndex;
_dense[usedIndex++] = i; _dense[usedIndex++] = i;
} }
else else
{ {
_sparse[i] = SetFlag_Free_For(freeIndex); _sparse[i] = freeIndex;
_dense[freeIndex++] = i; _dense[freeIndex++] = i;
} }
} }
@ -189,32 +184,12 @@ namespace DCFApixels.DragonECS.Internal
#endregion #endregion
#region Internal #region Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int SetFlag_Used_For(int value)
{
return value & INDEX_MASK;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int SetFlag_Free_For(int value)
{
return value | FREE_FLAG_BIT;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetFlag_Used(int id)
{
_sparse[id] &= INDEX_MASK;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetFlag_Free(int id)
{
_sparse[id] |= FREE_FLAG_BIT;
}
private void SetNullID(int nullID) private void SetNullID(int nullID)
{ {
_nullID = nullID; _nullID = nullID;
if (nullID >= 0) if (nullID >= 0)
{ {
CheckOrResize(nullID);
Swap(nullID, _usedCount++); Swap(nullID, _usedCount++);
} }
} }
@ -252,7 +227,7 @@ namespace DCFApixels.DragonECS.Internal
private void Swap(int sparseIndex, int denseIndex) private void Swap(int sparseIndex, int denseIndex)
{ {
int _dense_denseIndex_ = _dense[denseIndex]; int _dense_denseIndex_ = _dense[denseIndex];
int _sparse_sparseIndex_ = SetFlag_Used_For(_sparse[sparseIndex]); int _sparse_sparseIndex_ = _sparse[sparseIndex];
_dense[denseIndex] = _dense[_sparse_sparseIndex_]; _dense[denseIndex] = _dense[_sparse_sparseIndex_];
_dense[_sparse_sparseIndex_] = _dense_denseIndex_; _dense[_sparse_sparseIndex_] = _dense_denseIndex_;
_sparse[_dense_denseIndex_] = _sparse_sparseIndex_; _sparse[_dense_denseIndex_] = _sparse_sparseIndex_;
@ -269,7 +244,7 @@ namespace DCFApixels.DragonECS.Internal
Array.Resize(ref _sparse, newSize); Array.Resize(ref _sparse, newSize);
for (int i = _size; i < newSize;) for (int i = _size; i < newSize;)
{ {
_sparse[i] = SetFlag_Free_For(i); _sparse[i] = i;
_dense[i] = i++; _dense[i] = i++;
} }
_size = newSize; _size = newSize;