update queries stash

This commit is contained in:
Mikhail 2024-08-23 22:31:43 +08:00
parent 3a22a914d5
commit 9c033e6330
9 changed files with 426 additions and 328 deletions

View File

@ -242,6 +242,9 @@ namespace DCFApixels.DragonECS
#region Add/Remove
public void AddUnchecked(int entityID)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (Has(entityID)) { Throw.Group_AlreadyContains(entityID); }
#endif
Add_Internal(entityID);
}
public bool Add(int entityID)
@ -254,11 +257,8 @@ namespace DCFApixels.DragonECS
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void Add_Internal(int entityID)
private void Add_Internal(int entityID)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (Has(entityID)) { Throw.Group_AlreadyContains(entityID); }
#endif
if (++_count >= _dense.Length)
{
Array.Resize(ref _dense, _dense.Length << 1);
@ -340,9 +340,9 @@ namespace DCFApixels.DragonECS
{
Clear();
}
foreach (var item in group)
foreach (var entityID in group)
{
Add_Internal(item);
Add_Internal(entityID);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -786,11 +786,11 @@ namespace DCFApixels.DragonECS
public static EcsGroup Inverse(EcsGroup a)
{
EcsGroup result = a._source.GetFreeGroup();
foreach (var item in a._source.Entities)
foreach (var entityID in a._source.Entities)
{
if (a.Has(item) == false)
if (a.Has(entityID) == false)
{
result.Add_Internal(item);
result.Add_Internal(entityID);
}
}
return result;

View File

@ -8,10 +8,7 @@ namespace DCFApixels.DragonECS
{
public abstract class EcsAspect : ITemplateNode
{
internal EcsWorld _source;
internal EcsMask _mask;
private bool _isBuilt = false;
#region Initialization Halpers
[ThreadStatic]
private static Stack<Builder> _constructorBuildersStack = null;
private static Stack<Builder> GetBuildersStack()
@ -70,11 +67,11 @@ namespace DCFApixels.DragonECS
return buildersStack.Peek().Opt;
}
}
#endregion
private UnsafeArray<int> _sortIncBuffer;
private UnsafeArray<int> _sortExcBuffer;
private UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
internal EcsWorld _source;
internal EcsMask _mask;
private bool _isBuilt = false;
#region Properties
public EcsMask Mask
@ -274,219 +271,6 @@ namespace DCFApixels.DragonECS
_span = span;
this.aspect = aspect;
}
#region CopyTo
public void CopyTo(EcsGroup group)
{
group.Clear();
var enumerator = GetEnumerator();
while (enumerator.MoveNext())
{
group.Add_Internal(enumerator.Current);
}
}
public int CopyTo(ref int[] array)
{
int count = 0;
var enumerator = GetEnumerator();
while (enumerator.MoveNext())
{
if (array.Length <= count)
{
Array.Resize(ref array, array.Length << 1);
}
array[count++] = enumerator.Current;
}
return count;
}
public EcsSpan CopyToSpan(ref int[] array)
{
int count = CopyTo(ref array);
return new EcsSpan(worldID, array, count);
}
#endregion
#region Other
public override string ToString()
{
List<int> ints = new List<int>();
foreach (var e in this)
{
ints.Add(e);
}
return CollectionUtility.EntitiesToString(ints, "it");
}
#endregion
#region Enumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() { return new Enumerator(_span, aspect); }
public unsafe ref struct Enumerator
{
#region CountComparers
private readonly struct IncCountComparer : IComparerX<int>
{
public readonly int[] counts;
public IncCountComparer(int[] counts)
{
this.counts = counts;
}
public int Compare(int a, int b)
{
return counts[a] - counts[b];
}
}
private readonly struct ExcCountComparer : IComparerX<int>
{
public readonly int[] counts;
public ExcCountComparer(int[] counts)
{
this.counts = counts;
}
public int Compare(int a, int b)
{
return counts[b] - counts[a];
}
}
#endregion
private ReadOnlySpan<int>.Enumerator _span;
private readonly int[] _entityComponentMasks;
private static EcsMaskChunck* _preSortedIncBuffer;
private static EcsMaskChunck* _preSortedExcBuffer;
private UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
private readonly int _entityComponentMaskLengthBitShift;
public unsafe Enumerator(EcsSpan span, EcsAspect aspect)
{
_entityComponentMasks = aspect.World._entityComponentMasks;
_sortIncChunckBuffer = aspect._sortIncChunckBuffer;
_sortExcChunckBuffer = aspect._sortExcChunckBuffer;
_entityComponentMaskLengthBitShift = aspect.World._entityComponentMaskLengthBitShift;
if (aspect.Mask.IsBroken)
{
_span = span.Slice(0, 0).GetEnumerator();
return;
}
#region Sort
UnsafeArray<int> _sortIncBuffer = aspect._sortIncBuffer;
UnsafeArray<int> _sortExcBuffer = aspect._sortExcBuffer;
int[] counts = aspect.World._poolComponentCounts;
if (_preSortedIncBuffer == null)
{
_preSortedIncBuffer = UnmanagedArrayUtility.New<EcsMaskChunck>(256);
_preSortedExcBuffer = UnmanagedArrayUtility.New<EcsMaskChunck>(256);
}
if (_sortIncChunckBuffer.Length > 1)
{
IncCountComparer incComparer = new IncCountComparer(counts);
UnsafeArraySortHalperX<int>.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref incComparer);
for (int i = 0; i < _sortIncBuffer.Length; i++)
{
_preSortedIncBuffer[i] = EcsMaskChunck.FromID(_sortIncBuffer.ptr[i]);
}
for (int i = 0, ii = 0; ii < _sortIncChunckBuffer.Length; ii++)
{
EcsMaskChunck chunkX = _preSortedIncBuffer[i];
int chankIndexX = chunkX.chankIndex;
int maskX = chunkX.mask;
for (int j = i + 1; j < _sortIncBuffer.Length; j++)
{
if (_preSortedIncBuffer[j].chankIndex == chankIndexX)
{
maskX |= _preSortedIncBuffer[j].mask;
}
}
_sortIncChunckBuffer.ptr[ii] = new EcsMaskChunck(chankIndexX, maskX);
while (++i < _sortIncBuffer.Length && _preSortedIncBuffer[i].chankIndex == chankIndexX)
{
// skip
}
}
}
if (_sortIncChunckBuffer.Length > 0 && counts[_sortIncBuffer.ptr[0]] <= 0)
{
_span = span.Slice(0, 0).GetEnumerator();
return;
}
if (_sortExcChunckBuffer.Length > 1)
{
ExcCountComparer excComparer = new ExcCountComparer(counts);
UnsafeArraySortHalperX<int>.InsertionSort(_sortExcBuffer.ptr, _sortExcBuffer.Length, ref excComparer);
for (int i = 0; i < _sortExcBuffer.Length; i++)
{
_preSortedExcBuffer[i] = EcsMaskChunck.FromID(_sortExcBuffer.ptr[i]);
}
for (int i = 0, ii = 0; ii < _sortExcChunckBuffer.Length; ii++)
{
EcsMaskChunck bas = _preSortedExcBuffer[i];
int chankIndexX = bas.chankIndex;
int maskX = bas.mask;
for (int j = i + 1; j < _sortExcBuffer.Length; j++)
{
if (_preSortedExcBuffer[j].chankIndex == chankIndexX)
{
maskX |= _preSortedExcBuffer[j].mask;
}
}
_sortExcChunckBuffer.ptr[ii] = new EcsMaskChunck(chankIndexX, maskX);
while (++i < _sortExcBuffer.Length && _preSortedExcBuffer[i].chankIndex == chankIndexX)
{
// skip
}
}
}
#endregion
_span = span.GetEnumerator();
}
public int Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _span.Current; }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext()
{
while (_span.MoveNext())
{
int chunck = _span.Current << _entityComponentMaskLengthBitShift;
for (int i = 0; i < _sortIncChunckBuffer.Length; i++)
{
var bit = _sortIncChunckBuffer.ptr[i];
if ((_entityComponentMasks[chunck + bit.chankIndex] & bit.mask) != bit.mask)
{
goto skip;
}
}
for (int i = 0; i < _sortExcChunckBuffer.Length; i++)
{
var bit = _sortExcChunckBuffer.ptr[i];
if ((_entityComponentMasks[chunck + bit.chankIndex] & bit.mask) != 0)
{
goto skip;
}
}
return true;
skip: continue;
}
return false;
}
}
#endregion
}
#endregion
@ -522,6 +306,8 @@ namespace DCFApixels.DragonECS
}
#endregion
}
#region Constraint Markers
public readonly ref struct IncludeMarker
{
private readonly EcsAspect.Builder _builder;
@ -529,8 +315,7 @@ namespace DCFApixels.DragonECS
{
_builder = builder;
}
public T GetInstance<T>()
where T : IEcsPoolImplementation, new()
public T GetInstance<T>() where T : IEcsPoolImplementation, new()
{
return _builder.IncludePool<T>();
}
@ -542,8 +327,7 @@ namespace DCFApixels.DragonECS
{
_builder = builder;
}
public T GetInstance<T>()
where T : IEcsPoolImplementation, new()
public T GetInstance<T>() where T : IEcsPoolImplementation, new()
{
return _builder.ExcludePool<T>();
}
@ -555,10 +339,10 @@ namespace DCFApixels.DragonECS
{
_builder = builder;
}
public T GetInstance<T>()
where T : IEcsPoolImplementation, new()
public T GetInstance<T>() where T : IEcsPoolImplementation, new()
{
return _builder.OptionalPool<T>();
}
}
#endregion
}

View File

@ -22,6 +22,8 @@ namespace DCFApixels.DragonECS
internal readonly int[] _inc; //Sorted
internal readonly int[] _exc; //Sorted
private EcsMaskIterator _iterator;
#region Properties
public int ID
{
@ -217,6 +219,17 @@ namespace DCFApixels.DragonECS
}
#endregion
#region Other
public EcsMaskIterator GetIterator()
{
if(_iterator == null)
{
_iterator = new EcsMaskIterator(EcsWorld.GetWorld(_worldID), this);
}
return _iterator;
}
#endregion
#region Debug utils
#if DEBUG
private static HashSet<int> _dummyHashSet = new HashSet<int>();
@ -381,50 +394,6 @@ namespace DCFApixels.DragonECS
}
return result;
}
//internal EcsMask ExceptMask(EcsMask a, EcsMask b)
//{
// int operation = OpMaskKey.EXCEPT_OP;
// if (_opMasks.TryGetValue(new OpMaskKey(a.id, b.id, operation), out EcsMask result) == false)
// {
// var builder = New(a.World);
// if (a.IsConflictWith(b))
// {
// return a.World.Get<WorldMaskComponent>().BrokenMask;
// }
// ExceptMaskConstraint(builder, a.inc, b.inc, true);
// ExceptMaskConstraint(builder, a.exc, b.exc, false);
// result = builder.Build();
// _opMasks.Add(new OpMaskKey(a.id, b.id, operation), result);
// }
// return result;
//}
//private void ExceptMaskConstraint(Builder b, int[] acnstrs, int[] bcnstrs, bool isInc)
//{
// for (int i = 0, ii = 0; i < acnstrs.Length; i++)
// {
// int acnst = acnstrs[i];
// while (ii < bcnstrs.Length && acnst > bcnstrs[ii])
// {
// ii++;
// }
// if (ii >= bcnstrs.Length)
// {
// break;
// }
// int binc = bcnstrs[ii];
// if (acnst == binc)
// {
// if (isInc)
// {
// b.Include(acnst);
// }
// else
// {
// b.Exclude(acnst);
// }
// }
// }
//}
internal EcsMask GetMask(Key maskKey)
{
if (!_masks.TryGetValue(maskKey, out EcsMask result))
@ -681,4 +650,265 @@ namespace DCFApixels.DragonECS
}
}
#endregion
public class EcsMaskIterator
{
#region CountStructComparers
private readonly struct IncCountComparer : IStructComparer<int>
{
public readonly EcsWorld.PoolSlot[] counts;
public IncCountComparer(EcsWorld.PoolSlot[] counts)
{
this.counts = counts;
}
public int Compare(int a, int b)
{
return counts[a].count - counts[b].count;
}
}
private readonly struct ExcCountComparer : IStructComparer<int>
{
public readonly EcsWorld.PoolSlot[] counts;
public ExcCountComparer(EcsWorld.PoolSlot[] counts)
{
this.counts = counts;
}
public int Compare(int a, int b)
{
return counts[b].count - counts[a].count;
}
}
#endregion
internal EcsWorld _source;
internal EcsMask _mask;
private UnsafeArray<int> _sortIncBuffer;
private UnsafeArray<int> _sortExcBuffer;
private UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
#region Constructors
public EcsMaskIterator(EcsWorld source, EcsMask mask)
{
_source = source;
_mask = mask;
}
#endregion
#region Properties
public EcsWorld World
{
get { return _source; }
}
public EcsMask Mask
{
get { return _mask; }
}
#endregion
#region Enumerable
public Enumerable Iterate(EcsSpan span)
{
return new Enumerable();
}
public readonly ref struct Enumerable
{
private readonly EcsMaskIterator _iterator;
private readonly EcsSpan _span;
public Enumerable(EcsMaskIterator iterator, EcsSpan span)
{
_iterator = iterator;
_span = span;
}
#region CopyTo
public void CopyTo(EcsGroup group)
{
group.Clear();
var enumerator = GetEnumerator();
while (enumerator.MoveNext())
{
group.AddUnchecked(enumerator.Current);
}
}
public int CopyTo(ref int[] array)
{
int count = 0;
var enumerator = GetEnumerator();
while (enumerator.MoveNext())
{
if (array.Length <= count)
{
Array.Resize(ref array, array.Length << 1);
}
array[count++] = enumerator.Current;
}
return count;
}
public EcsSpan CopyToSpan(ref int[] array)
{
int count = CopyTo(ref array);
return new EcsSpan(_iterator.World.id, array, count);
}
#endregion
#region Other
public override string ToString()
{
List<int> ints = new List<int>();
foreach (var e in this)
{
ints.Add(e);
}
return CollectionUtility.EntitiesToString(ints, "it");
}
#endregion
#region Enumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() { return new Enumerator(_span, _iterator); }
public unsafe ref struct Enumerator
{
private ReadOnlySpan<int>.Enumerator _span;
private readonly int[] _entityComponentMasks;
private static EcsMaskChunck* _preSortedIncBuffer;
private static EcsMaskChunck* _preSortedExcBuffer;
private UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
private readonly int _entityComponentMaskLengthBitShift;
public unsafe Enumerator(EcsSpan span, EcsMaskIterator iterator)
{
_entityComponentMasks = iterator.World._entityComponentMasks;
_sortIncChunckBuffer = iterator._sortIncChunckBuffer;
_sortExcChunckBuffer = iterator._sortExcChunckBuffer;
_entityComponentMaskLengthBitShift = iterator.World._entityComponentMaskLengthBitShift;
if (iterator.Mask.IsBroken)
{
_span = span.Slice(0, 0).GetEnumerator();
return;
}
#region Sort
UnsafeArray<int> _sortIncBuffer = iterator._sortIncBuffer;
UnsafeArray<int> _sortExcBuffer = iterator._sortExcBuffer;
EcsWorld.PoolSlot[] counts = iterator.World._poolSlots;
if (_preSortedIncBuffer == null)
{
_preSortedIncBuffer = UnmanagedArrayUtility.New<EcsMaskChunck>(256);
_preSortedExcBuffer = UnmanagedArrayUtility.New<EcsMaskChunck>(256);
}
if (_sortIncChunckBuffer.Length > 1)
{
IncCountComparer incComparer = new IncCountComparer(counts);
UnsafeArraySortHalperX<int>.InsertionSort(_sortIncBuffer.ptr, _sortIncBuffer.Length, ref incComparer);
for (int i = 0; i < _sortIncBuffer.Length; i++)
{
_preSortedIncBuffer[i] = EcsMaskChunck.FromID(_sortIncBuffer.ptr[i]);
}
for (int i = 0, ii = 0; ii < _sortIncChunckBuffer.Length; ii++)
{
EcsMaskChunck chunkX = _preSortedIncBuffer[i];
int chankIndexX = chunkX.chankIndex;
int maskX = chunkX.mask;
for (int j = i + 1; j < _sortIncBuffer.Length; j++)
{
if (_preSortedIncBuffer[j].chankIndex == chankIndexX)
{
maskX |= _preSortedIncBuffer[j].mask;
}
}
_sortIncChunckBuffer.ptr[ii] = new EcsMaskChunck(chankIndexX, maskX);
while (++i < _sortIncBuffer.Length && _preSortedIncBuffer[i].chankIndex == chankIndexX)
{
// skip
}
}
}
if (_sortIncChunckBuffer.Length > 0 && counts[_sortIncBuffer.ptr[0]].count <= 0)
{
_span = span.Slice(0, 0).GetEnumerator();
return;
}
if (_sortExcChunckBuffer.Length > 1)
{
ExcCountComparer excComparer = new ExcCountComparer(counts);
UnsafeArraySortHalperX<int>.InsertionSort(_sortExcBuffer.ptr, _sortExcBuffer.Length, ref excComparer);
for (int i = 0; i < _sortExcBuffer.Length; i++)
{
_preSortedExcBuffer[i] = EcsMaskChunck.FromID(_sortExcBuffer.ptr[i]);
}
for (int i = 0, ii = 0; ii < _sortExcChunckBuffer.Length; ii++)
{
EcsMaskChunck bas = _preSortedExcBuffer[i];
int chankIndexX = bas.chankIndex;
int maskX = bas.mask;
for (int j = i + 1; j < _sortExcBuffer.Length; j++)
{
if (_preSortedExcBuffer[j].chankIndex == chankIndexX)
{
maskX |= _preSortedExcBuffer[j].mask;
}
}
_sortExcChunckBuffer.ptr[ii] = new EcsMaskChunck(chankIndexX, maskX);
while (++i < _sortExcBuffer.Length && _preSortedExcBuffer[i].chankIndex == chankIndexX)
{
// skip
}
}
}
#endregion
_span = span.GetEnumerator();
}
public int Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _span.Current; }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext()
{
while (_span.MoveNext())
{
int chunck = _span.Current << _entityComponentMaskLengthBitShift;
for (int i = 0; i < _sortIncChunckBuffer.Length; i++)
{
var bit = _sortIncChunckBuffer.ptr[i];
if ((_entityComponentMasks[chunck + bit.chankIndex] & bit.mask) != bit.mask)
{
goto skip;
}
}
for (int i = 0; i < _sortExcChunckBuffer.Length; i++)
{
var bit = _sortExcChunckBuffer.ptr[i];
if ((_entityComponentMasks[chunck + bit.chankIndex] & bit.mask) != 0)
{
goto skip;
}
}
return true;
skip: continue;
}
return false;
}
}
#endregion
}
#endregion
}
}

View File

@ -169,7 +169,7 @@ namespace DCFApixels.DragonECS
int poolsCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.PoolsCapacity);
_pools = new IEcsPoolImplementation[poolsCapacity];
_poolComponentCounts = new int[poolsCapacity];
_poolSlots = new int[poolsCapacity];
ArrayUtility.Fill(_pools, _nullPool);
int entitiesCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.EntitiesCapacity);
@ -816,10 +816,19 @@ namespace DCFApixels.DragonECS
public static class EcsWorldExtenssions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsNullOrDetroyed(this EcsWorld self)
{
return self == null || self.IsDestroyed;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ReleaseDelEntityBufferAllAuto(this EcsWorld self)
{
if (self.IsEnableReleaseDelEntBuffer)
{
self.ReleaseDelEntityBufferAll();
}
}
}
#region Callbacks Interface

View File

@ -12,11 +12,11 @@ namespace DCFApixels.DragonECS
private SparseArray<int> _cmpTypeCode_2_CmpTypeIDs = new SparseArray<int>();
private int _poolsCount;
internal IEcsPoolImplementation[] _pools;
internal int[] _poolComponentCounts;
internal PoolSlot[] _poolSlots;
private readonly PoolsMediator _poolsMediator;
private readonly EcsNullPool _nullPool = EcsNullPool.instance;
private EcsNullPool _nullPool = EcsNullPool.instance;
#region FindPoolInstance
[Obsolete("The GetPoolInstance(int componentTypeID) method will be removed in future updates, use FindPoolInstance(Type componentType)")]
@ -146,7 +146,7 @@ namespace DCFApixels.DragonECS
}
#endregion
#region Create
#region CreatePool
private TPool CreatePool<TPool>() where TPool : IEcsPoolImplementation, new()
{
int poolTypeCode = EcsTypeCode.Get<TPool>();
@ -184,7 +184,7 @@ namespace DCFApixels.DragonECS
{
int oldCapacity = _pools.Length;
Array.Resize(ref _pools, _pools.Length << 1);
Array.Resize(ref _poolComponentCounts, _pools.Length);
Array.Resize(ref _poolSlots, _pools.Length);
ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
int newEntityComponentMaskLength = CalcEntityComponentMaskLength(); //_pools.Length / COMPONENT_MASK_CHUNK_SIZE + 1;
@ -231,7 +231,9 @@ namespace DCFApixels.DragonECS
private void RegisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
{
UpVersion();
_poolComponentCounts[componentTypeID]++;
ref PoolSlot slot = ref _poolSlots[componentTypeID];
slot.count++;
slot.version++;
_entities[entityID].componentsCount++;
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex] |= maskBit.mask;
}
@ -239,7 +241,9 @@ namespace DCFApixels.DragonECS
private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
{
UpVersion();
_poolComponentCounts[componentTypeID]--;
ref PoolSlot slot = ref _poolSlots[componentTypeID];
slot.count--;
slot.version++;
var count = --_entities[entityID].componentsCount;
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex] &= ~maskBit.mask;
@ -262,7 +266,9 @@ namespace DCFApixels.DragonECS
{
UpVersion();
chunk = newChunk;
_poolComponentCounts[componentTypeID]++;
ref PoolSlot slot = ref _poolSlots[componentTypeID];
slot.count++;
slot.version++;
_entities[entityID].componentsCount++;
return true;
}
@ -276,7 +282,9 @@ namespace DCFApixels.DragonECS
if (chunk != newChunk)
{
UpVersion();
_poolComponentCounts[componentTypeID]--;
ref PoolSlot slot = ref _poolSlots[componentTypeID];
slot.count--;
slot.version++;
var count = --_entities[entityID].componentsCount;
chunk = newChunk;
@ -295,7 +303,12 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPoolComponentCount(int componentTypeID)
{
return _poolComponentCounts[componentTypeID];
return _poolSlots[componentTypeID].count;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private long GetPoolVersion(int componentTypeID)
{
return _poolSlots[componentTypeID].version;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool HasEntityComponent(int entityID, EcsMaskChunck maskBit)
@ -343,11 +356,24 @@ namespace DCFApixels.DragonECS
return World.GetPoolComponentCount(componentTypeID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public long GetVersion(int componentTypeID)
{
return World.GetPoolVersion(componentTypeID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool HasComponent(int entityID, EcsMaskChunck maskBit)
{
return World.HasEntityComponent(entityID, maskBit);
}
}
#endregion
#region PoolSlot
internal struct PoolSlot
{
public int count;
public long version;
}
#endregion
}
}

View File

@ -29,4 +29,38 @@ namespace DCFApixels.DragonECS
protected abstract void OnInitialize();
protected abstract void OnDestroy();
}
public readonly struct PoolVersionsChecker
{
private readonly EcsMask _mask;
private readonly long[] _versions;
public PoolVersionsChecker(EcsMask mask) : this()
{
_mask = mask;
_versions = new long[mask._inc.Length + mask._exc.Length];
}
public bool NextEquals()
{
var slots = _mask.World._poolSlots;
bool result = true;
int index = 0;
foreach (var i in _mask._inc)
{
if (slots[i].version != _versions[index++])
{
result = false;
}
}
foreach (var i in _mask._exc)
{
if (slots[i].version != _versions[index++])
{
result = false;
}
}
return result;
}
}
}

View File

@ -15,10 +15,7 @@ namespace DCFApixels.DragonECS
private int _filteredEntitiesCount;
private long _lastWorldVersion;
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
//private readonly EcsProfilerMarker _executeMarker = new EcsProfilerMarker("Where");
#endif
private PoolVersionsChecker _versionsChecker;
#region Properties
public TAspect Aspect
@ -38,11 +35,39 @@ namespace DCFApixels.DragonECS
{
_aspect = World.GetAspect<TAspect>();
_filteredEntities = new int[32];
_versionsChecker = new PoolVersionsChecker(_aspect._mask);
}
protected sealed override void OnDestroy() { }
#endregion
#region Methods
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Filter(EcsSpan span)
{
_filteredEntitiesCount = _aspect.GetIteratorFor(span).CopyTo(ref _filteredEntities);
_lastWorldVersion = World.Version;
}
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public EcsSpan Execute(Comparison<int> comparison)
// {
// return ExecuteFor(_aspect.World.Entities, comparison);
// }
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public EcsSpan ExecuteFor(EcsSpan span, Comparison<int> comparison)
// {
//#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
// if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
// if (span.WorldID != WorldID) { Throw.Quiery_ArgumentDifferentWorldsException(); }
//#endif
// World.ReleaseDelEntityBufferAllAuto();
// if (_lastWorldVersion != World.Version)
// {
// Filter(span);
// }
// Array.Sort<int>(_filteredEntities, 0, _filteredEntitiesCount, comparison);
// }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Execute()
{
@ -52,29 +77,15 @@ namespace DCFApixels.DragonECS
public EcsSpan ExecuteFor(EcsSpan span)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
//_executeMarker.Begin();
if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
if (span.WorldID != WorldID) { Throw.Quiery_ArgumentDifferentWorldsException(); }
#endif
if (World.IsEnableReleaseDelEntBuffer)
World.ReleaseDelEntityBufferAllAuto();
if (_lastWorldVersion != World.Version || _versionsChecker.NextEquals() == false)
{
World.ReleaseDelEntityBufferAll();
Filter(span);
}
EcsSpan result;
if (_lastWorldVersion != World.Version)
{
result = _aspect.GetIteratorFor(span).CopyToSpan(ref _filteredEntities);
_filteredEntitiesCount = result.Count;
_lastWorldVersion = World.Version;
}
else
{
result = new EcsSpan(WorldID, _filteredEntities, _filteredEntitiesCount);
}
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
//_executeMarker.End();
#endif
return result;
return new EcsSpan(WorldID, _filteredEntities, _filteredEntitiesCount);
}
#endregion
}

View File

@ -14,6 +14,7 @@ namespace DCFApixels.DragonECS
private EcsGroup _filteredGroup;
private long _lastWorldVersion;
private PoolVersionsChecker _versionsChecker;
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
private readonly EcsProfilerMarker _executeMarker = new EcsProfilerMarker("Where");
@ -37,6 +38,7 @@ namespace DCFApixels.DragonECS
{
_aspect = World.GetAspect<TAspect>();
_filteredGroup = EcsGroup.New(World);
_versionsChecker = new PoolVersionsChecker(_aspect._mask);
}
protected sealed override void OnDestroy()
{
@ -46,6 +48,12 @@ namespace DCFApixels.DragonECS
#region Methods
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Filter(EcsSpan span)
{
_aspect.GetIteratorFor(span).CopyTo(_filteredGroup);
_lastWorldVersion = World.Version;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup Execute()
{
return ExecuteFor(_aspect.World.Entities);
@ -58,14 +66,10 @@ namespace DCFApixels.DragonECS
if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
if (span.WorldID != WorldID) { Throw.Quiery_ArgumentDifferentWorldsException(); }
#endif
if (World.IsEnableReleaseDelEntBuffer)
World.ReleaseDelEntityBufferAllAuto();
if (_lastWorldVersion != World.Version || _versionsChecker.NextEquals() == false)
{
World.ReleaseDelEntityBufferAll();
}
if (_lastWorldVersion != World.Version)
{
_aspect.GetIteratorFor(span).CopyTo(_filteredGroup);
_lastWorldVersion = World.Version;
Filter(span);
}
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
_executeMarker.End();

View File

@ -4,7 +4,7 @@ using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS.Internal
{
internal interface IComparerX<T>
internal interface IStructComparer<T>
{
// a > b = return > 0
int Compare(T a, T b);
@ -14,7 +14,7 @@ namespace DCFApixels.DragonECS.Internal
private const int IntrosortSizeThreshold = 16;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SwapIfGreater<TComparer>(T[] items, ref TComparer comparer, int i, int j) where TComparer : IComparerX<T>
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)
{
@ -24,7 +24,7 @@ namespace DCFApixels.DragonECS.Internal
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InsertionSort<TComparer>(T[] items, ref TComparer comparer) where TComparer : IComparerX<T>
public static void InsertionSort<TComparer>(T[] items, ref TComparer comparer) where TComparer : IStructComparer<T>
{
for (int i = 0; i < items.Length - 1; i++)
{
@ -41,7 +41,7 @@ namespace DCFApixels.DragonECS.Internal
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Sort<TComparer>(T[] items, ref TComparer comparer) where TComparer : IComparerX<T>
public static void Sort<TComparer>(T[] items, ref TComparer comparer) where TComparer : IStructComparer<T>
{
int length = items.Length;
if (length == 1)
@ -69,7 +69,7 @@ namespace DCFApixels.DragonECS.Internal
InsertionSort(items, ref comparer);
return;
}
IComparerX<T> packed = comparer;
IStructComparer<T> packed = comparer;
Array.Sort(items, comparer.Compare);
comparer = (TComparer)packed;
}
@ -80,7 +80,7 @@ namespace DCFApixels.DragonECS.Internal
private const int IntrosortSizeThreshold = 16;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SwapIfGreater<TComparer>(T* items, ref TComparer comparer, int i, int j) where TComparer : IComparerX<T>
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)
{
@ -90,7 +90,7 @@ namespace DCFApixels.DragonECS.Internal
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InsertionSort_Unchecked<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IComparerX<T>
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++)
{
@ -127,7 +127,7 @@ namespace DCFApixels.DragonECS.Internal
// break;
// }
//}
public static void InsertionSort<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IComparerX<T>
public static void InsertionSort<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IStructComparer<T>
{
if (length == 1)
{