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

View File

@ -165,7 +165,6 @@ namespace DCFApixels.DragonECS
_worlds[worldID] = this;
_poolsMediator = new PoolsMediator(this);
_executorsMediator = new ExecutorMediator(this);
int poolsCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.PoolsCapacity);
_pools = new IEcsPoolImplementation[poolsCapacity];
@ -222,12 +221,16 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TAspect GetAspect<TAspect>() where TAspect : EcsAspect, new()
{
return Get<AspectCache<TAspect>>().instance;
return Get<AspectCache<TAspect>>().Instance;
}
[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)]

View File

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

View File

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

View File

@ -1,5 +1,4 @@
using DCFApixels.DragonECS.Internal;
using System;
using System;
using System.Runtime.CompilerServices;
#if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices;
@ -25,7 +24,7 @@ namespace DCFApixels.DragonECS.Internal
private PoolVersionsChecker _versionsChecker;
#region Properties
public long Version
public sealed override long Version
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _version; }
@ -97,61 +96,3 @@ namespace DCFApixels.DragonECS.Internal
#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
using Unity.IL2CPP.CompilerServices;
#endif
@ -22,7 +21,7 @@ namespace DCFApixels.DragonECS.Internal
private PoolVersionsChecker _versionsChecker;
#region Properties
public long Version
public sealed override long Version
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _version; }
@ -83,54 +82,3 @@ namespace DCFApixels.DragonECS.Internal
#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
{
@ -24,14 +25,39 @@ namespace DCFApixels.DragonECS
where TAspect : EcsAspect, new()
{
EcsWorld world = span.World;
var executor = world.GetQueryCache<EcsWhereCache<TAspect>>();
aspect = executor.Aspect;
world.GetQueryCache(out EcsWhereExecutor executor, out 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);
}
//public static EcsSpan Where<TCollection>(this TCollection entities, EcsStaticMask mask)
//{
//
//}
#endregion
#region Where with sort
@ -50,8 +76,37 @@ namespace DCFApixels.DragonECS
where TAspect : EcsAspect, new()
{
EcsWorld world = span.World;
var executor = world.GetQueryCache<EcsWhereCache<TAspect>>();
aspect = executor.Aspect;
world.GetQueryCache(out EcsWhereExecutor executor, out 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);
}
#endregion
@ -72,8 +127,38 @@ namespace DCFApixels.DragonECS
where TAspect : EcsAspect, new()
{
EcsWorld world = span.World;
var executor = world.GetQueryCache<EcsWhereToGroupCache<TAspect>>();
aspect = executor.Aspect;
world.GetQueryCache(out EcsWhereToGroupExecutor executor, out 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);
}
#endregion