using DCFApixels.DragonECS.Internal; using System.Runtime.CompilerServices; namespace DCFApixels.DragonECS { #if ENABLE_IL2CPP using Unity.IL2CPP.CompilerServices; [Il2CppSetOption(Option.NullChecks, false)] [Il2CppSetOption(Option.ArrayBoundsChecks, false)] #endif public sealed class EcsWhereToGroupExecutor : EcsQueryExecutor where TAspect : EcsAspect, new() { private TAspect _aspect; private EcsGroup _filteredGroup; private long _lastWorldVersion; private PoolVersionsChecker _versionsChecker; #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS private readonly EcsProfilerMarker _executeMarker = new EcsProfilerMarker("Where"); #endif #region Properties public TAspect Aspect { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _aspect; } public sealed override long Version { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _lastWorldVersion; } #endregion #region OnInitialize/OnDestroy protected sealed override void OnInitialize() { _aspect = World.GetAspect(); _filteredGroup = EcsGroup.New(World); _versionsChecker = new PoolVersionsChecker(_aspect._mask); } protected sealed override void OnDestroy() { _filteredGroup.Dispose(); } #endregion #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); } [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 } }