mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
update where queries, fix query cache
This commit is contained in:
parent
36c74d5a4c
commit
8c442a66c0
@ -184,7 +184,7 @@ namespace DCFApixels.DragonECS
|
||||
private TPool CachePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
||||
{
|
||||
var pool = _world.GetPoolInstance<TPool>();
|
||||
if(_poolsBufferCount >= _poolsBuffer.Length)
|
||||
if (_poolsBufferCount >= _poolsBuffer.Length)
|
||||
{
|
||||
Array.Resize(ref _poolsBuffer, _poolsBuffer.Length << 1);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DCFApixels.DragonECS.PoolsCore;
|
||||
using DCFApixels.DragonECS.Core;
|
||||
using DCFApixels.DragonECS.PoolsCore;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
@ -33,14 +34,8 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
|
||||
//TODO добавить сквозной кеш для инстансов TExecutor
|
||||
//private readonly struct WhereCache<TExecutor> : IEcsWorldComponent<WhereCache<TExecutor>>
|
||||
//{
|
||||
// private readonly SparseArray<int, TExecutor> _pairs
|
||||
//}
|
||||
// Это не подохидт
|
||||
internal readonly struct WhereQueryCache<TExecutor, TAspcet> : IEcsWorldComponent<WhereQueryCache<TExecutor, TAspcet>>
|
||||
where TExecutor : EcsQueryExecutor, new()
|
||||
where TExecutor : MaskQueryExecutor, new()
|
||||
where TAspcet : EcsAspect, new()
|
||||
{
|
||||
public readonly TExecutor Executor;
|
||||
@ -52,8 +47,8 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
void IEcsWorldComponent<WhereQueryCache<TExecutor, TAspcet>>.Init(ref WhereQueryCache<TExecutor, TAspcet> component, EcsWorld world)
|
||||
{
|
||||
TExecutor instance = new TExecutor();
|
||||
TAspcet aspect = world.GetAspect<TAspcet>();
|
||||
TExecutor instance = world.GetExecutorForMask<TExecutor>(aspect.Mask);
|
||||
instance.Initialize(world, aspect.Mask);
|
||||
component = new WhereQueryCache<TExecutor, TAspcet>(instance, aspect);
|
||||
}
|
||||
|
@ -73,6 +73,34 @@ namespace DCFApixels.DragonECS
|
||||
private List<IEcsWorldEventListener> _listeners = new List<IEcsWorldEventListener>();
|
||||
private List<IEcsEntityEventListener> _entityListeners = new List<IEcsEntityEventListener>();
|
||||
|
||||
|
||||
private static Stack<EcsWorldConfig> _configInitOnlynStack = new Stack<EcsWorldConfig>(4);
|
||||
protected internal static EcsWorldConfig Config_InitOnly
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_configInitOnlynStack.TryPeek(out EcsWorldConfig result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
Throw.UndefinedException();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private readonly ref struct ConfigInitOnlyScope
|
||||
{
|
||||
private readonly Stack<EcsWorldConfig> _stack;
|
||||
public ConfigInitOnlyScope(Stack<EcsWorldConfig> stack, EcsWorldConfig config)
|
||||
{
|
||||
_stack = stack;
|
||||
_stack.Push(config);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
_stack.Peek();
|
||||
}
|
||||
}
|
||||
|
||||
#region Properties
|
||||
EcsWorld IEntityStorage.World
|
||||
{
|
||||
@ -143,6 +171,8 @@ namespace DCFApixels.DragonECS
|
||||
lock (_worldLock)
|
||||
{
|
||||
if (configs == null) { configs = ConfigContainer.Empty; }
|
||||
_configInitOnlynStack.Push(configs.GetWorldConfigOrDefault());
|
||||
|
||||
bool nullWorld = this is NullWorld;
|
||||
if (nullWorld == false && worldID == NULL_WORLD_ID)
|
||||
{
|
||||
@ -164,6 +194,7 @@ namespace DCFApixels.DragonECS
|
||||
if (_worlds[worldID] != null)
|
||||
{
|
||||
_worldIdDispenser.Release(worldID);
|
||||
_configInitOnlynStack.Pop();
|
||||
Throw.Exception("The world with the specified ID has already been created\r\n");
|
||||
}
|
||||
}
|
||||
@ -181,6 +212,8 @@ namespace DCFApixels.DragonECS
|
||||
_entityDispenser = new IdDispenser(entitiesCapacity, 0, OnEntityDispenserResized);
|
||||
|
||||
GetComponentTypeID<NullComponent>();
|
||||
|
||||
_configInitOnlynStack.Pop();
|
||||
}
|
||||
}
|
||||
public void Destroy()
|
||||
@ -231,7 +264,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void GetQueryCache<TExecutor, TAspect>(out TExecutor executor, out TAspect aspect)
|
||||
where TExecutor : EcsQueryExecutor, new()
|
||||
where TExecutor : MaskQueryExecutor, new()
|
||||
where TAspect : EcsAspect, new()
|
||||
{
|
||||
ref var cmp = ref Get<WhereQueryCache<TExecutor, TAspect>>();
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using DCFApixels.DragonECS.Core;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
#if ENABLE_IL2CPP
|
||||
using Unity.IL2CPP.CompilerServices;
|
||||
@ -10,16 +11,16 @@ namespace DCFApixels.DragonECS.Internal
|
||||
[Il2CppSetOption(Option.NullChecks, false)]
|
||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||
#endif
|
||||
internal class EcsWhereExecutor : EcsQueryExecutor
|
||||
internal class EcsWhereExecutor : MaskQueryExecutor
|
||||
{
|
||||
private EcsMaskIterator _iterator;
|
||||
|
||||
private int[] _filteredAllEntities = new int[32];
|
||||
private int _filteredAllEntitiesCount = 0;
|
||||
private long _version;
|
||||
|
||||
private int[] _filteredEntities = null;
|
||||
private int _filteredEntitiesCount = 0;
|
||||
|
||||
private long _version;
|
||||
private WorldStateVersionsChecker _versionsChecker;
|
||||
|
||||
#region Properties
|
||||
@ -28,6 +29,11 @@ namespace DCFApixels.DragonECS.Internal
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _version; }
|
||||
}
|
||||
public sealed override bool IsCached
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _versionsChecker.Check(); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OnInitialize/OnDestroy
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using DCFApixels.DragonECS.Core;
|
||||
using System.Runtime.CompilerServices;
|
||||
#if ENABLE_IL2CPP
|
||||
using Unity.IL2CPP.CompilerServices;
|
||||
#endif
|
||||
@ -9,14 +10,14 @@ namespace DCFApixels.DragonECS.Internal
|
||||
[Il2CppSetOption(Option.NullChecks, false)]
|
||||
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
|
||||
#endif
|
||||
internal class EcsWhereToGroupExecutor : EcsQueryExecutor
|
||||
internal class EcsWhereToGroupExecutor : MaskQueryExecutor
|
||||
{
|
||||
private EcsMaskIterator _iterator;
|
||||
private EcsGroup _filteredAllGroup;
|
||||
private long _version;
|
||||
|
||||
private EcsGroup _filteredAllGroup;
|
||||
private EcsGroup _filteredGroup;
|
||||
|
||||
private long _version;
|
||||
private WorldStateVersionsChecker _versionsChecker;
|
||||
|
||||
#region Properties
|
||||
@ -25,6 +26,11 @@ namespace DCFApixels.DragonECS.Internal
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _version; }
|
||||
}
|
||||
public sealed override bool IsCached
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _versionsChecker.Check(); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OnInitialize/OnDestroy
|
||||
|
@ -8,21 +8,40 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
public partial class EcsWorld
|
||||
{
|
||||
private readonly Dictionary<(Type, object), EcsQueryExecutor> _executorCoures = new Dictionary<(Type, object), EcsQueryExecutor>(256);
|
||||
public TExecutor GetExecutor<TExecutor>(IComponentMask mask)
|
||||
where TExecutor : EcsQueryExecutor, new()
|
||||
private readonly Dictionary<(Type, object), IQueryExecutorImplementation> _executorCoures = new Dictionary<(Type, object), IQueryExecutorImplementation>(Config_InitOnly.PoolComponentsCapacity);
|
||||
public TExecutor GetExecutorForMask<TExecutor>(IComponentMask gmask)
|
||||
where TExecutor : MaskQueryExecutor, new()
|
||||
{
|
||||
var coreType = typeof(TExecutor);
|
||||
if (_executorCoures.TryGetValue((coreType, mask), out EcsQueryExecutor core) == false)
|
||||
//проверяет ключ по абстрактной маске
|
||||
if (_executorCoures.TryGetValue((coreType, gmask), out IQueryExecutorImplementation executor) == false)
|
||||
{
|
||||
core = new TExecutor();
|
||||
core.Initialize(this, mask.ToMask(this));
|
||||
_executorCoures.Add((coreType, mask), core);
|
||||
var mask = gmask.ToMask(this);
|
||||
//проверяет ключ по конкретной маске, или что конкретная и абстрактая одна и таже
|
||||
if (mask == gmask ||
|
||||
_executorCoures.TryGetValue((coreType, mask), out executor) == false)
|
||||
{
|
||||
TExecutor newCore = new TExecutor();
|
||||
newCore.Initialize(this, mask);
|
||||
executor = newCore;
|
||||
}
|
||||
return (TExecutor)core;
|
||||
_executorCoures.Add((coreType, gmask), executor);
|
||||
}
|
||||
return (TExecutor)executor;
|
||||
}
|
||||
}
|
||||
public abstract class EcsQueryExecutor
|
||||
}
|
||||
|
||||
namespace DCFApixels.DragonECS.Core
|
||||
{
|
||||
public interface IQueryExecutorImplementation
|
||||
{
|
||||
EcsWorld World { get; }
|
||||
long Version { get; }
|
||||
bool IsCached { get; }
|
||||
void Destroy();
|
||||
}
|
||||
public abstract class MaskQueryExecutor : IQueryExecutorImplementation
|
||||
{
|
||||
private EcsWorld _source;
|
||||
private EcsMask _mask;
|
||||
@ -42,13 +61,14 @@ namespace DCFApixels.DragonECS
|
||||
get { return _mask; }
|
||||
}
|
||||
public abstract long Version { get; }
|
||||
public abstract bool IsCached { get; }
|
||||
internal void Initialize(EcsWorld world, EcsMask mask)
|
||||
{
|
||||
_source = world;
|
||||
_mask = mask;
|
||||
OnInitialize();
|
||||
}
|
||||
internal void Destroy()
|
||||
void IQueryExecutorImplementation.Destroy()
|
||||
{
|
||||
OnDestroy();
|
||||
_source = null;
|
@ -40,7 +40,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
if (ReferenceEquals(entities, entities.World))
|
||||
{
|
||||
var executor = entities.World.GetExecutor<EcsWhereExecutor>(mask);
|
||||
var executor = entities.World.GetExecutorForMask<EcsWhereExecutor>(mask);
|
||||
return executor.Execute();
|
||||
}
|
||||
return entities.ToSpan().Where(mask);
|
||||
@ -51,7 +51,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public static EcsSpan Where(this EcsSpan span, IComponentMask mask)
|
||||
{
|
||||
var executor = span.World.GetExecutor<EcsWhereExecutor>(mask);
|
||||
var executor = span.World.GetExecutorForMask<EcsWhereExecutor>(mask);
|
||||
return executor.ExecuteFor(span);
|
||||
}
|
||||
#endregion
|
||||
@ -85,7 +85,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
if (ReferenceEquals(entities, entities.World))
|
||||
{
|
||||
EcsWhereExecutor executor = entities.World.GetExecutor<EcsWhereExecutor>(mask);
|
||||
EcsWhereExecutor executor = entities.World.GetExecutorForMask<EcsWhereExecutor>(mask);
|
||||
return executor.Execute(comparison);
|
||||
}
|
||||
return entities.ToSpan().Where(mask, comparison);
|
||||
@ -96,7 +96,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public static EcsSpan Where(this EcsSpan span, IComponentMask mask, Comparison<int> comparison)
|
||||
{
|
||||
var executor = span.World.GetExecutor<EcsWhereExecutor>(mask);
|
||||
var executor = span.World.GetExecutorForMask<EcsWhereExecutor>(mask);
|
||||
return executor.ExecuteFor(span);
|
||||
}
|
||||
#endregion
|
||||
@ -130,7 +130,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
if (ReferenceEquals(entities, entities.World))
|
||||
{
|
||||
EcsWhereToGroupExecutor executor = entities.World.GetExecutor<EcsWhereToGroupExecutor>(mask);
|
||||
EcsWhereToGroupExecutor executor = entities.World.GetExecutorForMask<EcsWhereToGroupExecutor>(mask);
|
||||
return executor.Execute();
|
||||
}
|
||||
return entities.ToSpan().WhereToGroup(mask);
|
||||
@ -141,7 +141,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public static EcsReadonlyGroup WhereToGroup(this EcsSpan span, IComponentMask mask)
|
||||
{
|
||||
var executor = span.World.GetExecutor<EcsWhereToGroupExecutor>(mask);
|
||||
var executor = span.World.GetExecutorForMask<EcsWhereToGroupExecutor>(mask);
|
||||
return executor.ExecuteFor(span);
|
||||
}
|
||||
#endregion
|
||||
|
Loading…
Reference in New Issue
Block a user