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