From a0e359bb1236d5e7c367e27b545c34fd0ffab6c1 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 2 Oct 2024 22:13:10 +0800 Subject: [PATCH] stash --- notes.txt.meta | 7 + src/DebugUtils/TypeMeta.cs | 8 +- src/EcsAspect.cs | 4 +- src/EcsMask.cs | 316 ++++++++++++++---- src/EcsWorld.cache.cs | 12 +- src/EcsWorld.cs | 13 +- src/EcsWorld.pools.cs | 24 +- src/Executors/EcsQueryExecutor.cs | 22 +- src/Executors/EcsWhereExecutor.cs | 18 +- src/Executors/EcsWhereToGroupExecutor.cs | 16 +- src/Executors/Queries.cs | 10 +- .../{EcsTypeCode.cs => EcsTypeCodeManager.cs} | 18 +- ...ode.cs.meta => EcsTypeCodeManager.cs.meta} | 0 src/Utils/EcsTypeCode.cs | 4 + src/Utils/EcsTypeCode.cs.meta | 11 + src/Utils/Exceptions.cs | 5 + 16 files changed, 364 insertions(+), 124 deletions(-) create mode 100644 notes.txt.meta rename src/Internal/{EcsTypeCode.cs => EcsTypeCodeManager.cs} (76%) rename src/Internal/{EcsTypeCode.cs.meta => EcsTypeCodeManager.cs.meta} (100%) create mode 100644 src/Utils/EcsTypeCode.cs create mode 100644 src/Utils/EcsTypeCode.cs.meta diff --git a/notes.txt.meta b/notes.txt.meta new file mode 100644 index 0000000..8a9ec6e --- /dev/null +++ b/notes.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e1e8de2a01be77f42b72fd7ba8c81570 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index 0361196..c4aaf96 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -57,7 +57,7 @@ namespace DCFApixels.DragonECS private MetaGroup _group; private IReadOnlyList _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(), _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; diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index a6abe1f..00d2d98 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -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(int order = 0) where TOtherAspect : EcsAspect, new() { diff --git a/src/EcsMask.cs b/src/EcsMask.cs index 0b03864..7c4d3ba 100644 --- a/src/EcsMask.cs +++ b/src/EcsMask.cs @@ -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 + { + private static ConcurrentDictionary _ids = new ConcurrentDictionary(); + private static IdDispenser _idDIspenser = new IdDispenser(nullID: 0); + private static object _lock = new object(); + + private readonly int _id; + /// Sorted + private readonly EcsTypeCode[] _inc; + /// Sorted + private readonly EcsTypeCode[] _exc; + + #region Properties + public int ID + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _id; } + } + /// Sorted set including constraints presented as global type codes. + public ReadOnlySpan IncTypeCodes + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _inc; } + } + /// Sorted set excluding constraints presented as global type codes. + public ReadOnlySpan ExcTypeCodes + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _exc; } + } + #endregion + + #region Constrcutors + public static Builder New() { return new Builder(); } + public static Builder Inc() { return new Builder().Inc(); } + public static Builder Exc() { return new Builder().Exc(); } + 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 + { + 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 _inc = new HashSet(); + private readonly HashSet _exc = new HashSet(); + + #region Constrcutors + internal Builder() { } + #endregion + + #region Include/Exclude/Combine + public Builder Inc() { return Inc(EcsTypeCodeManager.Get()); } + public Builder Exc() { return Exc(EcsTypeCodeManager.Get()); } + 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 combinedIncs = _inc; + HashSet 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 + /// Sorted + internal readonly int[] _inc; + /// Sorted + 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); } } - /// Including constraints + /// Sorted set including constraints. public ReadOnlySpan Inc { + [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _inc; } } - /// Excluding constraints + /// Sorted set excluding constraints. public ReadOnlySpan 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().ConvertFromAbstract(abstractMask); + } + #endregion + #region Builder private readonly struct WorldMaskComponent : IEcsWorldComponent { private readonly EcsWorld _world; private readonly Dictionary _masks; private readonly Dictionary _opMasks; + private readonly SparseArray _abstractMasks; public readonly EcsMask EmptyMask; public readonly EcsMask BrokenMask; #region Constructor/Destructor - public WorldMaskComponent(EcsWorld world, Dictionary masks, Dictionary opMasks, EcsMask emptyMask, EcsMask brokenMask) + public WorldMaskComponent(EcsWorld world, Dictionary masks, EcsMask emptyMask, EcsMask brokenMask) { _world = world; _masks = masks; - _opMasks = opMasks; + _opMasks = new Dictionary(256); + _abstractMasks = new SparseArray(256); EmptyMask = emptyMask; BrokenMask = brokenMask; } public void Init(ref WorldMaskComponent component, EcsWorld world) { var masks = new Dictionary(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(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() - { - return Include(_world.GetComponentTypeID()); - } - public Builder Exclude() - { - return Exclude(_world.GetComponentTypeID()); - } - 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() { return Inc(); } + [Obsolete("Use Exc(type)")] public Builder Exclude() { return Exc(); } + [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() { return Inc(_world.GetComponentTypeID()); } + public Builder Exc() { return Exc(_world.GetComponentTypeID()); } + 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; } @@ -950,4 +1138,4 @@ namespace DCFApixels.DragonECS #endregion } #endregion -} +} \ No newline at end of file diff --git a/src/EcsWorld.cache.cs b/src/EcsWorld.cache.cs index 4a2fafd..086fead 100644 --- a/src/EcsWorld.cache.cs +++ b/src/EcsWorld.cache.cs @@ -32,18 +32,18 @@ namespace DCFApixels.DragonECS component = default; } } - internal readonly struct ExeccutorCache : IEcsWorldComponent> - where T : EcsQueryExecutor, new() + internal readonly struct QueryCache : IEcsWorldComponent> + where T : EcsQueryCache, new() { public readonly T instance; - public ExeccutorCache(T instance) { this.instance = instance; } - void IEcsWorldComponent>.Init(ref ExeccutorCache component, EcsWorld world) + public QueryCache(T instance) { this.instance = instance; } + void IEcsWorldComponent>.Init(ref QueryCache component, EcsWorld world) { T instance = new T(); instance.Initialize(world, world._executorsMediator); - component = new ExeccutorCache(instance); + component = new QueryCache(instance); } - void IEcsWorldComponent>.OnDestroy(ref ExeccutorCache component, EcsWorld world) + void IEcsWorldComponent>.OnDestroy(ref QueryCache component, EcsWorld world) { component = default; } diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 69f5daf..d4db734 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -225,9 +225,9 @@ namespace DCFApixels.DragonECS return Get>().instance; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TExecutor GetExecutor() where TExecutor : EcsQueryExecutor, new() + public TExecutor GetQueryCache() where TExecutor : EcsQueryCache, new() { - return Get>().instance; + return Get>().instance; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -714,6 +714,15 @@ namespace DCFApixels.DragonECS int count = GetComponentTypeIDsFor(entityID, ref _componentIDsBuffer); return new ReadOnlySpan(_componentIDsBuffer, 0, count); } + public void GetComponentPoolsFor(int entityID, List 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 list) { list.Clear(); diff --git a/src/EcsWorld.pools.cs b/src/EcsWorld.pools.cs index 7d32136..3e14724 100644 --- a/src/EcsWorld.pools.cs +++ b/src/EcsWorld.pools.cs @@ -96,19 +96,19 @@ namespace DCFApixels.DragonECS #region ComponentInfo public int GetComponentTypeID() { - return DeclareOrGetComponentTypeID(EcsTypeCode.Get()); + return DeclareOrGetComponentTypeID(EcsTypeCodeManager.Get()); } public int GetComponentTypeID(Type componentType) { - return DeclareOrGetComponentTypeID(EcsTypeCode.Get(componentType)); + return DeclareOrGetComponentTypeID(EcsTypeCodeManager.Get(componentType)); } public bool IsComponentTypeDeclared() { - return _cmpTypeCode_2_CmpTypeIDs.Contains(EcsTypeCode.Get()); + return _cmpTypeCode_2_CmpTypeIDs.Contains((int)EcsTypeCodeManager.Get()); } 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(); + int poolTypeCode = (int)EcsTypeCodeManager.Get(); 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)) { diff --git a/src/Executors/EcsQueryExecutor.cs b/src/Executors/EcsQueryExecutor.cs index c7fff67..00a78ea 100644 --- a/src/Executors/EcsQueryExecutor.cs +++ b/src/Executors/EcsQueryExecutor.cs @@ -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(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(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; diff --git a/src/Executors/EcsWhereExecutor.cs b/src/Executors/EcsWhereExecutor.cs index 55b6cce..eab1a37 100644 --- a/src/Executors/EcsWhereExecutor.cs +++ b/src/Executors/EcsWhereExecutor.cs @@ -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 : EcsQueryExecutor where TAspect : EcsAspect, new() + public sealed class EcsWhereCache : 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(); - _core = Mediator.GetCore(_aspect.Mask); + _executor = Mediator.GetCore(_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 comparison) { - return _core.Execute(comparison); + return _executor.Execute(comparison); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public EcsSpan ExecuteFor(EcsSpan span, Comparison comparison) { - return _core.ExecuteFor(span, comparison); + return _executor.ExecuteFor(span, comparison); } #endregion } diff --git a/src/Executors/EcsWhereToGroupExecutor.cs b/src/Executors/EcsWhereToGroupExecutor.cs index 0389ef7..893e01c 100644 --- a/src/Executors/EcsWhereToGroupExecutor.cs +++ b/src/Executors/EcsWhereToGroupExecutor.cs @@ -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 : EcsQueryExecutor where TAspect : EcsAspect, new() + public sealed class EcsWhereToGroupCache : 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(); - _core = Mediator.GetCore(_aspect.Mask); + _executor = Mediator.GetCore(_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 } diff --git a/src/Executors/Queries.cs b/src/Executors/Queries.cs index bbc4015..d518e8d 100644 --- a/src/Executors/Queries.cs +++ b/src/Executors/Queries.cs @@ -24,10 +24,14 @@ namespace DCFApixels.DragonECS where TAspect : EcsAspect, new() { EcsWorld world = span.World; - var executor = world.GetExecutor>(); + var executor = world.GetQueryCache>(); aspect = executor.Aspect; return executor.ExecuteFor(span); } + //public static EcsSpan Where(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>(); + var executor = world.GetQueryCache>(); 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>(); + var executor = world.GetQueryCache>(); aspect = executor.Aspect; return executor.ExecuteFor(span); } diff --git a/src/Internal/EcsTypeCode.cs b/src/Internal/EcsTypeCodeManager.cs similarity index 76% rename from src/Internal/EcsTypeCode.cs rename to src/Internal/EcsTypeCodeManager.cs index e7bb23e..931ad4f 100644 --- a/src/Internal/EcsTypeCode.cs +++ b/src/Internal/EcsTypeCodeManager.cs @@ -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 _codes = new Dictionary(); + private static readonly Dictionary _codes = new Dictionary(); 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() { return EcsTypeCodeCache.code; } + public static EcsTypeCode Get() { return EcsTypeCodeCache.code; } public static bool Has(Type type) { return _codes.ContainsKey(type); } public static bool Has() { return _codes.ContainsKey(typeof(T)); } public static IEnumerable GetDeclaredTypes() { return _codes.Select(o => new TypeCodeInfo(o.Key, o.Value)); } @@ -46,7 +46,7 @@ namespace DCFApixels.DragonECS.Internal #endif internal static class EcsTypeCodeCache { - 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; diff --git a/src/Internal/EcsTypeCode.cs.meta b/src/Internal/EcsTypeCodeManager.cs.meta similarity index 100% rename from src/Internal/EcsTypeCode.cs.meta rename to src/Internal/EcsTypeCodeManager.cs.meta diff --git a/src/Utils/EcsTypeCode.cs b/src/Utils/EcsTypeCode.cs new file mode 100644 index 0000000..c487938 --- /dev/null +++ b/src/Utils/EcsTypeCode.cs @@ -0,0 +1,4 @@ +namespace DCFApixels.DragonECS +{ + public enum EcsTypeCode : int { } +} diff --git a/src/Utils/EcsTypeCode.cs.meta b/src/Utils/EcsTypeCode.cs.meta new file mode 100644 index 0000000..24a5919 --- /dev/null +++ b/src/Utils/EcsTypeCode.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b21f5b69a0fc3b447b93b34ef4377dbf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Utils/Exceptions.cs b/src/Utils/Exceptions.cs index 881ddfb..2ae2591 100644 --- a/src/Utils/Exceptions.cs +++ b/src/Utils/Exceptions.cs @@ -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) {