This commit is contained in:
Mikhail 2024-10-02 22:13:10 +08:00
parent 5bebf812f1
commit a0e359bb12
16 changed files with 364 additions and 124 deletions

7
notes.txt.meta Normal file
View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e1e8de2a01be77f42b72fd7ba8c81570
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -57,7 +57,7 @@ namespace DCFApixels.DragonECS
private MetaGroup _group;
private IReadOnlyList<string> _tags;
private string _metaID;
private int _typeCode;
private EcsTypeCode _typeCode;
private InitFlag _initFlags = InitFlag.None;
@ -77,7 +77,7 @@ namespace DCFApixels.DragonECS
_group = new MetaGroup(""),
_tags = Array.Empty<string>(),
_metaID = string.Empty,
_typeCode = EcsTypeCode.Get(typeof(void)),
_typeCode = EcsTypeCodeManager.Get(typeof(void)),
_initFlags = InitFlag.All,
};
@ -250,13 +250,13 @@ namespace DCFApixels.DragonECS
#endregion
#region TypeCode
public int TypeCode
public EcsTypeCode TypeCode
{
get
{
if (_initFlags.HasFlag(InitFlag.TypeCode) == false)
{
_typeCode = EcsTypeCode.Get(_type);
_typeCode = EcsTypeCodeManager.Get(_type);
_initFlags |= InitFlag.TypeCode;
}
return _typeCode;

View File

@ -166,11 +166,11 @@ namespace DCFApixels.DragonECS
}
private void IncludeImplicit(Type type)
{
_maskBuilder.Include(type);
_maskBuilder.Inc(type);
}
private void ExcludeImplicit(Type type)
{
_maskBuilder.Exclude(type);
_maskBuilder.Exc(type);
}
public TOtherAspect Combine<TOtherAspect>(int order = 0) where TOtherAspect : EcsAspect, new()
{

View File

@ -1,14 +1,188 @@
using DCFApixels.DragonECS.Internal;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
#if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices;
#endif
namespace DCFApixels.DragonECS
{
#if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices;
[Il2CppSetOption (Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
public sealed class EcsStaticMask : IEquatable<EcsStaticMask>
{
private static ConcurrentDictionary<Key, EcsStaticMask> _ids = new ConcurrentDictionary<Key, EcsStaticMask>();
private static IdDispenser _idDIspenser = new IdDispenser(nullID: 0);
private static object _lock = new object();
private readonly int _id;
/// <summary> Sorted </summary>
private readonly EcsTypeCode[] _inc;
/// <summary> Sorted </summary>
private readonly EcsTypeCode[] _exc;
#region Properties
public int ID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _id; }
}
/// <summary> Sorted set including constraints presented as global type codes. </summary>
public ReadOnlySpan<EcsTypeCode> IncTypeCodes
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _inc; }
}
/// <summary> Sorted set excluding constraints presented as global type codes. </summary>
public ReadOnlySpan<EcsTypeCode> ExcTypeCodes
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _exc; }
}
#endregion
#region Constrcutors
public static Builder New() { return new Builder(); }
public static Builder Inc<T>() { return new Builder().Inc<T>(); }
public static Builder Exc<T>() { return new Builder().Exc<T>(); }
private EcsStaticMask(int id, Key key)
{
_id = id;
_inc = key.inc;
_exc = key.exc;
}
#endregion
#region Methods
public EcsMask ToMask(EcsWorld world)
{
return EcsMask.FromStatic(world, this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(EcsStaticMask other) { return _id == other._id; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() { return _id; }
public override bool Equals(object obj) { return Equals((EcsStaticMask)obj); }
public override string ToString() { return $"s_mask({_id})"; }
#endregion
#region Builder
private readonly struct Key : IEquatable<Key>
{
public readonly EcsTypeCode[] inc;
public readonly EcsTypeCode[] exc;
public readonly int hash;
#region Constructors
public Key(EcsTypeCode[] inc, EcsTypeCode[] exc)
{
this.inc = inc;
this.exc = exc;
unchecked
{
hash = inc.Length + exc.Length;
for (int i = 0, iMax = inc.Length; i < iMax; i++)
{
hash = hash * EcsConsts.MAGIC_PRIME + (int)inc[i];
}
for (int i = 0, iMax = exc.Length; i < iMax; i++)
{
hash = hash * EcsConsts.MAGIC_PRIME - (int)exc[i];
}
}
}
#endregion
#region Object
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Key other)
{
if (inc.Length != other.inc.Length) { return false; }
if (exc.Length != other.exc.Length) { return false; }
for (int i = 0; i < inc.Length; i++)
{
if (inc[i] != other.inc[i]) { return false; }
}
for (int i = 0; i < exc.Length; i++)
{
if (exc[i] != other.exc[i]) { return false; }
}
return true;
}
public override bool Equals(object obj) { return Equals((Key)obj); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() { return hash; }
#endregion
}
public class Builder
{
private readonly HashSet<EcsTypeCode> _inc = new HashSet<EcsTypeCode>();
private readonly HashSet<EcsTypeCode> _exc = new HashSet<EcsTypeCode>();
#region Constrcutors
internal Builder() { }
#endregion
#region Include/Exclude/Combine
public Builder Inc<T>() { return Inc(EcsTypeCodeManager.Get<T>()); }
public Builder Exc<T>() { return Exc(EcsTypeCodeManager.Get<T>()); }
public Builder Inc(Type type) { return Inc(EcsTypeCodeManager.Get(type)); }
public Builder Exc(Type type) { return Exc(EcsTypeCodeManager.Get(type)); }
public Builder Inc(EcsTypeCode typeCode)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_inc.Contains(typeCode) || _exc.Contains(typeCode)) { Throw.ConstraintIsAlreadyContainedInMask(); }
#endif
_inc.Add(typeCode);
return this;
}
public Builder Exc(EcsTypeCode typeCode)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_inc.Contains(typeCode) || _exc.Contains(typeCode)) { Throw.ConstraintIsAlreadyContainedInMask(); }
#endif
_exc.Add(typeCode);
return this;
}
#endregion
#region Build
public EcsStaticMask Build()
{
HashSet<EcsTypeCode> combinedIncs = _inc;
HashSet<EcsTypeCode> combinedExcs = _exc;
var inc = combinedIncs.ToArray();
Array.Sort(inc);
var exc = combinedExcs.ToArray();
Array.Sort(exc);
var key = new Key(inc, exc);
if (_ids.TryGetValue(key, out EcsStaticMask result) == false)
{
lock (_lock)
{
if (_ids.TryGetValue(key, out result) == false)
{
result = new EcsStaticMask(_idDIspenser.UseFree(), key);
_ids[key] = result;
}
}
}
return result;
}
#endregion
}
#endregion
}
#if ENABLE_IL2CPP
[Il2CppSetOption (Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
@ -19,36 +193,44 @@ namespace DCFApixels.DragonECS
internal readonly short _worldID;
internal readonly EcsMaskChunck[] _incChunckMasks;
internal readonly EcsMaskChunck[] _excChunckMasks;
internal readonly int[] _inc; //Sorted
internal readonly int[] _exc; //Sorted
/// <summary> Sorted </summary>
internal readonly int[] _inc;
/// <summary> Sorted </summary>
internal readonly int[] _exc;
private EcsMaskIterator _iterator;
#region Properties
public int ID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _id; }
}
public short WorldID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _worldID; }
}
public EcsWorld World
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return EcsWorld.GetWorld(_worldID); }
}
/// <summary>Including constraints</summary>
/// <summary> Sorted set including constraints. </summary>
public ReadOnlySpan<int> Inc
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _inc; }
}
/// <summary>Excluding constraints</summary>
/// <summary> Sorted set excluding constraints. </summary>
public ReadOnlySpan<int> Exc
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _exc; }
}
public bool IsEmpty
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _inc.Length == 0 && _exc.Length == 0; }
}
public bool IsBroken
@ -58,32 +240,28 @@ namespace DCFApixels.DragonECS
#endregion
#region Constructors
public static Builder New(EcsWorld world)
{
return new Builder(world);
}
internal static EcsMask New(int id, short worldID, int[] inc, int[] exc)
public static Builder New(EcsWorld world) { return new Builder(world); }
internal static EcsMask Create(int id, short worldID, int[] inc, int[] exc)
{
#if DEBUG
CheckConstraints(inc, exc);
#endif
return new EcsMask(id, worldID, inc, exc);
}
internal static EcsMask NewEmpty(int id, short worldID)
internal static EcsMask CreateEmpty(int id, short worldID)
{
return new EcsMask(id, worldID, new int[0], new int[0]);
}
internal static EcsMask NewBroken(int id, short worldID)
internal static EcsMask CreateBroken(int id, short worldID)
{
return new EcsMask(id, worldID, new int[1] { 1 }, new int[1] { 1 });
}
private EcsMask(int id, short worldID, int[] inc, int[] exc)
{
this._id = id;
this._inc = inc;
this._exc = exc;
this._worldID = worldID;
_id = id;
_inc = inc;
_exc = exc;
_worldID = worldID;
_incChunckMasks = MakeMaskChuncsArray(inc);
_excChunckMasks = MakeMaskChuncsArray(exc);
@ -343,38 +521,48 @@ namespace DCFApixels.DragonECS
#endregion
#region AbstractMask
public static EcsMask FromStatic(EcsWorld world, EcsStaticMask abstractMask)
{
return world.Get<WorldMaskComponent>().ConvertFromAbstract(abstractMask);
}
#endregion
#region Builder
private readonly struct WorldMaskComponent : IEcsWorldComponent<WorldMaskComponent>
{
private readonly EcsWorld _world;
private readonly Dictionary<Key, EcsMask> _masks;
private readonly Dictionary<OpMaskKey, EcsMask> _opMasks;
private readonly SparseArray<EcsMask> _abstractMasks;
public readonly EcsMask EmptyMask;
public readonly EcsMask BrokenMask;
#region Constructor/Destructor
public WorldMaskComponent(EcsWorld world, Dictionary<Key, EcsMask> masks, Dictionary<OpMaskKey, EcsMask> opMasks, EcsMask emptyMask, EcsMask brokenMask)
public WorldMaskComponent(EcsWorld world, Dictionary<Key, EcsMask> masks, EcsMask emptyMask, EcsMask brokenMask)
{
_world = world;
_masks = masks;
_opMasks = opMasks;
_opMasks = new Dictionary<OpMaskKey, EcsMask>(256);
_abstractMasks = new SparseArray<EcsMask>(256);
EmptyMask = emptyMask;
BrokenMask = brokenMask;
}
public void Init(ref WorldMaskComponent component, EcsWorld world)
{
var masks = new Dictionary<Key, EcsMask>(256);
EcsMask emptyMask = NewEmpty(0, world.id);
EcsMask brokenMask = NewBroken(1, world.id);
EcsMask emptyMask = CreateEmpty(0, world.id);
EcsMask brokenMask = CreateBroken(1, world.id);
masks.Add(new Key(emptyMask._inc, emptyMask._exc), emptyMask);
masks.Add(new Key(brokenMask._inc, brokenMask._exc), brokenMask);
component = new WorldMaskComponent(world, masks, new Dictionary<OpMaskKey, EcsMask>(256), emptyMask, brokenMask);
component = new WorldMaskComponent(world, masks, emptyMask, brokenMask);
}
public void OnDestroy(ref WorldMaskComponent component, EcsWorld world)
{
component._masks.Clear();
component._opMasks.Clear();
component._abstractMasks.Clear();
component = default;
}
#endregion
@ -394,11 +582,29 @@ namespace DCFApixels.DragonECS
}
return result;
}
internal EcsMask ConvertFromAbstract(EcsStaticMask abstractMask)
{
if (_abstractMasks.TryGetValue(abstractMask.ID, out EcsMask result) == false)
{
var b = New(_world);
foreach (var typeCode in abstractMask.IncTypeCodes)
{
b.Inc(_world.DeclareOrGetComponentTypeID(typeCode));
}
foreach (var typeCode in abstractMask.ExcTypeCodes)
{
b.Exc(_world.DeclareOrGetComponentTypeID(typeCode));
}
result = b.Build();
_abstractMasks.Add(abstractMask.ID, result);
}
return result;
}
internal EcsMask GetMask(Key maskKey)
{
if (!_masks.TryGetValue(maskKey, out EcsMask result))
if (_masks.TryGetValue(maskKey, out EcsMask result) == false)
{
result = New(_masks.Count, _world.id, maskKey.inc, maskKey.exc);
result = Create(_masks.Count, _world.id, maskKey.inc, maskKey.exc);
_masks.Add(maskKey, result);
}
return result;
@ -435,30 +641,19 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Key other)
{
if (inc.Length != other.inc.Length)
{
return false;
}
if (exc.Length != other.exc.Length)
{
return false;
}
if (inc.Length != other.inc.Length) { return false; }
if (exc.Length != other.exc.Length) { return false; }
for (int i = 0; i < inc.Length; i++)
{
if (inc[i] != other.inc[i])
{
return false;
}
if (inc[i] != other.inc[i]) { return false; }
}
for (int i = 0; i < exc.Length; i++)
{
if (exc[i] != other.exc[i])
{
return false;
}
if (exc[i] != other.exc[i]) { return false; }
}
return true;
}
public override bool Equals(object obj) { return Equals((Key)obj); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() { return hash; }
#endregion
@ -479,38 +674,31 @@ namespace DCFApixels.DragonECS
}
#endregion
#region Include/Exclude/Combine
public Builder Include<T>()
{
return Include(_world.GetComponentTypeID<T>());
}
public Builder Exclude<T>()
{
return Exclude(_world.GetComponentTypeID<T>());
}
public Builder Include(Type type)
{
return Include(_world.GetComponentTypeID(type));
}
public Builder Exclude(Type type)
{
return Exclude(_world.GetComponentTypeID(type));
}
#region Inc/Exc/Combine
[Obsolete("Use Inc(type)")] public Builder Include<T>() { return Inc<T>(); }
[Obsolete("Use Exc(type)")] public Builder Exclude<T>() { return Exc<T>(); }
[Obsolete("Use Inc(type)")] public Builder Include(Type type) { return Inc(type); }
[Obsolete("Use Exc(type)")] public Builder Exclude(Type type) { return Exc(type); }
public Builder Include(int compponentTypeID)
public Builder Inc<T>() { return Inc(_world.GetComponentTypeID<T>()); }
public Builder Exc<T>() { return Exc(_world.GetComponentTypeID<T>()); }
public Builder Inc(Type type) { return Inc(_world.GetComponentTypeID(type)); }
public Builder Exc(Type type) { return Exc(_world.GetComponentTypeID(type)); }
public Builder Inc(int componentTypeID)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_inc.Contains(compponentTypeID) || _exc.Contains(compponentTypeID)) Throw.ConstraintIsAlreadyContainedInMask(_world.GetComponentType(compponentTypeID));
if (_inc.Contains(componentTypeID) || _exc.Contains(componentTypeID)) { Throw.ConstraintIsAlreadyContainedInMask(_world.GetComponentType(componentTypeID)); }
#endif
_inc.Add(compponentTypeID);
_inc.Add(componentTypeID);
return this;
}
public Builder Exclude(int compponentTypeID)
public Builder Exc(int componentTypeID)
{
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (_inc.Contains(compponentTypeID) || _exc.Contains(compponentTypeID)) Throw.ConstraintIsAlreadyContainedInMask(_world.GetComponentType(compponentTypeID));
if (_inc.Contains(componentTypeID) || _exc.Contains(componentTypeID)) { Throw.ConstraintIsAlreadyContainedInMask(_world.GetComponentType(componentTypeID)); }
#endif
_exc.Add(compponentTypeID);
_exc.Add(componentTypeID);
return this;
}

View File

@ -32,18 +32,18 @@ namespace DCFApixels.DragonECS
component = default;
}
}
internal readonly struct ExeccutorCache<T> : IEcsWorldComponent<ExeccutorCache<T>>
where T : EcsQueryExecutor, new()
internal readonly struct QueryCache<T> : IEcsWorldComponent<QueryCache<T>>
where T : EcsQueryCache, new()
{
public readonly T instance;
public ExeccutorCache(T instance) { this.instance = instance; }
void IEcsWorldComponent<ExeccutorCache<T>>.Init(ref ExeccutorCache<T> component, EcsWorld world)
public QueryCache(T instance) { this.instance = instance; }
void IEcsWorldComponent<QueryCache<T>>.Init(ref QueryCache<T> component, EcsWorld world)
{
T instance = new T();
instance.Initialize(world, world._executorsMediator);
component = new ExeccutorCache<T>(instance);
component = new QueryCache<T>(instance);
}
void IEcsWorldComponent<ExeccutorCache<T>>.OnDestroy(ref ExeccutorCache<T> component, EcsWorld world)
void IEcsWorldComponent<QueryCache<T>>.OnDestroy(ref QueryCache<T> component, EcsWorld world)
{
component = default;
}

View File

@ -225,9 +225,9 @@ namespace DCFApixels.DragonECS
return Get<AspectCache<TAspect>>().instance;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TExecutor GetExecutor<TExecutor>() where TExecutor : EcsQueryExecutor, new()
public TExecutor GetQueryCache<TExecutor>() where TExecutor : EcsQueryCache, new()
{
return Get<ExeccutorCache<TExecutor>>().instance;
return Get<QueryCache<TExecutor>>().instance;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -714,6 +714,15 @@ namespace DCFApixels.DragonECS
int count = GetComponentTypeIDsFor(entityID, ref _componentIDsBuffer);
return new ReadOnlySpan<int>(_componentIDsBuffer, 0, count);
}
public void GetComponentPoolsFor(int entityID, List<IEcsPool> list)
{
list.Clear();
int count = GetComponentTypeIDsFor(entityID, ref _componentIDsBuffer);
for (int i = 0; i < count; i++)
{
list.Add(_pools[_componentIDsBuffer[i]]);
}
}
public void GetComponentsFor(int entityID, List<object> list)
{
list.Clear();

View File

@ -96,19 +96,19 @@ namespace DCFApixels.DragonECS
#region ComponentInfo
public int GetComponentTypeID<TComponent>()
{
return DeclareOrGetComponentTypeID(EcsTypeCode.Get<TComponent>());
return DeclareOrGetComponentTypeID(EcsTypeCodeManager.Get<TComponent>());
}
public int GetComponentTypeID(Type componentType)
{
return DeclareOrGetComponentTypeID(EcsTypeCode.Get(componentType));
return DeclareOrGetComponentTypeID(EcsTypeCodeManager.Get(componentType));
}
public bool IsComponentTypeDeclared<TComponent>()
{
return _cmpTypeCode_2_CmpTypeIDs.Contains(EcsTypeCode.Get<TComponent>());
return _cmpTypeCode_2_CmpTypeIDs.Contains((int)EcsTypeCodeManager.Get<TComponent>());
}
public bool IsComponentTypeDeclared(Type componentType)
{
return _cmpTypeCode_2_CmpTypeIDs.Contains(EcsTypeCode.Get(componentType));
return _cmpTypeCode_2_CmpTypeIDs.Contains((int)EcsTypeCodeManager.Get(componentType));
}
public bool IsComponentTypeDeclared(int componentTypeID)
{
@ -125,21 +125,21 @@ namespace DCFApixels.DragonECS
#endregion
#region Declare
private int DeclareOrGetComponentTypeID(int componentTypeCode)
internal int DeclareOrGetComponentTypeID(EcsTypeCode componentTypeCode)
{
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue(componentTypeCode, out int ComponentTypeID) == false)
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue((int)componentTypeCode, out int ComponentTypeID) == false)
{
ComponentTypeID = _poolsCount++;
_cmpTypeCode_2_CmpTypeIDs.Add(componentTypeCode, ComponentTypeID);
_cmpTypeCode_2_CmpTypeIDs.Add((int)componentTypeCode, ComponentTypeID);
}
return ComponentTypeID;
}
private bool TryDeclareComponentTypeID(int componentTypeCode, out int componentTypeID)
internal bool TryDeclareComponentTypeID(EcsTypeCode componentTypeCode, out int componentTypeID)
{
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue(componentTypeCode, out componentTypeID) == false)
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue((int)componentTypeCode, out componentTypeID) == false)
{
componentTypeID = _poolsCount++;
_cmpTypeCode_2_CmpTypeIDs.Add(componentTypeCode, componentTypeID);
_cmpTypeCode_2_CmpTypeIDs.Add((int)componentTypeCode, componentTypeID);
return true;
}
return false;
@ -151,7 +151,7 @@ namespace DCFApixels.DragonECS
{
lock (_worldLock)
{
int poolTypeCode = EcsTypeCode.Get<TPool>();
int poolTypeCode = (int)EcsTypeCodeManager.Get<TPool>();
if (_poolTypeCode_2_CmpTypeIDs.Contains(poolTypeCode))
{
Throw.World_PoolAlreadyCreated();
@ -169,7 +169,7 @@ namespace DCFApixels.DragonECS
}
#pragma warning restore IL2090 // 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The generic parameter of the source method or type does not have matching annotations.
#endif
int componentTypeCode = EcsTypeCode.Get(componentType);
int componentTypeCode = (int)EcsTypeCodeManager.Get(componentType);
if (_cmpTypeCode_2_CmpTypeIDs.TryGetValue(componentTypeCode, out int componentTypeID))
{

View File

@ -6,7 +6,7 @@ namespace DCFApixels.DragonECS
{
public partial class EcsWorld
{
private readonly Dictionary<(Type, EcsMask), EcsQueryExecutorCore> _executorCoures = new Dictionary<(Type, EcsMask), EcsQueryExecutorCore>();
private readonly Dictionary<(Type, object), EcsQueryExecutor> _executorCoures = new Dictionary<(Type, object), EcsQueryExecutor>(256);
private readonly ExecutorMediator _executorsMediator;
public readonly struct ExecutorMediator
{
@ -20,10 +20,10 @@ namespace DCFApixels.DragonECS
World = world;
}
public TExecutorCore GetCore<TExecutorCore>(EcsMask mask)
where TExecutorCore : EcsQueryExecutorCore, new()
where TExecutorCore : EcsQueryExecutor, new()
{
var coreType = typeof(TExecutorCore);
if (World._executorCoures.TryGetValue((coreType, mask), out EcsQueryExecutorCore core) == false)
if (World._executorCoures.TryGetValue((coreType, mask), out EcsQueryExecutor core) == false)
{
core = new TExecutorCore();
core.Initialize(World, mask);
@ -31,9 +31,21 @@ namespace DCFApixels.DragonECS
}
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;
}
}
public abstract class EcsQueryExecutorCore
}
public abstract class EcsQueryExecutor
{
private EcsWorld _source;
private EcsMask _mask;
@ -66,7 +78,7 @@ namespace DCFApixels.DragonECS
protected abstract void OnInitialize();
protected abstract void OnDestroy();
}
public abstract class EcsQueryExecutor
public abstract class EcsQueryCache
{
private EcsWorld _source;
private EcsWorld.ExecutorMediator _mediator;

View File

@ -11,7 +11,7 @@ namespace DCFApixels.DragonECS.Internal
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
internal class EcsWhereExecutorCore : EcsQueryExecutorCore
internal class EcsWhereExecutor : EcsQueryExecutor
{
private EcsMaskIterator _iterator;
private int[] _filteredAllEntities = new int[32];
@ -104,10 +104,10 @@ namespace DCFApixels.DragonECS
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
public sealed class EcsWhereExecutor<TAspect> : EcsQueryExecutor where TAspect : EcsAspect, new()
public sealed class EcsWhereCache<TAspect> : EcsQueryCache where TAspect : EcsAspect, new()
{
private TAspect _aspect;
private EcsWhereExecutorCore _core;
private EcsWhereExecutor _executor;
#region Properties
public TAspect Aspect
@ -118,7 +118,7 @@ namespace DCFApixels.DragonECS
public sealed override long Version
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _core.Version; }
get { return _executor.Version; }
}
#endregion
@ -126,7 +126,7 @@ namespace DCFApixels.DragonECS
protected sealed override void OnInitialize()
{
_aspect = World.GetAspect<TAspect>();
_core = Mediator.GetCore<EcsWhereExecutorCore>(_aspect.Mask);
_executor = Mediator.GetCore<EcsWhereExecutor>(_aspect.Mask);
}
protected sealed override void OnDestroy() { }
#endregion
@ -135,22 +135,22 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Execute()
{
return _core.Execute();
return _executor.Execute();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ExecuteFor(EcsSpan span)
{
return _core.ExecuteFor(span);
return _executor.ExecuteFor(span);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Execute(Comparison<int> comparison)
{
return _core.Execute(comparison);
return _executor.Execute(comparison);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ExecuteFor(EcsSpan span, Comparison<int> comparison)
{
return _core.ExecuteFor(span, comparison);
return _executor.ExecuteFor(span, comparison);
}
#endregion
}

View File

@ -10,7 +10,7 @@ namespace DCFApixels.DragonECS.Internal
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
internal class EcsWhereToGroupExecutorCore : EcsQueryExecutorCore
internal class EcsWhereToGroupExecutor : EcsQueryExecutor
{
private EcsMaskIterator _iterator;
private EcsGroup _filteredAllGroup;
@ -90,10 +90,10 @@ namespace DCFApixels.DragonECS
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
public sealed class EcsWhereToGroupExecutor<TAspect> : EcsQueryExecutor where TAspect : EcsAspect, new()
public sealed class EcsWhereToGroupCache<TAspect> : EcsQueryCache where TAspect : EcsAspect, new()
{
private TAspect _aspect;
private EcsWhereToGroupExecutorCore _core;
private EcsWhereToGroupExecutor _executor;
#region Properties
public TAspect Aspect
@ -104,7 +104,7 @@ namespace DCFApixels.DragonECS
public sealed override long Version
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _core.Version; }
get { return _executor.Version; }
}
#endregion
@ -112,11 +112,11 @@ namespace DCFApixels.DragonECS
protected sealed override void OnInitialize()
{
_aspect = World.GetAspect<TAspect>();
_core = Mediator.GetCore<EcsWhereToGroupExecutorCore>(_aspect.Mask);
_executor = Mediator.GetCore<EcsWhereToGroupExecutor>(_aspect.Mask);
}
protected sealed override void OnDestroy()
{
_core.Destroy();
_executor.Destroy();
}
#endregion
@ -124,12 +124,12 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup Execute()
{
return _core.Execute();
return _executor.Execute();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup ExecuteFor(EcsSpan span)
{
return _core.ExecuteFor(span);
return _executor.ExecuteFor(span);
}
#endregion
}

View File

@ -24,10 +24,14 @@ namespace DCFApixels.DragonECS
where TAspect : EcsAspect, new()
{
EcsWorld world = span.World;
var executor = world.GetExecutor<EcsWhereExecutor<TAspect>>();
var executor = world.GetQueryCache<EcsWhereCache<TAspect>>();
aspect = executor.Aspect;
return executor.ExecuteFor(span);
}
//public static EcsSpan Where<TCollection>(this TCollection entities, EcsStaticMask mask)
//{
//
//}
#endregion
#region Where with sort
@ -46,7 +50,7 @@ namespace DCFApixels.DragonECS
where TAspect : EcsAspect, new()
{
EcsWorld world = span.World;
var executor = world.GetExecutor<EcsWhereExecutor<TAspect>>();
var executor = world.GetQueryCache<EcsWhereCache<TAspect>>();
aspect = executor.Aspect;
return executor.ExecuteFor(span, comparison);
}
@ -68,7 +72,7 @@ namespace DCFApixels.DragonECS
where TAspect : EcsAspect, new()
{
EcsWorld world = span.World;
var executor = world.GetExecutor<EcsWhereToGroupExecutor<TAspect>>();
var executor = world.GetQueryCache<EcsWhereToGroupCache<TAspect>>();
aspect = executor.Aspect;
return executor.ExecuteFor(span);
}

View File

@ -12,9 +12,9 @@ namespace DCFApixels.DragonECS.Internal
[Il2CppSetOption(Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
internal static class EcsTypeCode
internal static class EcsTypeCodeManager
{
private static readonly Dictionary<Type, int> _codes = new Dictionary<Type, int>();
private static readonly Dictionary<Type, EcsTypeCode> _codes = new Dictionary<Type, EcsTypeCode>();
private static int _increment = 1;
private static object _lock = new object();
public static int Count
@ -22,20 +22,20 @@ namespace DCFApixels.DragonECS.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _codes.Count; }
}
public static int Get(Type type)
public static EcsTypeCode Get(Type type)
{
lock (_lock)
{
if (!_codes.TryGetValue(type, out int code))
if (!_codes.TryGetValue(type, out EcsTypeCode code))
{
code = _increment++;
code = (EcsTypeCode)_increment++;
_codes.Add(type, code);
}
return code;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Get<T>() { return EcsTypeCodeCache<T>.code; }
public static EcsTypeCode Get<T>() { return EcsTypeCodeCache<T>.code; }
public static bool Has(Type type) { return _codes.ContainsKey(type); }
public static bool Has<T>() { return _codes.ContainsKey(typeof(T)); }
public static IEnumerable<TypeCodeInfo> GetDeclaredTypes() { return _codes.Select(o => new TypeCodeInfo(o.Key, o.Value)); }
@ -46,7 +46,7 @@ namespace DCFApixels.DragonECS.Internal
#endif
internal static class EcsTypeCodeCache<T>
{
public static readonly int code = EcsTypeCode.Get(typeof(T));
public static readonly EcsTypeCode code = EcsTypeCodeManager.Get(typeof(T));
}
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
@ -55,8 +55,8 @@ namespace DCFApixels.DragonECS.Internal
internal struct TypeCodeInfo
{
public Type type;
public int code;
public TypeCodeInfo(Type type, int code)
public EcsTypeCode code;
public TypeCodeInfo(Type type, EcsTypeCode code)
{
this.type = type;
this.code = code;

4
src/Utils/EcsTypeCode.cs Normal file
View File

@ -0,0 +1,4 @@
namespace DCFApixels.DragonECS
{
public enum EcsTypeCode : int { }
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b21f5b69a0fc3b447b93b34ef4377dbf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -37,6 +37,11 @@ namespace DCFApixels.DragonECS.Internal
{
internal static class Throw
{
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ConstraintIsAlreadyContainedInMask()
{
throw new EcsFrameworkException($"The constraint is already contained in the mask.");
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ConstraintIsAlreadyContainedInMask(Type type)
{