update queries stash

This commit is contained in:
Mikhail 2024-08-24 12:29:58 +08:00
parent 2b73c35977
commit 07c122d406
7 changed files with 363 additions and 130 deletions

View File

@ -2,7 +2,7 @@
using DCFApixels.DragonECS.PoolsCore; using DCFApixels.DragonECS.PoolsCore;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using static DCFApixels.DragonECS.EcsAspect;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
@ -138,29 +138,6 @@ namespace DCFApixels.DragonECS
builder.Build(out newAspect._mask); builder.Build(out newAspect._mask);
newAspect._isBuilt = true; newAspect._isBuilt = true;
newAspect._sortIncBuffer = new UnsafeArray<int>(newAspect._mask._inc.Length, true);
newAspect._sortExcBuffer = new UnsafeArray<int>(newAspect._mask._exc.Length, true);
newAspect._sortIncChunckBuffer = new UnsafeArray<EcsMaskChunck>(newAspect._mask._incChunckMasks.Length, true);
newAspect._sortExcChunckBuffer = new UnsafeArray<EcsMaskChunck>(newAspect._mask._excChunckMasks.Length, true);
for (int i = 0; i < newAspect._sortIncBuffer.Length; i++)
{
newAspect._sortIncBuffer.ptr[i] = newAspect._mask._inc[i];
}
for (int i = 0; i < newAspect._sortExcBuffer.Length; i++)
{
newAspect._sortExcBuffer.ptr[i] = newAspect._mask._exc[i];
}
for (int i = 0; i < newAspect._sortIncChunckBuffer.Length; i++)
{
newAspect._sortIncChunckBuffer.ptr[i] = newAspect._mask._incChunckMasks[i];
}
for (int i = 0; i < newAspect._sortExcChunckBuffer.Length; i++)
{
newAspect._sortExcChunckBuffer.ptr[i] = newAspect._mask._excChunckMasks[i];
}
return (TAspect)newAspect; return (TAspect)newAspect;
} }
@ -224,27 +201,6 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region Finalizator
unsafe ~EcsAspect()
{
_sortIncBuffer.Dispose();
_sortExcBuffer.Dispose();
_sortIncChunckBuffer.Dispose();
_sortExcChunckBuffer.Dispose();
}
#endregion
#region Iterator
public Iterator GetIterator()
{
return new Iterator(this, _source.Entities);
}
public Iterator GetIteratorFor(EcsSpan span)
{
return new Iterator(this, span);
}
#endregion
#region Combined #region Combined
private readonly struct Combined private readonly struct Combined
{ {
@ -259,17 +215,48 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Iterator #region Iterator
[Obsolete("Use EcsMask.GetIterator()")]
public Iterator GetIterator()
{
return new Iterator(Mask.GetIterator(), _source.Entities);
}
[Obsolete("Use EcsMask.GetIterator().Iterate(span)")]
public Iterator GetIteratorFor(EcsSpan span)
{
return new Iterator(Mask.GetIterator(), span);
}
[Obsolete("Use EcsMaskIterator")]
public ref struct Iterator public ref struct Iterator
{ {
public readonly short worldID; public readonly short worldID;
public readonly EcsAspect aspect; public readonly EcsMaskIterator.Enumerable iterator;
private EcsSpan _span; private EcsSpan _span;
public Iterator(EcsAspect aspect, EcsSpan span) public Iterator(EcsMaskIterator iterator, EcsSpan span)
{ {
worldID = aspect.World.id; worldID = iterator.World.id;
_span = span; _span = span;
this.aspect = aspect; this.iterator = iterator.Iterate(span);
}
#region CopyTo
public void CopyTo(EcsGroup group)
{
iterator.CopyTo(group);
}
public int CopyTo(ref int[] array)
{
return iterator.CopyTo(ref array);
}
public EcsSpan CopyToSpan(ref int[] array)
{
return iterator.CopyToSpan(ref array);
}
#endregion
public EcsMaskIterator.Enumerable.Enumerator GetEnumerator()
{
return iterator.GetEnumerator();
} }
} }
#endregion #endregion

View File

@ -651,6 +651,11 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region EcsMaskIterator
#if ENABLE_IL2CPP
[Il2CppSetOption (Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
public class EcsMaskIterator public class EcsMaskIterator
{ {
#region CountStructComparers #region CountStructComparers
@ -689,10 +694,43 @@ namespace DCFApixels.DragonECS
private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer; private UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
#region Constructors #region Constructors
public EcsMaskIterator(EcsWorld source, EcsMask mask) public unsafe EcsMaskIterator(EcsWorld source, EcsMask mask)
{ {
_source = source; _source = source;
_mask = mask; _mask = mask;
_sortIncBuffer = new UnsafeArray<int>(_mask._inc.Length, true);
_sortExcBuffer = new UnsafeArray<int>(_mask._exc.Length, true);
_sortIncChunckBuffer = new UnsafeArray<EcsMaskChunck>(_mask._incChunckMasks.Length, true);
_sortExcChunckBuffer = new UnsafeArray<EcsMaskChunck>(_mask._excChunckMasks.Length, true);
for (int i = 0; i < _sortIncBuffer.Length; i++)
{
_sortIncBuffer.ptr[i] = _mask._inc[i];
}
for (int i = 0; i < _sortExcBuffer.Length; i++)
{
_sortExcBuffer.ptr[i] = _mask._exc[i];
}
for (int i = 0; i < _sortIncChunckBuffer.Length; i++)
{
_sortIncChunckBuffer.ptr[i] = _mask._incChunckMasks[i];
}
for (int i = 0; i < _sortExcChunckBuffer.Length; i++)
{
_sortExcChunckBuffer.ptr[i] = _mask._excChunckMasks[i];
}
}
#endregion
#region Finalizator
unsafe ~EcsMaskIterator()
{
_sortIncBuffer.Dispose();
_sortExcBuffer.Dispose();
_sortIncChunckBuffer.Dispose();
_sortExcChunckBuffer.Dispose();
} }
#endregion #endregion
@ -911,4 +949,5 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
} }
#endregion
} }

View File

@ -32,18 +32,18 @@ namespace DCFApixels.DragonECS
component = default; component = default;
} }
} }
internal readonly struct ExcecutorCache<T> : IEcsWorldComponent<ExcecutorCache<T>> internal readonly struct ExeccutorCache<T> : IEcsWorldComponent<ExeccutorCache<T>>
where T : EcsQueryExecutor, new() where T : EcsQueryExecutor, new()
{ {
public readonly T instance; public readonly T instance;
public ExcecutorCache(T instance) => this.instance = instance; public ExeccutorCache(T instance) => this.instance = instance;
void IEcsWorldComponent<ExcecutorCache<T>>.Init(ref ExcecutorCache<T> component, EcsWorld world) void IEcsWorldComponent<ExeccutorCache<T>>.Init(ref ExeccutorCache<T> component, EcsWorld world)
{ {
T instance = new T(); T instance = new T();
instance.Initialize(world); instance.Initialize(world, world._executorsMediator);
component = new ExcecutorCache<T>(instance); component = new ExeccutorCache<T>(instance);
} }
void IEcsWorldComponent<ExcecutorCache<T>>.OnDestroy(ref ExcecutorCache<T> component, EcsWorld world) void IEcsWorldComponent<ExeccutorCache<T>>.OnDestroy(ref ExeccutorCache<T> component, EcsWorld world)
{ {
component = default; component = default;
} }

View File

@ -166,10 +166,11 @@ namespace DCFApixels.DragonECS
_worlds[worldID] = this; _worlds[worldID] = this;
_poolsMediator = new PoolsMediator(this); _poolsMediator = new PoolsMediator(this);
_executorsMediator = new ExecutorMediator(this);
int poolsCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.PoolsCapacity); int poolsCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.PoolsCapacity);
_pools = new IEcsPoolImplementation[poolsCapacity]; _pools = new IEcsPoolImplementation[poolsCapacity];
_poolSlots = new int[poolsCapacity]; _poolSlots = new PoolSlot[poolsCapacity];
ArrayUtility.Fill(_pools, _nullPool); ArrayUtility.Fill(_pools, _nullPool);
int entitiesCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.EntitiesCapacity); int entitiesCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.EntitiesCapacity);
@ -218,7 +219,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TExecutor GetExecutor<TExecutor>() where TExecutor : EcsQueryExecutor, new() public TExecutor GetExecutor<TExecutor>() where TExecutor : EcsQueryExecutor, new()
{ {
return Get<ExcecutorCache<TExecutor>>().instance; return Get<ExeccutorCache<TExecutor>>().instance;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@ -1,8 +1,39 @@
using System.Runtime.CompilerServices; using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
public abstract class EcsQueryExecutor public partial class EcsWorld
{
private readonly Dictionary<(Type, Type), EcsQueryExecutorCore> _executorCoures = new Dictionary<(Type, Type), EcsQueryExecutorCore>();
private readonly ExecutorMediator _executorsMediator;
public readonly struct ExecutorMediator
{
public readonly EcsWorld World;
internal ExecutorMediator(EcsWorld world)
{
if (world == null || world._executorsMediator.World != null)
{
throw new InvalidOperationException();
}
World = world;
}
public TExecutorCore GetCore<TExecutorCore>(Type aspectType)
where TExecutorCore : EcsQueryExecutorCore, new()
{
var coreType = typeof(EcsQueryExecutorCore);
if(World._executorCoures.TryGetValue((aspectType, coreType), out EcsQueryExecutorCore core))
{
core = new TExecutorCore();
core.Initialize(World);
World._executorCoures.Add((aspectType, coreType), core);
}
return (TExecutorCore)core;
}
}
}
public abstract class EcsQueryExecutorCore
{ {
private EcsWorld _source; private EcsWorld _source;
public short WorldID public short WorldID
@ -15,7 +46,6 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source; } get { return _source; }
} }
public abstract long Version { get; }
internal void Initialize(EcsWorld world) internal void Initialize(EcsWorld world)
{ {
_source = world; _source = world;
@ -29,13 +59,47 @@ namespace DCFApixels.DragonECS
protected abstract void OnInitialize(); protected abstract void OnInitialize();
protected abstract void OnDestroy(); protected abstract void OnDestroy();
} }
public abstract class EcsQueryExecutor
{
private EcsWorld _source;
private EcsWorld.ExecutorMediator _mediator;
public short WorldID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source.id; }
}
public EcsWorld World
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source; }
}
protected EcsWorld.ExecutorMediator Mediator
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _mediator; }
}
public abstract long Version { get; }
internal void Initialize(EcsWorld world, EcsWorld.ExecutorMediator mediator)
{
_source = world;
_mediator = mediator;
OnInitialize();
}
internal void Destroy()
{
OnDestroy();
_source = null;
}
protected abstract void OnInitialize();
protected abstract void OnDestroy();
}
public readonly struct PoolVersionsChecker public readonly struct PoolVersionsChecker
{ {
private readonly EcsMask _mask; private readonly EcsMask _mask;
private readonly long[] _versions; private readonly long[] _versions;
public PoolVersionsChecker(EcsMask mask) : this() public PoolVersionsChecker(EcsMask mask)
{ {
_mask = mask; _mask = mask;
_versions = new long[mask._inc.Length + mask._exc.Length]; _versions = new long[mask._inc.Length + mask._exc.Length];

View File

@ -1,51 +1,89 @@
using DCFApixels.DragonECS.Internal; using DCFApixels.DragonECS.Internal;
using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS
{
#if ENABLE_IL2CPP #if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices; using Unity.IL2CPP.CompilerServices;
#endif
namespace DCFApixels.DragonECS.Internal
{
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)] [Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)] [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif #endif
public sealed class EcsWhereExecutor<TAspect> : EcsQueryExecutor where TAspect : EcsAspect, new() internal readonly struct EcsWhereExecutorCoreList : IEcsWorldComponent<EcsWhereExecutorCoreList>
{ {
private TAspect _aspect; internal readonly EcsWhereExecutorCore[] _cores;
private int[] _filteredEntities; public EcsWhereExecutorCoreList(EcsWhereExecutorCore[] cores)
private int _filteredEntitiesCount; {
_cores = cores;
}
public void Init(ref EcsWhereExecutorCoreList component, EcsWorld world)
{
component = new EcsWhereExecutorCoreList(new EcsWhereExecutorCore[64]);
}
public void OnDestroy(ref EcsWhereExecutorCoreList component, EcsWorld world)
{
component = default;
}
}
private long _lastWorldVersion; #if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
internal class EcsWhereExecutorCore
{
private EcsWorld _source;
private EcsMaskIterator _iterator;
private int[] _filteredEntities = new int[32];
private int _filteredEntitiesCount = 0;
private long _lastWorldVersion = 0;
private PoolVersionsChecker _versionsChecker; private PoolVersionsChecker _versionsChecker;
#region Properties #region Properties
public TAspect Aspect public long Version
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _aspect; get { return _lastWorldVersion; }
}
public sealed override long Version
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _lastWorldVersion;
} }
#endregion #endregion
#region OnInitialize/OnDestroy #region Constructors
protected sealed override void OnInitialize() public EcsWhereExecutorCore(EcsWorld source, EcsAspect aspect)
{ {
_aspect = World.GetAspect<TAspect>(); _source = source;
_filteredEntities = new int[32]; _versionsChecker = new PoolVersionsChecker(aspect.Mask);
_versionsChecker = new PoolVersionsChecker(_aspect._mask);
} }
protected sealed override void OnDestroy() { }
#endregion #endregion
#region Methods #region Methods
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Filter(EcsSpan span) private void Filter(EcsSpan span)
{ {
_filteredEntitiesCount = _aspect.GetIteratorFor(span).CopyTo(ref _filteredEntities); _filteredEntitiesCount = _iterator.Iterate(span).CopyTo(ref _filteredEntities);
_lastWorldVersion = World.Version; _lastWorldVersion = _source.Version;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Execute()
{
return ExecuteFor(_source.Entities);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ExecuteFor(EcsSpan span)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
if (span.WorldID != _source.id) { Throw.Quiery_ArgumentDifferentWorldsException(); }
#endif
_source.ReleaseDelEntityBufferAllAuto();
if (_lastWorldVersion != _source.Version || _versionsChecker.NextEquals() == false)
{
Filter(span);
}
return new EcsSpan(_source.id, _filteredEntities, _filteredEntitiesCount);
} }
// [MethodImpl(MethodImplOptions.AggressiveInlining)] // [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -67,25 +105,66 @@ namespace DCFApixels.DragonECS
// } // }
// Array.Sort<int>(_filteredEntities, 0, _filteredEntitiesCount, comparison); // Array.Sort<int>(_filteredEntities, 0, _filteredEntitiesCount, comparison);
// } // }
#endregion
}
}
namespace DCFApixels.DragonECS
{
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
public sealed class EcsWhereExecutor<TAspect> : EcsQueryExecutor where TAspect : EcsAspect, new()
{
private TAspect _aspect;
private EcsWhereExecutorCore _core;
#region Properties
public TAspect Aspect
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _aspect; }
}
public sealed override long Version
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _core.Version; }
}
#endregion
#region OnInitialize/OnDestroy
protected sealed override void OnInitialize()
{
_aspect = World.GetAspect<TAspect>();
int maskID = _aspect.Mask.ID;
ref var list = ref World.Get<EcsWhereExecutorCoreList>();
var cores = list._cores;
if (maskID >= list._cores.Length)
{
Array.Resize(ref cores, cores.Length << 1);
list = new EcsWhereExecutorCoreList(cores);
}
ref var coreRef = ref cores[maskID];
if (coreRef == null)
{
coreRef = new EcsWhereExecutorCore(World, _aspect);
}
_core = coreRef;
}
protected sealed override void OnDestroy() { }
#endregion
#region Methods
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Execute() public EcsSpan Execute()
{ {
return ExecuteFor(_aspect.World.Entities); return _core.Execute();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ExecuteFor(EcsSpan span) public EcsSpan ExecuteFor(EcsSpan span)
{ {
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS return _core.ExecuteFor(span);
if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
if (span.WorldID != WorldID) { Throw.Quiery_ArgumentDifferentWorldsException(); }
#endif
World.ReleaseDelEntityBufferAllAuto();
if (_lastWorldVersion != World.Version || _versionsChecker.NextEquals() == false)
{
Filter(span);
}
return new EcsSpan(WorldID, _filteredEntities, _filteredEntitiesCount);
} }
#endregion #endregion
} }

View File

@ -1,35 +1,117 @@
using DCFApixels.DragonECS.Internal; using DCFApixels.DragonECS.Internal;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
#if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices;
#endif
namespace DCFApixels.DragonECS.Internal
{
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
internal readonly struct EcsWhereToGroupExecutorCoreList : IEcsWorldComponent<EcsWhereToGroupExecutorCoreList>
{
internal readonly EcsWhereToGroupExecutorCore[] _cores;
public EcsWhereToGroupExecutorCoreList(EcsWhereToGroupExecutorCore[] cores)
{
_cores = cores;
}
public void Init(ref EcsWhereToGroupExecutorCoreList component, EcsWorld world)
{
component = new EcsWhereToGroupExecutorCoreList(new EcsWhereToGroupExecutorCore[64]);
}
public void OnDestroy(ref EcsWhereToGroupExecutorCoreList component, EcsWorld world)
{
component = default;
}
}
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
internal class EcsWhereToGroupExecutorCore
{
private EcsWorld _source;
private EcsMaskIterator _iterator;
private EcsGroup _filteredGroup;
private long _lastWorldVersion;
private PoolVersionsChecker _versionsChecker;
#region Properties
public long Version
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _lastWorldVersion; }
}
#endregion
#region Constructors/Destroy
public EcsWhereToGroupExecutorCore(EcsWorld source, EcsAspect aspect)
{
_source = source;
_versionsChecker = new PoolVersionsChecker(aspect.Mask);
}
public void Destroy()
{
_filteredGroup.Dispose();
}
#endregion
#region Methods
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Filter(EcsSpan span)
{
_iterator.Iterate(span).CopyTo(_filteredGroup);
_lastWorldVersion = _source.Version;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Execute()
{
return ExecuteFor(_source.Entities);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ExecuteFor(EcsSpan span)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (span.IsNull) { Throw.ArgumentNull(nameof(span)); }
if (span.WorldID != _source.id) { Throw.Quiery_ArgumentDifferentWorldsException(); }
#endif
_source.ReleaseDelEntityBufferAllAuto();
if (_lastWorldVersion != _source.Version || _versionsChecker.NextEquals() == false)
{
Filter(span);
}
return _filteredGroup.Readonly;
}
#endregion
}
}
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
#if ENABLE_IL2CPP #if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices;
[Il2CppSetOption(Option.NullChecks, false)] [Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)] [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif #endif
public sealed class EcsWhereToGroupExecutor<TAspect> : EcsQueryExecutor where TAspect : EcsAspect, new() public sealed class EcsWhereToGroupExecutor<TAspect> : EcsQueryExecutor where TAspect : EcsAspect, new()
{ {
private TAspect _aspect; private TAspect _aspect;
private EcsGroup _filteredGroup; private EcsWhereToGroupExecutorCore _core;
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
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _aspect; get { return _aspect; }
} }
public sealed override long Version public sealed override long Version
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _lastWorldVersion; get { return _core.Version; }
} }
#endregion #endregion
@ -42,39 +124,20 @@ namespace DCFApixels.DragonECS
} }
protected sealed override void OnDestroy() protected sealed override void OnDestroy()
{ {
_filteredGroup.Dispose(); _core.Destroy();
} }
#endregion #endregion
#region Methods #region Methods
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Filter(EcsSpan span) public EcsSpan Execute()
{ {
_aspect.GetIteratorFor(span).CopyTo(_filteredGroup); return _core.Execute();
_lastWorldVersion = World.Version;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup Execute() public EcsSpan ExecuteFor(EcsSpan span)
{ {
return ExecuteFor(_aspect.World.Entities); return _core.ExecuteFor(span);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup 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
World.ReleaseDelEntityBufferAllAuto();
if (_lastWorldVersion != World.Version || _versionsChecker.NextEquals() == false)
{
Filter(span);
}
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
_executeMarker.End();
#endif
return _filteredGroup.Readonly;
} }
#endregion #endregion
} }