diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index adb37b3..a65d555 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -123,10 +123,10 @@ namespace DCFApixels.DragonECS foreach (var item in _combined) { EcsMask submask = item.aspect.mask; - maskInc.ExceptWith(submask._exc);//удаляю конфликтующие ограничения - maskExc.ExceptWith(submask._inc);//удаляю конфликтующие ограничения - maskInc.UnionWith(submask._inc); - maskExc.UnionWith(submask._exc); + maskInc.ExceptWith(submask.exc);//удаляю конфликтующие ограничения + maskExc.ExceptWith(submask.inc);//удаляю конфликтующие ограничения + maskInc.UnionWith(submask.inc); + maskExc.UnionWith(submask.exc); } maskInc.ExceptWith(_exc);//удаляю конфликтующие ограничения maskExc.ExceptWith(_inc);//удаляю конфликтующие ограничения @@ -144,7 +144,7 @@ namespace DCFApixels.DragonECS var exc = maskExc.ToArray(); Array.Sort(exc); - mask = new EcsMask(_world.WorldTypeID, inc, exc); + mask = new EcsMask(_world.id, inc, exc); _world = null; _inc = null; _exc = null; @@ -202,24 +202,23 @@ namespace DCFApixels.DragonECS [DebuggerTypeProxy(typeof(DebuggerProxy))] public sealed class EcsMask { - internal readonly int _worldTypeID; + internal readonly int worldID; /// Including constraints - internal readonly int[] _inc; + internal readonly int[] inc; /// Excluding constraints - internal readonly int[] _exc; - internal EcsMask(int worldTypeID, int[] inc, int[] exc) + internal readonly int[] exc; + internal EcsMask(int worldID, int[] inc, int[] exc) { #if DEBUG - if (worldTypeID == 0) throw new ArgumentException(); CheckConstraints(inc, exc); #endif - _worldTypeID = worldTypeID; - _inc = inc; - _exc = exc; + this.worldID = worldID; + this.inc = inc; + this.exc = exc; } #region Object - public override string ToString() => CreateLogString(_worldTypeID, _inc, _exc); + public override string ToString() => CreateLogString(worldID, inc, exc); #endregion #region Debug utils @@ -247,10 +246,10 @@ namespace DCFApixels.DragonECS return false; } #endif - private static string CreateLogString(int worldTypeID, int[] inc, int[] exc) + private static string CreateLogString(int worldID, int[] inc, int[] exc) { #if (DEBUG && !DISABLE_DEBUG) - string converter(int o) => EcsDebugUtility.GetGenericTypeName(WorldMetaStorage.GetComponentType(worldTypeID, o), 1); + string converter(int o) => EcsDebugUtility.GetGenericTypeName(EcsWorld.GetWorld(worldID).AllPools[o].ComponentType, 1); return $"Inc({string.Join(", ", inc.Select(converter))}) Exc({string.Join(", ", exc.Select(converter))})"; #else return $"Inc({string.Join(", ", inc)}) Exc({string.Join(", ", exc)})"; // Release optimization @@ -259,22 +258,22 @@ namespace DCFApixels.DragonECS internal class DebuggerProxy { public readonly Type worldType; - public readonly int worldTypeID; + public readonly int worldID; public readonly int[] included; public readonly int[] excluded; public readonly Type[] includedTypes; public readonly Type[] excludedTypes; public DebuggerProxy(EcsMask mask) { - worldType = WorldMetaStorage.GetWorldType(mask._worldTypeID); - worldTypeID = mask._worldTypeID; - included = mask._inc; - excluded = mask._exc; - Type converter(int o) => WorldMetaStorage.GetComponentType(worldTypeID, o); + worldType = WorldMetaStorage.GetWorldType(mask.worldID); + worldID = mask.worldID; + included = mask.inc; + excluded = mask.exc; + Type converter(int o) => WorldMetaStorage.GetComponentType(worldID, o); includedTypes = included.Select(converter).ToArray(); excludedTypes = excluded.Select(converter).ToArray(); } - public override string ToString() => CreateLogString(worldTypeID, included, excluded); + public override string ToString() => CreateLogString(worldID, included, excluded); } #endregion } @@ -338,8 +337,8 @@ namespace DCFApixels.DragonECS public Enumerator(EcsReadonlyGroup sourceGroup, EcsMask mask) { _sourceGroup = sourceGroup.GetEnumerator(); - _inc = mask._inc; - _exc = mask._exc; + _inc = mask.inc; + _exc = mask.exc; _pools = sourceGroup.World._pools; } public int Current diff --git a/src/EcsWorld.cache.cs b/src/EcsWorld.cache.cs new file mode 100644 index 0000000..56ae21c --- /dev/null +++ b/src/EcsWorld.cache.cs @@ -0,0 +1,40 @@ +using DCFApixels.DragonECS.Utils; +using System; + +namespace DCFApixels.DragonECS +{ + public partial class EcsWorld + { + internal readonly struct PoolCache : IEcsWorldComponent> + where TPool : IEcsPoolImplementation, new() + { + public readonly TPool instance; + public PoolCache(TPool instance) => this.instance = instance; + void IEcsWorldComponent>.Init(ref PoolCache component, EcsWorld world) + { + component = new PoolCache(world.CreatePool()); + } + void IEcsWorldComponent>.OnDestroy(ref PoolCache component, EcsWorld world) + { + component = default; + } + } + private TPool CreatePool() where TPool : IEcsPoolImplementation, new() + { + int index = WorldMetaStorage.GetPoolID(_worldTypeID); + if (index >= _pools.Length) + { + int oldCapacity = _pools.Length; + Array.Resize(ref _pools, _pools.Length << 1); + ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length); + } + if (_pools[index] == _nullPool) + { + var pool = new TPool(); + _pools[index] = pool; + pool.OnInit(this, index); + } + return (TPool)_pools[index]; + } + } +} diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 6e8e334..d3f2c21 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -3,6 +3,7 @@ using DCFApixels.DragonECS.Utils; using System; using System.Collections.Generic; using System.Runtime.CompilerServices; +using typecode = System.Int32; namespace DCFApixels.DragonECS { @@ -102,22 +103,10 @@ namespace DCFApixels.DragonECS #if UNITY_2020_3_OR_NEWER [UnityEngine.Scripting.Preserve] #endif + [MethodImpl(MethodImplOptions.AggressiveInlining)] public TPool GetPool() where TPool : IEcsPoolImplementation, new() { - int index = WorldMetaStorage.GetPoolID(_worldTypeID); - if (index >= _pools.Length) - { - int oldCapacity = _pools.Length; - Array.Resize(ref _pools, _pools.Length << 1); - ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length); - } - if (_pools[index] == _nullPool) - { - var pool = new TPool(); - _pools[index] = pool; - pool.OnInit(this, index); - } - return (TPool)_pools[index]; + return Get>().instance; } public TAspect GetAspect() where TAspect : EcsAspect { @@ -236,17 +225,17 @@ namespace DCFApixels.DragonECS public bool IsMatchesMask(EcsMask mask, int entityID) { #if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (mask._worldTypeID != _worldTypeID) + if (mask.worldID != id) throw new EcsFrameworkException("The types of the target world of the mask and this world are different."); #endif - for (int i = 0, iMax = mask._inc.Length; i < iMax; i++) + for (int i = 0, iMax = mask.inc.Length; i < iMax; i++) { - if (!_pools[mask._inc[i]].Has(entityID)) + if (!_pools[mask.inc[i]].Has(entityID)) return false; } - for (int i = 0, iMax = mask._exc.Length; i < iMax; i++) + for (int i = 0, iMax = mask.exc.Length; i < iMax; i++) { - if (_pools[mask._exc[i]].Has(entityID)) + if (_pools[mask.exc[i]].Has(entityID)) return false; } return true; diff --git a/src/Utils/EcsTypeCodeCache.cs b/src/Utils/EcsTypeCodeCache.cs new file mode 100644 index 0000000..c60c241 --- /dev/null +++ b/src/Utils/EcsTypeCodeCache.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; + +namespace DCFApixels.DragonECS +{ + namespace Internal + { + internal static class EcsTypeCode + { + private static readonly Dictionary _codes = new Dictionary(); + private static int _incremetn = 1; + public static int GetCode(Type type) + { + if (!_codes.TryGetValue(type, out int code)) + { + code = _incremetn++; + _codes.Add(type, code); + } + return code; + } + public static int Count => _codes.Count; + } + internal static class EcsTypeCodeCache + { + public static readonly int code = EcsTypeCode.GetCode(typeof(T)); + } + } +}