rework queries/add using mask queries

This commit is contained in:
Mikhail 2024-10-03 08:20:22 +08:00
parent a0e359bb12
commit 952aaa23b1
7 changed files with 153 additions and 215 deletions

View File

@ -7,8 +7,8 @@ namespace DCFApixels.DragonECS
internal readonly struct PoolCache<T> : IEcsWorldComponent<PoolCache<T>> internal readonly struct PoolCache<T> : IEcsWorldComponent<PoolCache<T>>
where T : IEcsPoolImplementation, new() where T : IEcsPoolImplementation, new()
{ {
public readonly T instance; public readonly T Instance;
public PoolCache(T instance) { this.instance = instance; } public PoolCache(T instance) { Instance = instance; }
void IEcsWorldComponent<PoolCache<T>>.Init(ref PoolCache<T> component, EcsWorld world) void IEcsWorldComponent<PoolCache<T>>.Init(ref PoolCache<T> component, EcsWorld world)
{ {
component = new PoolCache<T>(world.CreatePool<T>()); component = new PoolCache<T>(world.CreatePool<T>());
@ -21,8 +21,8 @@ namespace DCFApixels.DragonECS
internal readonly struct AspectCache<T> : IEcsWorldComponent<AspectCache<T>> internal readonly struct AspectCache<T> : IEcsWorldComponent<AspectCache<T>>
where T : EcsAspect, new() where T : EcsAspect, new()
{ {
public readonly T instance; public readonly T Instance;
public AspectCache(T instance) { this.instance = instance; } public AspectCache(T instance) { Instance = instance; }
void IEcsWorldComponent<AspectCache<T>>.Init(ref AspectCache<T> component, EcsWorld world) void IEcsWorldComponent<AspectCache<T>>.Init(ref AspectCache<T> component, EcsWorld world)
{ {
component = new AspectCache<T>(EcsAspect.Builder.New<T>(world)); component = new AspectCache<T>(EcsAspect.Builder.New<T>(world));
@ -32,18 +32,25 @@ namespace DCFApixels.DragonECS
component = default; component = default;
} }
} }
internal readonly struct QueryCache<T> : IEcsWorldComponent<QueryCache<T>> internal readonly struct QueryCache<TExecutor, TAspcet> : IEcsWorldComponent<QueryCache<TExecutor, TAspcet>>
where T : EcsQueryCache, new() where TExecutor : EcsQueryExecutor, new()
where TAspcet : EcsAspect, new()
{ {
public readonly T instance; public readonly TExecutor Executor;
public QueryCache(T instance) { this.instance = instance; } public readonly TAspcet Aspcet;
void IEcsWorldComponent<QueryCache<T>>.Init(ref QueryCache<T> component, EcsWorld world) public QueryCache(TExecutor executor, TAspcet aspcet)
{ {
T instance = new T(); Executor = executor;
instance.Initialize(world, world._executorsMediator); Aspcet = aspcet;
component = new QueryCache<T>(instance);
} }
void IEcsWorldComponent<QueryCache<T>>.OnDestroy(ref QueryCache<T> component, EcsWorld world) void IEcsWorldComponent<QueryCache<TExecutor, TAspcet>>.Init(ref QueryCache<TExecutor, TAspcet> component, EcsWorld world)
{
TExecutor instance = new TExecutor();
TAspcet aspect = world.GetAspect<TAspcet>();
instance.Initialize(world, aspect.Mask);
component = new QueryCache<TExecutor, TAspcet>(instance, aspect);
}
void IEcsWorldComponent<QueryCache<TExecutor, TAspcet>>.OnDestroy(ref QueryCache<TExecutor, TAspcet> component, EcsWorld world)
{ {
component = default; component = default;
} }

View File

@ -165,7 +165,6 @@ 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];
@ -222,12 +221,16 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TAspect GetAspect<TAspect>() where TAspect : EcsAspect, new() public TAspect GetAspect<TAspect>() where TAspect : EcsAspect, new()
{ {
return Get<AspectCache<TAspect>>().instance; return Get<AspectCache<TAspect>>().Instance;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TExecutor GetQueryCache<TExecutor>() where TExecutor : EcsQueryCache, new() public void GetQueryCache<TExecutor, TAspect>(out TExecutor executor, out TAspect aspect)
where TExecutor : EcsQueryExecutor, new()
where TAspect : EcsAspect, new()
{ {
return Get<QueryCache<TExecutor>>().instance; ref var cmp = ref Get<QueryCache<TExecutor, TAspect>>();
executor = cmp.Executor;
aspect = cmp.Aspcet;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@ -65,7 +65,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TPool GetPoolInstance<TPool>() where TPool : IEcsPoolImplementation, new() public TPool GetPoolInstance<TPool>() where TPool : IEcsPoolImplementation, new()
{ {
return Get<PoolCache<TPool>>().instance; return Get<PoolCache<TPool>>().Instance;
} }
#if UNITY_2020_3_OR_NEWER #if UNITY_2020_3_OR_NEWER
[UnityEngine.Scripting.Preserve] [UnityEngine.Scripting.Preserve]
@ -73,7 +73,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TPool GetPoolInstanceUnchecked<TPool>() where TPool : IEcsPoolImplementation, new() public TPool GetPoolInstanceUnchecked<TPool>() where TPool : IEcsPoolImplementation, new()
{ {
return GetUnchecked<PoolCache<TPool>>().instance; return GetUnchecked<PoolCache<TPool>>().Instance;
} }
#if UNITY_2020_3_OR_NEWER #if UNITY_2020_3_OR_NEWER
[UnityEngine.Scripting.Preserve] [UnityEngine.Scripting.Preserve]
@ -81,7 +81,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TPool GetPoolInstance<TPool>(int worldID) where TPool : IEcsPoolImplementation, new() public static TPool GetPoolInstance<TPool>(int worldID) where TPool : IEcsPoolImplementation, new()
{ {
return Get<PoolCache<TPool>>(worldID).instance; return Get<PoolCache<TPool>>(worldID).Instance;
} }
#if UNITY_2020_3_OR_NEWER #if UNITY_2020_3_OR_NEWER
[UnityEngine.Scripting.Preserve] [UnityEngine.Scripting.Preserve]
@ -89,7 +89,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TPool GetPoolInstanceUnchecked<TPool>(int worldID) where TPool : IEcsPoolImplementation, new() public static TPool GetPoolInstanceUnchecked<TPool>(int worldID) where TPool : IEcsPoolImplementation, new()
{ {
return GetUnchecked<PoolCache<TPool>>(worldID).instance; return GetUnchecked<PoolCache<TPool>>(worldID).Instance;
} }
#endregion #endregion

View File

@ -7,42 +7,29 @@ namespace DCFApixels.DragonECS
public partial class EcsWorld public partial class EcsWorld
{ {
private readonly Dictionary<(Type, object), EcsQueryExecutor> _executorCoures = new Dictionary<(Type, object), EcsQueryExecutor>(256); private readonly Dictionary<(Type, object), EcsQueryExecutor> _executorCoures = new Dictionary<(Type, object), EcsQueryExecutor>(256);
private readonly ExecutorMediator _executorsMediator; public TExecutor GetExecutor<TExecutor>(EcsMask mask)
public readonly struct ExecutorMediator where TExecutor : EcsQueryExecutor, new()
{ {
public readonly EcsWorld World; var coreType = typeof(TExecutor);
internal ExecutorMediator(EcsWorld world) if (_executorCoures.TryGetValue((coreType, mask), out EcsQueryExecutor core) == false)
{ {
if (world == null || world._executorsMediator.World != null) core = new TExecutor();
{ core.Initialize(this, mask);
throw new InvalidOperationException(); _executorCoures.Add((coreType, mask), core);
}
World = world;
} }
public TExecutorCore GetCore<TExecutorCore>(EcsMask mask) return (TExecutor)core;
where TExecutorCore : EcsQueryExecutor, new() }
public TExecutorCore GetExecutor<TExecutorCore>(EcsStaticMask staticMask)
where TExecutorCore : EcsQueryExecutor, new()
{
var coreType = typeof(TExecutorCore);
if (_executorCoures.TryGetValue((coreType, staticMask), out EcsQueryExecutor core) == false)
{ {
var coreType = typeof(TExecutorCore); core = new TExecutorCore();
if (World._executorCoures.TryGetValue((coreType, mask), out EcsQueryExecutor core) == false) core.Initialize(this, staticMask.ToMask(this));
{ _executorCoures.Add((coreType, staticMask), core);
core = new TExecutorCore();
core.Initialize(World, mask);
World._executorCoures.Add((coreType, mask), core);
}
return (TExecutorCore)core;
}
public TExecutorCore GetCore<TExecutorCore>(EcsStaticMask staticMask)
where TExecutorCore : EcsQueryExecutor, new()
{
var coreType = typeof(TExecutorCore);
if (World._executorCoures.TryGetValue((coreType, staticMask), out EcsQueryExecutor core) == false)
{
core = new TExecutorCore();
core.Initialize(World, staticMask.ToMask(World));
World._executorCoures.Add((coreType, staticMask), core);
}
return (TExecutorCore)core;
} }
return (TExecutorCore)core;
} }
} }
public abstract class EcsQueryExecutor public abstract class EcsQueryExecutor
@ -64,6 +51,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _mask; } get { return _mask; }
} }
public abstract long Version { get; }
internal void Initialize(EcsWorld world, EcsMask mask) internal void Initialize(EcsWorld world, EcsMask mask)
{ {
_source = world; _source = world;
@ -78,40 +66,6 @@ namespace DCFApixels.DragonECS
protected abstract void OnInitialize(); protected abstract void OnInitialize();
protected abstract void OnDestroy(); protected abstract void OnDestroy();
} }
public abstract class EcsQueryCache
{
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
{ {

View File

@ -1,5 +1,4 @@
using DCFApixels.DragonECS.Internal; using System;
using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
#if ENABLE_IL2CPP #if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices; using Unity.IL2CPP.CompilerServices;
@ -25,7 +24,7 @@ namespace DCFApixels.DragonECS.Internal
private PoolVersionsChecker _versionsChecker; private PoolVersionsChecker _versionsChecker;
#region Properties #region Properties
public long Version public sealed override long Version
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _version; } get { return _version; }
@ -97,61 +96,3 @@ namespace DCFApixels.DragonECS.Internal
#endregion #endregion
} }
} }
namespace DCFApixels.DragonECS
{
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
public sealed class EcsWhereCache<TAspect> : EcsQueryCache where TAspect : EcsAspect, new()
{
private TAspect _aspect;
private EcsWhereExecutor _executor;
#region Properties
public TAspect Aspect
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _aspect; }
}
public sealed override long Version
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _executor.Version; }
}
#endregion
#region OnInitialize/OnDestroy
protected sealed override void OnInitialize()
{
_aspect = World.GetAspect<TAspect>();
_executor = Mediator.GetCore<EcsWhereExecutor>(_aspect.Mask);
}
protected sealed override void OnDestroy() { }
#endregion
#region Methods
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Execute()
{
return _executor.Execute();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ExecuteFor(EcsSpan span)
{
return _executor.ExecuteFor(span);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Execute(Comparison<int> comparison)
{
return _executor.Execute(comparison);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ExecuteFor(EcsSpan span, Comparison<int> comparison)
{
return _executor.ExecuteFor(span, comparison);
}
#endregion
}
}

View File

@ -1,5 +1,4 @@
using DCFApixels.DragonECS.Internal; using System.Runtime.CompilerServices;
using System.Runtime.CompilerServices;
#if ENABLE_IL2CPP #if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices; using Unity.IL2CPP.CompilerServices;
#endif #endif
@ -22,7 +21,7 @@ namespace DCFApixels.DragonECS.Internal
private PoolVersionsChecker _versionsChecker; private PoolVersionsChecker _versionsChecker;
#region Properties #region Properties
public long Version public sealed override long Version
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _version; } get { return _version; }
@ -83,54 +82,3 @@ namespace DCFApixels.DragonECS.Internal
#endregion #endregion
} }
} }
namespace DCFApixels.DragonECS
{
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
public sealed class EcsWhereToGroupCache<TAspect> : EcsQueryCache where TAspect : EcsAspect, new()
{
private TAspect _aspect;
private EcsWhereToGroupExecutor _executor;
#region Properties
public TAspect Aspect
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _aspect; }
}
public sealed override long Version
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _executor.Version; }
}
#endregion
#region OnInitialize/OnDestroy
protected sealed override void OnInitialize()
{
_aspect = World.GetAspect<TAspect>();
_executor = Mediator.GetCore<EcsWhereToGroupExecutor>(_aspect.Mask);
}
protected sealed override void OnDestroy()
{
_executor.Destroy();
}
#endregion
#region Methods
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup Execute()
{
return _executor.Execute();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup ExecuteFor(EcsSpan span)
{
return _executor.ExecuteFor(span);
}
#endregion
}
}

View File

@ -1,4 +1,5 @@
using System; using DCFApixels.DragonECS.Internal;
using System;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
@ -24,14 +25,39 @@ namespace DCFApixels.DragonECS
where TAspect : EcsAspect, new() where TAspect : EcsAspect, new()
{ {
EcsWorld world = span.World; EcsWorld world = span.World;
var executor = world.GetQueryCache<EcsWhereCache<TAspect>>(); world.GetQueryCache(out EcsWhereExecutor executor, out aspect);
aspect = executor.Aspect; return executor.ExecuteFor(span);
}
public static EcsSpan Where<TCollection>(this TCollection entities, EcsStaticMask mask)
where TCollection : IEntityStorage
{
return entities.ToSpan().Where(mask);
}
public static EcsSpan Where(this EcsReadonlyGroup group, EcsStaticMask mask)
{
return group.ToSpan().Where(mask);
}
public static EcsSpan Where(this EcsSpan span, EcsStaticMask mask)
{
EcsWorld world = span.World;
var executor = world.GetExecutor<EcsWhereExecutor>(mask);
return executor.ExecuteFor(span);
}
public static EcsSpan Where<TCollection>(this TCollection entities, EcsMask mask)
where TCollection : IEntityStorage
{
return entities.ToSpan().Where(mask);
}
public static EcsSpan Where(this EcsReadonlyGroup group, EcsMask mask)
{
return group.ToSpan().Where(mask);
}
public static EcsSpan Where(this EcsSpan span, EcsMask mask)
{
EcsWorld world = span.World;
var executor = world.GetExecutor<EcsWhereExecutor>(mask);
return executor.ExecuteFor(span); return executor.ExecuteFor(span);
} }
//public static EcsSpan Where<TCollection>(this TCollection entities, EcsStaticMask mask)
//{
//
//}
#endregion #endregion
#region Where with sort #region Where with sort
@ -50,8 +76,37 @@ namespace DCFApixels.DragonECS
where TAspect : EcsAspect, new() where TAspect : EcsAspect, new()
{ {
EcsWorld world = span.World; EcsWorld world = span.World;
var executor = world.GetQueryCache<EcsWhereCache<TAspect>>(); world.GetQueryCache(out EcsWhereExecutor executor, out aspect);
aspect = executor.Aspect; return executor.ExecuteFor(span, comparison);
}
public static EcsSpan Where<TCollection>(this TCollection entities, EcsStaticMask mask, Comparison<int> comparison)
where TCollection : IEntityStorage
{
return entities.ToSpan().Where(mask, comparison);
}
public static EcsSpan Where(this EcsReadonlyGroup group, EcsStaticMask mask, Comparison<int> comparison)
{
return group.ToSpan().Where(mask, comparison);
}
public static EcsSpan Where(this EcsSpan span, EcsStaticMask mask, Comparison<int> comparison)
{
EcsWorld world = span.World;
var executor = world.GetExecutor<EcsWhereExecutor>(mask);
return executor.ExecuteFor(span);
}
public static EcsSpan Where<TCollection>(this TCollection entities, EcsMask mask, Comparison<int> comparison)
where TCollection : IEntityStorage
{
return entities.ToSpan().Where(mask, comparison);
}
public static EcsSpan Where(this EcsReadonlyGroup group, EcsMask mask, Comparison<int> comparison)
{
return group.ToSpan().Where(mask, comparison);
}
public static EcsSpan Where(this EcsSpan span, EcsMask mask, Comparison<int> comparison)
{
EcsWorld world = span.World;
var executor = world.GetExecutor<EcsWhereExecutor>(mask);
return executor.ExecuteFor(span, comparison); return executor.ExecuteFor(span, comparison);
} }
#endregion #endregion
@ -72,8 +127,38 @@ namespace DCFApixels.DragonECS
where TAspect : EcsAspect, new() where TAspect : EcsAspect, new()
{ {
EcsWorld world = span.World; EcsWorld world = span.World;
var executor = world.GetQueryCache<EcsWhereToGroupCache<TAspect>>(); world.GetQueryCache(out EcsWhereToGroupExecutor executor, out aspect);
aspect = executor.Aspect; return executor.ExecuteFor(span);
}
public static EcsReadonlyGroup WhereToGroup<TCollection>(this TCollection entities, EcsStaticMask mask)
where TCollection : IEntityStorage
{
return entities.ToSpan().WhereToGroup(mask);
}
public static EcsReadonlyGroup WhereToGroup(this EcsReadonlyGroup group, EcsStaticMask mask)
{
return group.ToSpan().WhereToGroup(mask);
}
public static EcsReadonlyGroup WhereToGroup(this EcsSpan span, EcsStaticMask mask)
{
EcsWorld world = span.World;
var executor = world.GetExecutor<EcsWhereToGroupExecutor>(mask);
return executor.ExecuteFor(span);
}
public static EcsReadonlyGroup WhereToGroup<TCollection>(this TCollection entities, EcsMask mask)
where TCollection : IEntityStorage
{
return entities.ToSpan().WhereToGroup(mask);
}
public static EcsReadonlyGroup WhereToGroup(this EcsReadonlyGroup group, EcsMask mask)
{
return group.ToSpan().WhereToGroup(mask);
}
public static EcsReadonlyGroup WhereToGroup(this EcsSpan span, EcsMask mask)
{
EcsWorld world = span.World;
var executor = world.GetExecutor<EcsWhereToGroupExecutor>(mask);
return executor.ExecuteFor(span); return executor.ExecuteFor(span);
} }
#endregion #endregion