mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
update queries stash
This commit is contained in:
parent
3a22a914d5
commit
9c033e6330
@ -242,6 +242,9 @@ namespace DCFApixels.DragonECS
|
|||||||
#region Add/Remove
|
#region Add/Remove
|
||||||
public void AddUnchecked(int entityID)
|
public void AddUnchecked(int entityID)
|
||||||
{
|
{
|
||||||
|
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||||
|
if (Has(entityID)) { Throw.Group_AlreadyContains(entityID); }
|
||||||
|
#endif
|
||||||
Add_Internal(entityID);
|
Add_Internal(entityID);
|
||||||
}
|
}
|
||||||
public bool Add(int entityID)
|
public bool Add(int entityID)
|
||||||
@ -254,11 +257,8 @@ namespace DCFApixels.DragonECS
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[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)
|
if (++_count >= _dense.Length)
|
||||||
{
|
{
|
||||||
Array.Resize(ref _dense, _dense.Length << 1);
|
Array.Resize(ref _dense, _dense.Length << 1);
|
||||||
@ -340,9 +340,9 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
foreach (var item in group)
|
foreach (var entityID in group)
|
||||||
{
|
{
|
||||||
Add_Internal(item);
|
Add_Internal(entityID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -786,11 +786,11 @@ namespace DCFApixels.DragonECS
|
|||||||
public static EcsGroup Inverse(EcsGroup a)
|
public static EcsGroup Inverse(EcsGroup a)
|
||||||
{
|
{
|
||||||
EcsGroup result = a._source.GetFreeGroup();
|
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;
|
return result;
|
||||||
|
240
src/EcsAspect.cs
240
src/EcsAspect.cs
@ -8,10 +8,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
public abstract class EcsAspect : ITemplateNode
|
public abstract class EcsAspect : ITemplateNode
|
||||||
{
|
{
|
||||||
internal EcsWorld _source;
|
#region Initialization Halpers
|
||||||
internal EcsMask _mask;
|
|
||||||
private bool _isBuilt = false;
|
|
||||||
|
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static Stack<Builder> _constructorBuildersStack = null;
|
private static Stack<Builder> _constructorBuildersStack = null;
|
||||||
private static Stack<Builder> GetBuildersStack()
|
private static Stack<Builder> GetBuildersStack()
|
||||||
@ -70,11 +67,11 @@ namespace DCFApixels.DragonECS
|
|||||||
return buildersStack.Peek().Opt;
|
return buildersStack.Peek().Opt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
private UnsafeArray<int> _sortIncBuffer;
|
internal EcsWorld _source;
|
||||||
private UnsafeArray<int> _sortExcBuffer;
|
internal EcsMask _mask;
|
||||||
private UnsafeArray<EcsMaskChunck> _sortIncChunckBuffer;
|
private bool _isBuilt = false;
|
||||||
private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
|
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public EcsMask Mask
|
public EcsMask Mask
|
||||||
@ -274,219 +271,6 @@ namespace DCFApixels.DragonECS
|
|||||||
_span = span;
|
_span = span;
|
||||||
this.aspect = aspect;
|
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
|
#endregion
|
||||||
|
|
||||||
@ -522,6 +306,8 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Constraint Markers
|
||||||
public readonly ref struct IncludeMarker
|
public readonly ref struct IncludeMarker
|
||||||
{
|
{
|
||||||
private readonly EcsAspect.Builder _builder;
|
private readonly EcsAspect.Builder _builder;
|
||||||
@ -529,8 +315,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
_builder = builder;
|
_builder = builder;
|
||||||
}
|
}
|
||||||
public T GetInstance<T>()
|
public T GetInstance<T>() where T : IEcsPoolImplementation, new()
|
||||||
where T : IEcsPoolImplementation, new()
|
|
||||||
{
|
{
|
||||||
return _builder.IncludePool<T>();
|
return _builder.IncludePool<T>();
|
||||||
}
|
}
|
||||||
@ -542,8 +327,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
_builder = builder;
|
_builder = builder;
|
||||||
}
|
}
|
||||||
public T GetInstance<T>()
|
public T GetInstance<T>() where T : IEcsPoolImplementation, new()
|
||||||
where T : IEcsPoolImplementation, new()
|
|
||||||
{
|
{
|
||||||
return _builder.ExcludePool<T>();
|
return _builder.ExcludePool<T>();
|
||||||
}
|
}
|
||||||
@ -555,10 +339,10 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
_builder = builder;
|
_builder = builder;
|
||||||
}
|
}
|
||||||
public T GetInstance<T>()
|
public T GetInstance<T>() where T : IEcsPoolImplementation, new()
|
||||||
where T : IEcsPoolImplementation, new()
|
|
||||||
{
|
{
|
||||||
return _builder.OptionalPool<T>();
|
return _builder.OptionalPool<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
#endregion
|
||||||
|
}
|
318
src/EcsMask.cs
318
src/EcsMask.cs
@ -22,6 +22,8 @@ namespace DCFApixels.DragonECS
|
|||||||
internal readonly int[] _inc; //Sorted
|
internal readonly int[] _inc; //Sorted
|
||||||
internal readonly int[] _exc; //Sorted
|
internal readonly int[] _exc; //Sorted
|
||||||
|
|
||||||
|
private EcsMaskIterator _iterator;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public int ID
|
public int ID
|
||||||
{
|
{
|
||||||
@ -217,6 +219,17 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Other
|
||||||
|
public EcsMaskIterator GetIterator()
|
||||||
|
{
|
||||||
|
if(_iterator == null)
|
||||||
|
{
|
||||||
|
_iterator = new EcsMaskIterator(EcsWorld.GetWorld(_worldID), this);
|
||||||
|
}
|
||||||
|
return _iterator;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Debug utils
|
#region Debug utils
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
private static HashSet<int> _dummyHashSet = new HashSet<int>();
|
private static HashSet<int> _dummyHashSet = new HashSet<int>();
|
||||||
@ -381,50 +394,6 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
return result;
|
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)
|
internal EcsMask GetMask(Key maskKey)
|
||||||
{
|
{
|
||||||
if (!_masks.TryGetValue(maskKey, out EcsMask result))
|
if (!_masks.TryGetValue(maskKey, out EcsMask result))
|
||||||
@ -681,4 +650,265 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
int poolsCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.PoolsCapacity);
|
int poolsCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.PoolsCapacity);
|
||||||
_pools = new IEcsPoolImplementation[poolsCapacity];
|
_pools = new IEcsPoolImplementation[poolsCapacity];
|
||||||
_poolComponentCounts = new int[poolsCapacity];
|
_poolSlots = new int[poolsCapacity];
|
||||||
ArrayUtility.Fill(_pools, _nullPool);
|
ArrayUtility.Fill(_pools, _nullPool);
|
||||||
|
|
||||||
int entitiesCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.EntitiesCapacity);
|
int entitiesCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.EntitiesCapacity);
|
||||||
@ -816,10 +816,19 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public static class EcsWorldExtenssions
|
public static class EcsWorldExtenssions
|
||||||
{
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool IsNullOrDetroyed(this EcsWorld self)
|
public static bool IsNullOrDetroyed(this EcsWorld self)
|
||||||
{
|
{
|
||||||
return self == null || self.IsDestroyed;
|
return self == null || self.IsDestroyed;
|
||||||
}
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void ReleaseDelEntityBufferAllAuto(this EcsWorld self)
|
||||||
|
{
|
||||||
|
if (self.IsEnableReleaseDelEntBuffer)
|
||||||
|
{
|
||||||
|
self.ReleaseDelEntityBufferAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Callbacks Interface
|
#region Callbacks Interface
|
||||||
|
@ -12,11 +12,11 @@ namespace DCFApixels.DragonECS
|
|||||||
private SparseArray<int> _cmpTypeCode_2_CmpTypeIDs = new SparseArray<int>();
|
private SparseArray<int> _cmpTypeCode_2_CmpTypeIDs = new SparseArray<int>();
|
||||||
private int _poolsCount;
|
private int _poolsCount;
|
||||||
internal IEcsPoolImplementation[] _pools;
|
internal IEcsPoolImplementation[] _pools;
|
||||||
internal int[] _poolComponentCounts;
|
internal PoolSlot[] _poolSlots;
|
||||||
|
|
||||||
private readonly PoolsMediator _poolsMediator;
|
private readonly PoolsMediator _poolsMediator;
|
||||||
|
|
||||||
private readonly EcsNullPool _nullPool = EcsNullPool.instance;
|
private EcsNullPool _nullPool = EcsNullPool.instance;
|
||||||
|
|
||||||
#region FindPoolInstance
|
#region FindPoolInstance
|
||||||
[Obsolete("The GetPoolInstance(int componentTypeID) method will be removed in future updates, use FindPoolInstance(Type componentType)")]
|
[Obsolete("The GetPoolInstance(int componentTypeID) method will be removed in future updates, use FindPoolInstance(Type componentType)")]
|
||||||
@ -146,7 +146,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Create
|
#region CreatePool
|
||||||
private TPool CreatePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
private TPool CreatePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
||||||
{
|
{
|
||||||
int poolTypeCode = EcsTypeCode.Get<TPool>();
|
int poolTypeCode = EcsTypeCode.Get<TPool>();
|
||||||
@ -184,7 +184,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
int oldCapacity = _pools.Length;
|
int oldCapacity = _pools.Length;
|
||||||
Array.Resize(ref _pools, _pools.Length << 1);
|
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);
|
ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
|
||||||
|
|
||||||
int newEntityComponentMaskLength = CalcEntityComponentMaskLength(); //_pools.Length / COMPONENT_MASK_CHUNK_SIZE + 1;
|
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)
|
private void RegisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
||||||
{
|
{
|
||||||
UpVersion();
|
UpVersion();
|
||||||
_poolComponentCounts[componentTypeID]++;
|
ref PoolSlot slot = ref _poolSlots[componentTypeID];
|
||||||
|
slot.count++;
|
||||||
|
slot.version++;
|
||||||
_entities[entityID].componentsCount++;
|
_entities[entityID].componentsCount++;
|
||||||
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex] |= maskBit.mask;
|
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex] |= maskBit.mask;
|
||||||
}
|
}
|
||||||
@ -239,7 +241,9 @@ namespace DCFApixels.DragonECS
|
|||||||
private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
private void UnregisterEntityComponent(int entityID, int componentTypeID, EcsMaskChunck maskBit)
|
||||||
{
|
{
|
||||||
UpVersion();
|
UpVersion();
|
||||||
_poolComponentCounts[componentTypeID]--;
|
ref PoolSlot slot = ref _poolSlots[componentTypeID];
|
||||||
|
slot.count--;
|
||||||
|
slot.version++;
|
||||||
var count = --_entities[entityID].componentsCount;
|
var count = --_entities[entityID].componentsCount;
|
||||||
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex] &= ~maskBit.mask;
|
_entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chankIndex] &= ~maskBit.mask;
|
||||||
|
|
||||||
@ -262,7 +266,9 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
UpVersion();
|
UpVersion();
|
||||||
chunk = newChunk;
|
chunk = newChunk;
|
||||||
_poolComponentCounts[componentTypeID]++;
|
ref PoolSlot slot = ref _poolSlots[componentTypeID];
|
||||||
|
slot.count++;
|
||||||
|
slot.version++;
|
||||||
_entities[entityID].componentsCount++;
|
_entities[entityID].componentsCount++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -276,7 +282,9 @@ namespace DCFApixels.DragonECS
|
|||||||
if (chunk != newChunk)
|
if (chunk != newChunk)
|
||||||
{
|
{
|
||||||
UpVersion();
|
UpVersion();
|
||||||
_poolComponentCounts[componentTypeID]--;
|
ref PoolSlot slot = ref _poolSlots[componentTypeID];
|
||||||
|
slot.count--;
|
||||||
|
slot.version++;
|
||||||
var count = --_entities[entityID].componentsCount;
|
var count = --_entities[entityID].componentsCount;
|
||||||
chunk = newChunk;
|
chunk = newChunk;
|
||||||
|
|
||||||
@ -295,7 +303,12 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private int GetPoolComponentCount(int componentTypeID)
|
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)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private bool HasEntityComponent(int entityID, EcsMaskChunck maskBit)
|
private bool HasEntityComponent(int entityID, EcsMaskChunck maskBit)
|
||||||
@ -343,11 +356,24 @@ namespace DCFApixels.DragonECS
|
|||||||
return World.GetPoolComponentCount(componentTypeID);
|
return World.GetPoolComponentCount(componentTypeID);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public long GetVersion(int componentTypeID)
|
||||||
|
{
|
||||||
|
return World.GetPoolVersion(componentTypeID);
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool HasComponent(int entityID, EcsMaskChunck maskBit)
|
public bool HasComponent(int entityID, EcsMaskChunck maskBit)
|
||||||
{
|
{
|
||||||
return World.HasEntityComponent(entityID, maskBit);
|
return World.HasEntityComponent(entityID, maskBit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region PoolSlot
|
||||||
|
internal struct PoolSlot
|
||||||
|
{
|
||||||
|
public int count;
|
||||||
|
public long version;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,4 +29,38 @@ namespace DCFApixels.DragonECS
|
|||||||
protected abstract void OnInitialize();
|
protected abstract void OnInitialize();
|
||||||
protected abstract void OnDestroy();
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -15,10 +15,7 @@ namespace DCFApixels.DragonECS
|
|||||||
private int _filteredEntitiesCount;
|
private int _filteredEntitiesCount;
|
||||||
|
|
||||||
private long _lastWorldVersion;
|
private long _lastWorldVersion;
|
||||||
|
private PoolVersionsChecker _versionsChecker;
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
|
||||||
//private readonly EcsProfilerMarker _executeMarker = new EcsProfilerMarker("Where");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public TAspect Aspect
|
public TAspect Aspect
|
||||||
@ -38,11 +35,39 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
_aspect = World.GetAspect<TAspect>();
|
_aspect = World.GetAspect<TAspect>();
|
||||||
_filteredEntities = new int[32];
|
_filteredEntities = new int[32];
|
||||||
|
_versionsChecker = new PoolVersionsChecker(_aspect._mask);
|
||||||
}
|
}
|
||||||
protected sealed override void OnDestroy() { }
|
protected sealed override void OnDestroy() { }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#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)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public EcsSpan Execute()
|
public EcsSpan Execute()
|
||||||
{
|
{
|
||||||
@ -52,29 +77,15 @@ namespace DCFApixels.DragonECS
|
|||||||
public EcsSpan ExecuteFor(EcsSpan span)
|
public EcsSpan ExecuteFor(EcsSpan span)
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||||
//_executeMarker.Begin();
|
|
||||||
if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
|
if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
|
||||||
if (span.WorldID != WorldID) { Throw.Quiery_ArgumentDifferentWorldsException(); }
|
if (span.WorldID != WorldID) { Throw.Quiery_ArgumentDifferentWorldsException(); }
|
||||||
#endif
|
#endif
|
||||||
if (World.IsEnableReleaseDelEntBuffer)
|
World.ReleaseDelEntityBufferAllAuto();
|
||||||
|
if (_lastWorldVersion != World.Version || _versionsChecker.NextEquals() == false)
|
||||||
{
|
{
|
||||||
World.ReleaseDelEntityBufferAll();
|
Filter(span);
|
||||||
}
|
}
|
||||||
EcsSpan result;
|
return new EcsSpan(WorldID, _filteredEntities, _filteredEntitiesCount);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ namespace DCFApixels.DragonECS
|
|||||||
private EcsGroup _filteredGroup;
|
private EcsGroup _filteredGroup;
|
||||||
|
|
||||||
private long _lastWorldVersion;
|
private long _lastWorldVersion;
|
||||||
|
private PoolVersionsChecker _versionsChecker;
|
||||||
|
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||||
private readonly EcsProfilerMarker _executeMarker = new EcsProfilerMarker("Where");
|
private readonly EcsProfilerMarker _executeMarker = new EcsProfilerMarker("Where");
|
||||||
@ -37,6 +38,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
_aspect = World.GetAspect<TAspect>();
|
_aspect = World.GetAspect<TAspect>();
|
||||||
_filteredGroup = EcsGroup.New(World);
|
_filteredGroup = EcsGroup.New(World);
|
||||||
|
_versionsChecker = new PoolVersionsChecker(_aspect._mask);
|
||||||
}
|
}
|
||||||
protected sealed override void OnDestroy()
|
protected sealed override void OnDestroy()
|
||||||
{
|
{
|
||||||
@ -46,6 +48,12 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private void Filter(EcsSpan span)
|
||||||
|
{
|
||||||
|
_aspect.GetIteratorFor(span).CopyTo(_filteredGroup);
|
||||||
|
_lastWorldVersion = World.Version;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public EcsReadonlyGroup Execute()
|
public EcsReadonlyGroup Execute()
|
||||||
{
|
{
|
||||||
return ExecuteFor(_aspect.World.Entities);
|
return ExecuteFor(_aspect.World.Entities);
|
||||||
@ -58,14 +66,10 @@ namespace DCFApixels.DragonECS
|
|||||||
if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
|
if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
|
||||||
if (span.WorldID != WorldID) { Throw.Quiery_ArgumentDifferentWorldsException(); }
|
if (span.WorldID != WorldID) { Throw.Quiery_ArgumentDifferentWorldsException(); }
|
||||||
#endif
|
#endif
|
||||||
if (World.IsEnableReleaseDelEntBuffer)
|
World.ReleaseDelEntityBufferAllAuto();
|
||||||
|
if (_lastWorldVersion != World.Version || _versionsChecker.NextEquals() == false)
|
||||||
{
|
{
|
||||||
World.ReleaseDelEntityBufferAll();
|
Filter(span);
|
||||||
}
|
|
||||||
if (_lastWorldVersion != World.Version)
|
|
||||||
{
|
|
||||||
_aspect.GetIteratorFor(span).CopyTo(_filteredGroup);
|
|
||||||
_lastWorldVersion = World.Version;
|
|
||||||
}
|
}
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||||
_executeMarker.End();
|
_executeMarker.End();
|
||||||
|
@ -4,7 +4,7 @@ using System.Runtime.CompilerServices;
|
|||||||
|
|
||||||
namespace DCFApixels.DragonECS.Internal
|
namespace DCFApixels.DragonECS.Internal
|
||||||
{
|
{
|
||||||
internal interface IComparerX<T>
|
internal interface IStructComparer<T>
|
||||||
{
|
{
|
||||||
// a > b = return > 0
|
// a > b = return > 0
|
||||||
int Compare(T a, T b);
|
int Compare(T a, T b);
|
||||||
@ -14,7 +14,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
private const int IntrosortSizeThreshold = 16;
|
private const int IntrosortSizeThreshold = 16;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[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)
|
if (comparer.Compare(items[i], items[j]) > 0)
|
||||||
{
|
{
|
||||||
@ -24,7 +24,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[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++)
|
for (int i = 0; i < items.Length - 1; i++)
|
||||||
{
|
{
|
||||||
@ -41,7 +41,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[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;
|
int length = items.Length;
|
||||||
if (length == 1)
|
if (length == 1)
|
||||||
@ -69,7 +69,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
InsertionSort(items, ref comparer);
|
InsertionSort(items, ref comparer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IComparerX<T> packed = comparer;
|
IStructComparer<T> packed = comparer;
|
||||||
Array.Sort(items, comparer.Compare);
|
Array.Sort(items, comparer.Compare);
|
||||||
comparer = (TComparer)packed;
|
comparer = (TComparer)packed;
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
private const int IntrosortSizeThreshold = 16;
|
private const int IntrosortSizeThreshold = 16;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[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)
|
if (comparer.Compare(items[i], items[j]) > 0)
|
||||||
{
|
{
|
||||||
@ -90,7 +90,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[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++)
|
for (int i = 0; i < length - 1; i++)
|
||||||
{
|
{
|
||||||
@ -127,7 +127,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
// break;
|
// 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)
|
if (length == 1)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user