From 8f8571a6467c035a7cf8e0e74aca5ddbdc3de01c Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 27 May 2023 09:06:10 +0800 Subject: [PATCH 1/7] Change generic constraints --- src/EcsSubject.cs | 6 +++--- src/EcsWorld.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EcsSubject.cs b/src/EcsSubject.cs index 9e096ed..beb2df8 100644 --- a/src/EcsSubject.cs +++ b/src/EcsSubject.cs @@ -127,9 +127,9 @@ namespace DCFApixels.DragonECS #region BuilderBase public abstract class EcsSubjectBuilderBase { - public abstract TPool Include() where TComponent : struct where TPool : IEcsPoolImplementation, new(); - public abstract TPool Exclude() where TComponent : struct where TPool : IEcsPoolImplementation, new(); - public abstract TPool Optional() where TComponent : struct where TPool : IEcsPoolImplementation, new(); + public abstract TPool Include() where TPool : IEcsPoolImplementation, new(); + public abstract TPool Exclude() where TPool : IEcsPoolImplementation, new(); + public abstract TPool Optional() where TPool : IEcsPoolImplementation, new(); } #endregion diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 690a5d9..011e480 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -121,7 +121,7 @@ namespace DCFApixels.DragonECS #endregion #region GetPool - public TPool GetPool() where TComponent : struct where TPool : IEcsPoolImplementation, new() + public TPool GetPool() where TPool : IEcsPoolImplementation, new() { int uniqueID = WorldMetaStorage.GetComponentId(_worldTypeID); From 1b8cf0f0e98f420ec145c3bda37bcd20d0d8c270 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 27 May 2023 15:59:46 +0800 Subject: [PATCH 2/7] refactoring --- src/Builtin/InjectSystem.cs | 3 -- src/Debug/EcsDebug.cs | 9 ++++- src/EcsGroup.cs | 5 ++- src/EcsWorld.cs | 58 ++++++------------------------- src/Executors/EcsQueryExecutor.cs | 8 +++++ src/Executors/EcsWhereExecutor.cs | 48 +++++++++++++++++-------- 6 files changed, 61 insertions(+), 70 deletions(-) diff --git a/src/Builtin/InjectSystem.cs b/src/Builtin/InjectSystem.cs index e387514..b4f9151 100644 --- a/src/Builtin/InjectSystem.cs +++ b/src/Builtin/InjectSystem.cs @@ -4,9 +4,6 @@ using System.Linq; namespace DCFApixels.DragonECS { - //TODO развить идею инжектов - //добавить контейнер, который автоматически создается, собирает в себя все пре-инжекты и авто-инжектится во все системы. - //но это спорная идея public interface IEcsPreInject : IEcsSystem { void PreInject(object obj); diff --git a/src/Debug/EcsDebug.cs b/src/Debug/EcsDebug.cs index 1e29074..57bbc1e 100644 --- a/src/Debug/EcsDebug.cs +++ b/src/Debug/EcsDebug.cs @@ -36,7 +36,14 @@ namespace DCFApixels.DragonECS public static void Set(DebugService service) => DebugService.Set(service); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Print(object v) => DebugService.Instance.Print(v); + public static void PrintWarning(object v) => Print(EcsConsts.DEBUG_WARNING_TAG, v); + public static void PrintError(object v) => Print(EcsConsts.DEBUG_ERROR_TAG, v); + public static void Print(object v) + { +#if !DISABLE_DRAGONECS_DEBUGGER + DebugService.Instance.Print(v); +#endif + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Print(string tag, object v) { diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs index c7126d9..2bb9460 100644 --- a/src/EcsGroup.cs +++ b/src/EcsGroup.cs @@ -219,12 +219,11 @@ namespace DCFApixels.DragonECS } #endregion - #region Sort/Clear - //public void Sort() { } //TODO прошлай реализация сортировки не удачная, так как в dense могут храниться занчения больше чем dense.Length + #region Clear public void Clear() { _count = 0; - //массив _dense нет смысла очищать, испольщуется только область от 1 до _count + //массив _dense нет смысла очищать for (int i = 0; i < _sparse.Length; i++) _sparse[i] = 0; } diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 011e480..e5ff6e6 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -26,9 +26,6 @@ namespace DCFApixels.DragonECS private short[] _componentCounts; private EcsGroup _allEntites; - //буфер удаления откладывает освобождение андишников сущностей. - //Нужен для того чтобы запускать некоторые процесыы связанные с удалением сущности не по одному при каждом удалении, а пачкой - //В теории такой подход частично улучшает ситуацию с переполнением поколений private int[] _delEntBuffer; private int _delEntBufferCount; @@ -138,7 +135,6 @@ namespace DCFApixels.DragonECS _pools[uniqueID] = pool; pool.OnInit(this, uniqueID); _poolsCount++; - //EcsDebug.Print(pool.GetType().FullName); } return (TPool)_pools[uniqueID]; @@ -158,39 +154,39 @@ namespace DCFApixels.DragonECS #endregion #region Queries - public TExecutor GetExecutor(Func builder) where TExecutor: EcsQueryExecutor + public TExecutor GetExecutor() where TExecutor : EcsQueryExecutor, new() { int id = WorldMetaStorage.GetExecutorId(_worldTypeID); if (id >= _executors.Length) Array.Resize(ref _executors, _executors.Length << 1); if (_executors[id] == null) - _executors[id] = builder(this); + { + var executor = new TExecutor(); + executor.Initialize(this); + _executors[id] = executor; + } return (TExecutor)_executors[id]; } - private EcsWhereExecutor EcsWhereExecutorBuilder(EcsWorld world) where TSubject : EcsSubject - { - return new EcsWhereExecutor(world.GetSubject()); - } public EcsWhereResult WhereFor(EcsReadonlyGroup sourceGroup, out TSubject subject) where TSubject : EcsSubject { - var executor = GetExecutor(EcsWhereExecutorBuilder); + var executor = GetExecutor>(); subject = executor.Subject; return executor.ExecuteFor(sourceGroup); } public EcsWhereResult WhereFor(EcsReadonlyGroup sourceGroup) where TSubject : EcsSubject { - return GetExecutor(EcsWhereExecutorBuilder).ExecuteFor(sourceGroup); + return GetExecutor>().ExecuteFor(sourceGroup); } public EcsWhereResult Where(out TSubject subject) where TSubject : EcsSubject { - var executor = GetExecutor(EcsWhereExecutorBuilder); + var executor = GetExecutor>(); subject = executor.Subject; return executor.Execute(); } public EcsWhereResult Where() where TSubject : EcsSubject { - return GetExecutor(EcsWhereExecutorBuilder).Execute(); + return GetExecutor>().Execute(); } #endregion @@ -369,40 +365,6 @@ namespace DCFApixels.DragonECS break; } } - - // public int GetComponents(int entity, ref object[] list) - // { - // var entityOffset = GetRawEntityOffset(entity); - // var itemsCount = _entities[entityOffset + RawEntityOffsets.ComponentsCount]; - // if (itemsCount == 0) { return 0; } - // if (list == null || list.Length < itemsCount) - // { - // list = new object[_pools.Length]; - // } - // var dataOffset = entityOffset + RawEntityOffsets.Components; - // for (var i = 0; i < itemsCount; i++) - // { - // list[i] = _pools[_entities[dataOffset + i]].GetRaw(entity); - // } - // return itemsCount; - // } - - // public int GetComponentTypes(int entity, ref Type[] list) - // { - // var entityOffset = GetRawEntityOffset(entity); - // var itemsCount = _entities[entityOffset + RawEntityOffsets.ComponentsCount]; - // if (itemsCount == 0) { return 0; } - // if (list == null || list.Length < itemsCount) - // { - // list = new Type[_pools.Length]; - // } - // var dataOffset = entityOffset + RawEntityOffsets.Components; - // for (var i = 0; i < itemsCount; i++) - // { - // list[i] = _pools[_entities[dataOffset + i]].GetComponentType(); - // } - // return itemsCount; - // } #endregion } diff --git a/src/Executors/EcsQueryExecutor.cs b/src/Executors/EcsQueryExecutor.cs index 8b8534e..ad6db0b 100644 --- a/src/Executors/EcsQueryExecutor.cs +++ b/src/Executors/EcsQueryExecutor.cs @@ -2,6 +2,14 @@ { public abstract class EcsQueryExecutor { + private EcsWorld _world; + public EcsWorld World => _world; + internal void Initialize(EcsWorld world) + { + _world = world; + OnInitialize(); + } + protected abstract void OnInitialize(); internal void Destroy() => OnDestroy(); protected abstract void OnDestroy(); } diff --git a/src/Executors/EcsWhereExecutor.cs b/src/Executors/EcsWhereExecutor.cs index c7ccc97..db88c69 100644 --- a/src/Executors/EcsWhereExecutor.cs +++ b/src/Executors/EcsWhereExecutor.cs @@ -1,26 +1,28 @@ -using Unity.Profiling; - -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS { public sealed class EcsWhereExecutor : EcsQueryExecutor where TSubject : EcsSubject { - private readonly TSubject _subject; - private readonly EcsGroup _filteredGroup; + private TSubject _subject; + private EcsGroup _filteredGroup; private long _executeVersion; - private ProfilerMarker _executeWhere = new ProfilerMarker("JoinAttachQuery.Where"); + private EcsProfilerMarker _executeWhere = new EcsProfilerMarker("Where"); #region Properties public TSubject Subject => _subject; internal long ExecuteVersion => _executeVersion; #endregion - #region Constructors - public EcsWhereExecutor(TSubject subject) + #region OnInitialize/OnDestroy + protected sealed override void OnInitialize() { - _subject = subject; - _filteredGroup = EcsGroup.New(subject.World); + _subject = World.GetSubject(); + _filteredGroup = EcsGroup.New(World); + } + protected sealed override void OnDestroy() + { + _filteredGroup.Release(); } #endregion @@ -33,14 +35,30 @@ namespace DCFApixels.DragonECS #if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS if (sourceGroup.IsNull) throw new System.ArgumentNullException();//TODO составить текст исключения. #endif - _subject.GetIteratorFor(sourceGroup).CopyTo(_filteredGroup); + //_subject.GetIteratorFor(sourceGroup).CopyTo(_filteredGroup); + + var pools = _subject.World._pools; + var mask = _subject.Mask; + _filteredGroup.Clear(); + foreach (var e in sourceGroup) + { + for (int i = 0, iMax = mask._inc.Length; i < iMax; i++) + { + if (!pools[mask._inc[i]].Has(e)) + goto next; + } + for (int i = 0, iMax = mask._exc.Length; i < iMax; i++) + { + if (pools[mask._exc[i]].Has(e)) + goto next; + } + _filteredGroup.AddInternal(e); + next: continue; + } + return new EcsWhereResult(this, _filteredGroup.Readonly); } } - protected sealed override void OnDestroy() - { - _filteredGroup.Release(); - } #endregion } From 77286fc00c1e09b9265cf12a48b3eb22b79d33b3 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 27 May 2023 22:15:25 +0800 Subject: [PATCH 3/7] update world meta/update mask debuging --- src/EcsSubject.cs | 34 ++++++++++++++++++++++-- src/EcsWorld.cs | 68 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/EcsSubject.cs b/src/EcsSubject.cs index beb2df8..1dfcd45 100644 --- a/src/EcsSubject.cs +++ b/src/EcsSubject.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; +using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; @@ -134,6 +136,7 @@ namespace DCFApixels.DragonECS #endregion #region Mask + [DebuggerTypeProxy(typeof(DebuggerProxy))] public sealed class EcsMask { internal readonly Type _worldType; @@ -145,9 +148,36 @@ namespace DCFApixels.DragonECS _inc = inc; _exc = exc; } - public override string ToString() + public override string ToString() => CreateLogString(_worldType, _inc, _exc); + private static string CreateLogString(Type worldType, int[] inc, int[] exc) { - return $"Inc({string.Join(", ", _inc)}) Exc({string.Join(", ", _exc)})"; +#if DEBUG + int worldID = WorldMetaStorage.GetWorldID(worldType); + string converter(int o) => EcsDebugUtility.GetGenericTypeName(WorldMetaStorage.GetComponentType(worldID, o), 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 +#endif + } + + internal class DebuggerProxy + { + public readonly Type worldType; + public readonly int[] inc; + public readonly int[] exc; + public readonly Type[] incTypes; + public readonly Type[] excTypes; + public DebuggerProxy(EcsMask mask) + { + worldType = mask._worldType; + int worldID = WorldMetaStorage.GetWorldID(worldType); + inc = mask._inc; + exc = mask._exc; + Type converter(int o) => WorldMetaStorage.GetComponentType(worldID, o); + incTypes = inc.Select(converter).ToArray(); + excTypes = exc.Select(converter).ToArray(); + } + public override string ToString() => CreateLogString(worldType, inc, exc); } } #endregion diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index e5ff6e6..c9f833b 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -72,7 +72,7 @@ namespace DCFApixels.DragonECS Worlds[uniqueID] = this; } - _worldTypeID = WorldMetaStorage.GetWorldId(Archetype); + _worldTypeID = WorldMetaStorage.GetWorldID(Archetype); _entityDispenser = new IntDispenser(0); _nullPool = EcsNullPool.instance; @@ -376,31 +376,33 @@ namespace DCFApixels.DragonECS internal EcsWorld(bool isIndexable) : base(isIndexable) { } } - #region Utils + #region WorldMetaStorage public static class WorldMetaStorage { private static List _resizer = new List(); private static int _tokenCount = 0; - private static int[] _componentCounts = new int[0]; - private static int[] _subjectsCounts = new int[0]; + + private static WorldMeta[] _metas = new WorldMeta[0]; private static Dictionary _worldIds = new Dictionary(); private static class WorldIndex { - public static int id = GetWorldId(typeof(TWorldArchetype)); + public static int id = GetWorldID(typeof(TWorldArchetype)); } private static int GetToken() { - _tokenCount++; - Array.Resize(ref _componentCounts, _tokenCount); - Array.Resize(ref _subjectsCounts, _tokenCount); + WorldMeta meta = new WorldMeta(); + meta.id = _tokenCount; + Array.Resize(ref _metas, ++_tokenCount); + _metas[_tokenCount - 1] = meta; + foreach (var item in _resizer) item.Resize(_tokenCount); return _tokenCount - 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetWorldId(Type archetype) + public static int GetWorldID(Type archetype) { - if(_worldIds.TryGetValue(archetype, out int id) == false) + if(!_worldIds.TryGetValue(archetype, out int id)) { id = GetToken(); _worldIds.Add(archetype, id); @@ -415,6 +417,11 @@ namespace DCFApixels.DragonECS public static int GetSubjectId(int worldID) => Subject.Get(worldID); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetExecutorId(int worldID) => Executor.Get(worldID); + + public static bool IsComponentTypeDeclared(int worldID, Type type) => _metas[worldID].IsDeclaredType(type); + public static Type GetComponentType(int worldID, int componentID) => _metas[worldID].GetComponentType(componentID); + + #region Resizer private abstract class Resizer { public abstract void Resize(int size); @@ -428,6 +435,7 @@ namespace DCFApixels.DragonECS Array.Resize(ref Executor.ids, size); } } + #endregion private static class Component { public static int[] ids; @@ -443,7 +451,11 @@ namespace DCFApixels.DragonECS { ref int id = ref ids[token]; if (id < 0) - id = _componentCounts[token]++; + { + var meta = _metas[token]; + id = meta.componentCount++; + meta.AddType(id, typeof(T)); + } return id; } } @@ -462,7 +474,7 @@ namespace DCFApixels.DragonECS { ref int id = ref ids[token]; if (id < 0) - id = _subjectsCounts[token]++; + id = _metas[token].subjectsCount++; return id; } } @@ -481,10 +493,40 @@ namespace DCFApixels.DragonECS { ref int id = ref ids[token]; if (id < 0) - id = _subjectsCounts[token]++; + id = _metas[token].executorsCount++; return id; } } + + private class WorldMeta + { + public int id; + + public int componentCount; + public int subjectsCount; + public int executorsCount; + + private Type[] types; + private HashSet declaredComponentTypes; + + public void AddType(int id, Type type) + { + if(types.Length <= id) + Array.Resize(ref types, id + 10); + types[id] = type; + + declaredComponentTypes.Add(type); + } + + public Type GetComponentType(int componentID) => types[componentID]; + public bool IsDeclaredType(Type type) => declaredComponentTypes.Contains(type); + + public WorldMeta() + { + types = new Type[10]; + declaredComponentTypes = new HashSet(); + } + } } #endregion From 5c805ba555cc0a0f57e84a6f401074b78c38e18d Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 27 May 2023 23:02:32 +0800 Subject: [PATCH 4/7] refactoring/add DebuggerProxy to entlong --- src/Builtin/BaseRunners.cs | 8 +++----- src/EcsRunner.cs | 7 +++---- src/EcsSubject.cs | 21 ++++++++++++--------- src/entlong.cs | 38 +++++++++++++++++++++++++++++++++----- 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/Builtin/BaseRunners.cs b/src/Builtin/BaseRunners.cs index 539a849..76ac5db 100644 --- a/src/Builtin/BaseRunners.cs +++ b/src/Builtin/BaseRunners.cs @@ -2,6 +2,7 @@ namespace DCFApixels.DragonECS { + #region Interfaces public interface IEcsPreInitProcess : IEcsSystem { void PreInit(EcsPipeline pipeline); @@ -18,7 +19,8 @@ namespace DCFApixels.DragonECS { void Destroy(EcsPipeline pipeline); } - public interface IEcsBaseSystem : IEcsInitProcess, IEcsRunProcess, IEcsDestroyProcess { } + + #endregion namespace Internal { @@ -40,7 +42,6 @@ namespace DCFApixels.DragonECS foreach (var item in targets) item.PreInit(pipeline); #endif } - #if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { @@ -70,7 +71,6 @@ namespace DCFApixels.DragonECS foreach (var item in targets) item.Init(pipeline); #endif } - #if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { @@ -101,7 +101,6 @@ namespace DCFApixels.DragonECS foreach (var item in targets) item.Run(pipeline); #endif } - #if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { @@ -131,7 +130,6 @@ namespace DCFApixels.DragonECS foreach (var item in targets) item.Destroy(pipeline); #endif } - #if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { diff --git a/src/EcsRunner.cs b/src/EcsRunner.cs index 7fe8745..910e4f3 100644 --- a/src/EcsRunner.cs +++ b/src/EcsRunner.cs @@ -1,7 +1,9 @@ -using System; +using DCFApixels.DragonECS.RunnersCore; +using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; @@ -9,9 +11,6 @@ using static DCFApixels.DragonECS.EcsDebugUtility; namespace DCFApixels.DragonECS { - using RunnersCore; - using System.ComponentModel; - [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] sealed class EcsRunnerFilterAttribute : Attribute { diff --git a/src/EcsSubject.cs b/src/EcsSubject.cs index 1dfcd45..af1e44f 100644 --- a/src/EcsSubject.cs +++ b/src/EcsSubject.cs @@ -148,7 +148,10 @@ namespace DCFApixels.DragonECS _inc = inc; _exc = exc; } + public override string ToString() => CreateLogString(_worldType, _inc, _exc); + + #region Debug utils private static string CreateLogString(Type worldType, int[] inc, int[] exc) { #if DEBUG @@ -159,7 +162,6 @@ namespace DCFApixels.DragonECS return $"Inc({string.Join(", ", inc)}) Exc({string.Join(", ", exc)})"; // Release optimization #endif } - internal class DebuggerProxy { public readonly Type worldType; @@ -179,6 +181,7 @@ namespace DCFApixels.DragonECS } public override string ToString() => CreateLogString(worldType, inc, exc); } + #endregion } #endregion @@ -186,25 +189,25 @@ namespace DCFApixels.DragonECS public ref struct EcsSubjectIterator where TSubject : EcsSubject { public readonly TSubject s; - private EcsReadonlyGroup sourceGroup; - private Enumerator enumerator; + private EcsReadonlyGroup _sourceGroup; + private Enumerator _enumerator; public EcsSubjectIterator(TSubject s, EcsReadonlyGroup sourceGroup) { this.s = s; - this.sourceGroup = sourceGroup; - enumerator = default; + this._sourceGroup = sourceGroup; + _enumerator = default; } public int Entity { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => enumerator.Current; + get => _enumerator.Current; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Begin() => enumerator = GetEnumerator(); + public void Begin() => _enumerator = GetEnumerator(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Next() => enumerator.MoveNext(); + public bool Next() => _enumerator.MoveNext(); public void CopyTo(EcsGroup group) { group.Clear(); @@ -213,7 +216,7 @@ namespace DCFApixels.DragonECS group.AddInternal(enumerator.Current); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Enumerator GetEnumerator() => new Enumerator(sourceGroup, s); + public Enumerator GetEnumerator() => new Enumerator(_sourceGroup, s); public override string ToString() { diff --git a/src/entlong.cs b/src/entlong.cs index 52841b1..bdbca2f 100644 --- a/src/entlong.cs +++ b/src/entlong.cs @@ -1,15 +1,18 @@ #pragma warning disable IDE1006 using System; -using System.ComponentModel; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using static DCFApixels.DragonECS.entlong.ThrowHalper; namespace DCFApixels.DragonECS { - using static entlong.ThrowHalper; // [ id 32 | gen 16 | world 16 ] /// Strong identifier/Permanent entity identifier [StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)] + [DebuggerTypeProxy(typeof(DebuggerProxy))] public readonly struct entlong : IEquatable, IEquatable { public static readonly entlong NULL = default; @@ -34,7 +37,6 @@ namespace DCFApixels.DragonECS get => this == NULL; } - [EditorBrowsable(EditorBrowsableState.Never)] public int ID { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -46,7 +48,6 @@ namespace DCFApixels.DragonECS return id; } } - [EditorBrowsable(EditorBrowsableState.Never)] public short Gen { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -69,7 +70,6 @@ namespace DCFApixels.DragonECS return EcsWorld.Worlds[world]; } } - [EditorBrowsable(EditorBrowsableState.Never)] public short WorldID { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -158,5 +158,33 @@ namespace DCFApixels.DragonECS } } #endregion + + #region DebuggerProxy + internal class DebuggerProxy + { + private List _componentsList; + private entlong _value; + public long full => _value.full; + public int id => _value.id; + public int gen => _value.gen; + public int world => _value.world; + public EntState State => _value.IsNull ? EntState.Null : _value.IsAlive ? EntState.Alive : EntState.Dead; + public EcsWorld EcsWorld => _value.World; + public IEnumerable components + { + get + { + _value.World.GetComponents(_value.ID, _componentsList); + return _componentsList; + } + } + public DebuggerProxy(entlong value) + { + _value = value; + _componentsList = new List(); + } + public enum EntState { Null, Dead, Alive, } + } + #endregion } } From 42a8be73455988b12f38b5d9e772b22b98311981 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 28 May 2023 05:53:08 +0800 Subject: [PATCH 5/7] refactoring --- src/Builtin/Systems.cs | 4 ++-- src/Builtin/Worlds.cs | 4 ---- src/Debug/EcsDebug.cs | 7 ------- src/EcsPipeline.cs | 2 +- src/EcsRunner.cs | 8 ++++---- src/EcsSubject.cs | 19 ++++++++++++++++-- src/EcsWorld.cs | 32 ++++++++++++++----------------- src/Executors/EcsWhereExecutor.cs | 24 +---------------------- src/Pools/EcsPoolBase.cs | 23 +++++++++++----------- src/entlong.cs | 2 -- 10 files changed, 50 insertions(+), 75 deletions(-) diff --git a/src/Builtin/Systems.cs b/src/Builtin/Systems.cs index 15ff527..5f2fc45 100644 --- a/src/Builtin/Systems.cs +++ b/src/Builtin/Systems.cs @@ -6,10 +6,10 @@ namespace DCFApixels.DragonECS namespace Internal { [DebugHide, DebugColor(DebugColor.Black)] - public class SystemsBlockMarkerSystem : IEcsSystem + public class SystemsLayerMarkerSystem : IEcsSystem { public readonly string name; - public SystemsBlockMarkerSystem(string name) => this.name = name; + public SystemsLayerMarkerSystem(string name) => this.name = name; } [DebugHide, DebugColor(DebugColor.Grey)] public class DeleteEmptyEntitesSystem : IEcsRunProcess, IEcsPreInject diff --git a/src/Builtin/Worlds.cs b/src/Builtin/Worlds.cs index 23f26cb..d92e45e 100644 --- a/src/Builtin/Worlds.cs +++ b/src/Builtin/Worlds.cs @@ -1,9 +1,5 @@ namespace DCFApixels.DragonECS { - internal sealed class EcsNullWorld : EcsWorld - { - public EcsNullWorld() : base(false) { } - } public sealed class EcsDefaultWorld : EcsWorld { } public sealed class EcsEventWorld : EcsWorld { } } diff --git a/src/Debug/EcsDebug.cs b/src/Debug/EcsDebug.cs index 57bbc1e..a2f8d2a 100644 --- a/src/Debug/EcsDebug.cs +++ b/src/Debug/EcsDebug.cs @@ -17,7 +17,6 @@ namespace DCFApixels.DragonECS public void End() => EcsDebug.ProfileMarkEnd(id); [MethodImpl(MethodImplOptions.AggressiveInlining)] public AutoScope Auto() => new AutoScope(id); - public readonly ref struct AutoScope { private readonly int _id; @@ -146,7 +145,6 @@ namespace DCFApixels.DragonECS { private Stopwatch[] _stopwatchs; private string[] _stopwatchsNames; - public DefaultDebugService() { #if !DISABLE_DRAGONECS_DEBUGGER @@ -154,17 +152,14 @@ namespace DCFApixels.DragonECS _stopwatchsNames= new string[64]; #endif } - public override void Print(string tag, object v) { Console.WriteLine($"[{tag}] {v}"); } - public override void ProfileMarkBegin(int id) { _stopwatchs[id].Start(); } - public override void ProfileMarkEnd(int id) { _stopwatchs[id].Stop(); @@ -172,12 +167,10 @@ namespace DCFApixels.DragonECS _stopwatchs[id].Reset(); Print(_stopwatchsNames[id] + " s:" + time.TotalSeconds); } - protected override void OnDelMark(int id) { _stopwatchs[id] = null; } - protected override void OnNewMark(int id, string name) { if (id >= _stopwatchs.Length) diff --git a/src/EcsPipeline.cs b/src/EcsPipeline.cs index 2d51e6e..2af0ecd 100644 --- a/src/EcsPipeline.cs +++ b/src/EcsPipeline.cs @@ -182,7 +182,7 @@ namespace DCFApixels.DragonECS List list; if (!_systems.TryGetValue(layerName, out list)) { - list = new List { new SystemsBlockMarkerSystem(layerName.ToString()) }; + list = new List { new SystemsLayerMarkerSystem(layerName.ToString()) }; _systems.Add(layerName, list); } if ((_uniqueTypes.Add(system.GetType()) == false && isUnique)) diff --git a/src/EcsRunner.cs b/src/EcsRunner.cs index 910e4f3..40fd715 100644 --- a/src/EcsRunner.cs +++ b/src/EcsRunner.cs @@ -3,7 +3,6 @@ using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.ComponentModel; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; @@ -28,7 +27,6 @@ namespace DCFApixels.DragonECS namespace RunnersCore { - [EditorBrowsable(EditorBrowsableState.Never)] public interface IEcsRunner { EcsPipeline Source { get; } @@ -121,8 +119,10 @@ namespace DCFApixels.DragonECS EcsRunner.Register(runnerType); } } - [EditorBrowsable(EditorBrowsableState.Never)] - public abstract class EcsRunner : IEcsSystem, IEcsRunner +#if UNITY_2020_3_OR_NEWER + [UnityEngine.Scripting.RequireDerived, UnityEngine.Scripting.Preserve] +#endif + public abstract class EcsRunner : IEcsSystem, IEcsRunner where TInterface : IEcsSystem { #region Register diff --git a/src/EcsSubject.cs b/src/EcsSubject.cs index af1e44f..a1f60b3 100644 --- a/src/EcsSubject.cs +++ b/src/EcsSubject.cs @@ -67,6 +67,7 @@ namespace DCFApixels.DragonECS return (TSubject)newSubject; } + #region Include/Exclude/Optional public sealed override TPool Include() { IncludeImplicit(); @@ -81,7 +82,6 @@ namespace DCFApixels.DragonECS { return _world.GetPool(); } - public void IncludeImplicit() { int id = _world.GetComponentID(); @@ -98,6 +98,7 @@ namespace DCFApixels.DragonECS #endif _exc.Add(_world.GetComponentID()); } + #endregion private void End(out EcsMask mask) { @@ -108,6 +109,20 @@ namespace DCFApixels.DragonECS _inc = null; _exc = null; } + + #region SupportReflectionHack +#if UNITY_2020_3_OR_NEWER + [UnityEngine.Scripting.Preserve] +#endif + private void SupportReflectionHack() where TPool : IEcsPoolImplementation, new() + { + Include(); + Exclude(); + Optional(); + IncludeImplicit(); + ExcludeImplicit(); + } + #endregion } #endregion } @@ -195,7 +210,7 @@ namespace DCFApixels.DragonECS public EcsSubjectIterator(TSubject s, EcsReadonlyGroup sourceGroup) { this.s = s; - this._sourceGroup = sourceGroup; + _sourceGroup = sourceGroup; _enumerator = default; } diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index c9f833b..42d4aab 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -92,7 +92,6 @@ namespace DCFApixels.DragonECS _subjects = new EcsSubject[128]; _executors = new EcsQueryExecutor[128]; } - public void Destroy() { _entityDispenser = null; @@ -106,10 +105,6 @@ namespace DCFApixels.DragonECS Worlds[uniqueID] = null; _worldIdDispenser.Release(uniqueID); } - public void DestryWithPipeline() - { - Destroy(); - } #endregion #region GetComponentID @@ -118,17 +113,18 @@ namespace DCFApixels.DragonECS #endregion #region GetPool +#if UNITY_2020_3_OR_NEWER + [UnityEngine.Scripting.Preserve] +#endif public TPool GetPool() where TPool : IEcsPoolImplementation, new() { int uniqueID = WorldMetaStorage.GetComponentId(_worldTypeID); - if (uniqueID >= _pools.Length) { int oldCapacity = _pools.Length; Array.Resize(ref _pools, _pools.Length << 1); ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length); } - if (_pools[uniqueID] == _nullPool) { var pool = new TPool(); @@ -136,7 +132,6 @@ namespace DCFApixels.DragonECS pool.OnInit(this, uniqueID); _poolsCount++; } - return (TPool)_pools[uniqueID]; } #endregion @@ -167,7 +162,6 @@ namespace DCFApixels.DragonECS } return (TExecutor)_executors[id]; } - public EcsWhereResult WhereFor(EcsReadonlyGroup sourceGroup, out TSubject subject) where TSubject : EcsSubject { var executor = GetExecutor>(); @@ -366,6 +360,13 @@ namespace DCFApixels.DragonECS } } #endregion + + #region NullWorld + private sealed class EcsNullWorld : EcsWorld + { + public EcsNullWorld() : base(false) { } + } + #endregion } public abstract class EcsWorld : EcsWorld @@ -382,7 +383,7 @@ namespace DCFApixels.DragonECS private static List _resizer = new List(); private static int _tokenCount = 0; - private static WorldMeta[] _metas = new WorldMeta[0]; + private static WorldTypeMeta[] _metas = new WorldTypeMeta[0]; private static Dictionary _worldIds = new Dictionary(); private static class WorldIndex { @@ -390,7 +391,7 @@ namespace DCFApixels.DragonECS } private static int GetToken() { - WorldMeta meta = new WorldMeta(); + WorldTypeMeta meta = new WorldTypeMeta(); meta.id = _tokenCount; Array.Resize(ref _metas, ++_tokenCount); _metas[_tokenCount - 1] = meta; @@ -498,17 +499,14 @@ namespace DCFApixels.DragonECS } } - private class WorldMeta + private class WorldTypeMeta { public int id; - public int componentCount; public int subjectsCount; public int executorsCount; - private Type[] types; private HashSet declaredComponentTypes; - public void AddType(int id, Type type) { if(types.Length <= id) @@ -517,11 +515,9 @@ namespace DCFApixels.DragonECS declaredComponentTypes.Add(type); } - public Type GetComponentType(int componentID) => types[componentID]; public bool IsDeclaredType(Type type) => declaredComponentTypes.Contains(type); - - public WorldMeta() + public WorldTypeMeta() { types = new Type[10]; declaredComponentTypes = new HashSet(); diff --git a/src/Executors/EcsWhereExecutor.cs b/src/Executors/EcsWhereExecutor.cs index db88c69..4673825 100644 --- a/src/Executors/EcsWhereExecutor.cs +++ b/src/Executors/EcsWhereExecutor.cs @@ -35,27 +35,7 @@ #if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS if (sourceGroup.IsNull) throw new System.ArgumentNullException();//TODO составить текст исключения. #endif - //_subject.GetIteratorFor(sourceGroup).CopyTo(_filteredGroup); - - var pools = _subject.World._pools; - var mask = _subject.Mask; - _filteredGroup.Clear(); - foreach (var e in sourceGroup) - { - for (int i = 0, iMax = mask._inc.Length; i < iMax; i++) - { - if (!pools[mask._inc[i]].Has(e)) - goto next; - } - for (int i = 0, iMax = mask._exc.Length; i < iMax; i++) - { - if (pools[mask._exc[i]].Has(e)) - goto next; - } - _filteredGroup.AddInternal(e); - next: continue; - } - + _subject.GetIteratorFor(sourceGroup).CopyTo(_filteredGroup); return new EcsWhereResult(this, _filteredGroup.Readonly); } } @@ -70,7 +50,6 @@ public readonly EcsReadonlyGroup group; private readonly long _version; public bool IsRelevant => _version == _executer.ExecuteVersion; - public EcsWhereResult(EcsWhereExecutor executer, EcsReadonlyGroup group) { _executer = executer; @@ -85,7 +64,6 @@ #endif return group.GetEnumerator(); } - public override string ToString() { return group.ToString(); diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs index 2e28565..1628aeb 100644 --- a/src/Pools/EcsPoolBase.cs +++ b/src/Pools/EcsPoolBase.cs @@ -31,15 +31,6 @@ namespace DCFApixels.DragonECS void RemoveListener(IEcsPoolEventListener listener); #endregion } - public interface IEcsPoolEventListener - { - /// Called after adding an entity to the pool, but before changing values. - void OnAdd(int entityID); - /// Is called when EcsPool.Write or EcsPool.Add is called, but before changing values. - void OnWrite(int entityID); - /// Called after deleting an entity from the pool - void OnDel(int entityID); - } public interface IEcsPool { ref T Add(int entityID); @@ -47,7 +38,6 @@ namespace DCFApixels.DragonECS ref T Write(int entityID); } /// Only used to implement a custom pool. In other contexts use IEcsPool or IEcsPool. - /// Component type public interface IEcsPoolImplementation : IEcsPool { void OnInit(EcsWorld world, int componentID); @@ -98,7 +88,7 @@ namespace DCFApixels.DragonECS } } - #region Dummy + #region Dummy EcsNullPool namespace Internal { public struct NullComponent { } @@ -216,7 +206,16 @@ namespace DCFApixels.DragonECS } #endregion - #region Extensions + #region Callbacks Interface + public interface IEcsPoolEventListener + { + /// Called after adding an entity to the pool, but before changing values. + void OnAdd(int entityID); + /// Is called when EcsPool.Write or EcsPool.Add is called, but before changing values. + void OnWrite(int entityID); + /// Called after deleting an entity from the pool + void OnDel(int entityID); + } public static class PoolEventListExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/entlong.cs b/src/entlong.cs index bdbca2f..5ce81df 100644 --- a/src/entlong.cs +++ b/src/entlong.cs @@ -1,6 +1,5 @@ #pragma warning disable IDE1006 using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -36,7 +35,6 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get => this == NULL; } - public int ID { [MethodImpl(MethodImplOptions.AggressiveInlining)] From 72b344b3dda4d6e8fd5264d29b8e4cb5792c27b8 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 28 May 2023 06:29:04 +0800 Subject: [PATCH 6/7] refactoring --- src/Debug/Attributes/DebugColorAttribute.cs | 34 +++------- .../Attributes/DebugDescriptionAttribute.cs | 5 +- src/Debug/Attributes/DebugNameAttribute.cs | 5 +- src/EcsGroup.cs | 67 ++++++++++--------- src/EcsWorld.cs | 8 ++- 5 files changed, 54 insertions(+), 65 deletions(-) diff --git a/src/Debug/Attributes/DebugColorAttribute.cs b/src/Debug/Attributes/DebugColorAttribute.cs index 253f64f..378a02b 100644 --- a/src/Debug/Attributes/DebugColorAttribute.cs +++ b/src/Debug/Attributes/DebugColorAttribute.cs @@ -10,45 +10,31 @@ namespace DCFApixels.DragonECS public byte r => color.r; public byte g => color.g; public byte b => color.b; - + /// normalized R channel public float rn => color.r / 255f; + /// normalized G channel public float gn => color.g / 255f; + /// normalized B channel public float bn => color.b / 255f; - - public DebugColorAttribute(byte r, byte g, byte b) - { - color = new ColorRecord(r, g, b); - } - public DebugColorAttribute(DebugColor color) - { - this.color = new ColorRecord((int)color); - } + public DebugColorAttribute(byte r, byte g, byte b) => color = new ColorRecord(r, g, b); + public DebugColorAttribute(DebugColor color) => this.color = new ColorRecord((int)color); [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)] private readonly struct ColorRecord // Union { - [FieldOffset(0)] - public readonly int full; - [FieldOffset(3)] - public readonly byte r; - [FieldOffset(2)] - public readonly byte g; - [FieldOffset(1)] - public readonly byte b; - + [FieldOffset(0)] public readonly int full; + [FieldOffset(3)] public readonly byte r; + [FieldOffset(2)] public readonly byte g; + [FieldOffset(1)] public readonly byte b; public ColorRecord(byte r, byte g, byte b) : this() { this.r = r; this.g = g; this.b = b; } - public ColorRecord(int full) : this() - { - this.full = full; - } + public ColorRecord(int full) : this() => this.full = full; } } - public enum DebugColor { /// Red. RGB is (255, 0, 0) diff --git a/src/Debug/Attributes/DebugDescriptionAttribute.cs b/src/Debug/Attributes/DebugDescriptionAttribute.cs index 88a50c5..1a7aacd 100644 --- a/src/Debug/Attributes/DebugDescriptionAttribute.cs +++ b/src/Debug/Attributes/DebugDescriptionAttribute.cs @@ -6,9 +6,6 @@ namespace DCFApixels.DragonECS public sealed class DebugDescriptionAttribute : Attribute { public readonly string description; - public DebugDescriptionAttribute(string description) - { - this.description = description; - } + public DebugDescriptionAttribute(string description) => this.description = description; } } diff --git a/src/Debug/Attributes/DebugNameAttribute.cs b/src/Debug/Attributes/DebugNameAttribute.cs index 30c4d57..01f6fda 100644 --- a/src/Debug/Attributes/DebugNameAttribute.cs +++ b/src/Debug/Attributes/DebugNameAttribute.cs @@ -6,9 +6,6 @@ namespace DCFApixels.DragonECS public sealed class DebugNameAttribute : Attribute { public readonly string name; - public DebugNameAttribute(string name) - { - this.name = name; - } + public DebugNameAttribute(string name) => this.name = name; } } diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs index 2bb9460..2f0ee31 100644 --- a/src/EcsGroup.cs +++ b/src/EcsGroup.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; #if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS @@ -8,6 +9,7 @@ using static DCFApixels.DragonECS.EcsGroup.ThrowHalper; namespace DCFApixels.DragonECS { [StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)] + [DebuggerTypeProxy(typeof(DebuggerProxy))] public readonly ref struct EcsReadonlyGroup { private readonly EcsGroup _source; @@ -65,12 +67,7 @@ namespace DCFApixels.DragonECS #endregion #region Object - public override string ToString() - { - if (_source != null) - return _source.ToString(); - return "NULL"; - } + public override string ToString() => _source != null ? _source.ToString() : "NULL"; public override int GetHashCode() => _source.GetHashCode(); public override bool Equals(object obj) => obj is EcsGroup group && group == this; public bool Equals(EcsReadonlyGroup other) => _source == other._source; @@ -88,15 +85,23 @@ namespace DCFApixels.DragonECS public static bool operator !=(EcsReadonlyGroup a, EcsReadonlyGroup b) => !a.Equals(b); public static bool operator !=(EcsReadonlyGroup a, EcsGroup b) => !a.Equals(b); #endregion + + #region DebuggerProxy + internal class DebuggerProxy : EcsGroup.DebuggerProxy + { + public DebuggerProxy(EcsReadonlyGroup group) : base(group._source) { } + } + #endregion } + [DebuggerTypeProxy(typeof(DebuggerProxy))] public unsafe class EcsGroup : IDisposable, IEquatable { private EcsWorld _source; private int[] _dense; private int[] _sparse; private int _count; - private bool _isReleased = true; + internal bool _isReleased = true; #region Properties public EcsWorld World => _source; @@ -391,10 +396,7 @@ namespace DCFApixels.DragonECS #endregion #region Object - public override string ToString() - { - return string.Join(", ", _dense.AsSpan(1, _count).ToArray()); - } + public override string ToString() => string.Join(", ", _dense.AsSpan(1, _count).ToArray()); public override bool Equals(object obj) => obj is EcsGroup group && Equals(group); public bool Equals(EcsReadonlyGroup other) => Equals(other.GetGroupInternal()); public bool Equals(EcsGroup other) @@ -448,13 +450,9 @@ namespace DCFApixels.DragonECS #endregion #region IDisposable/Release - public void Dispose() - { - Release(); - } + public void Dispose() => Release(); public void Release() { - _isReleased = true; _source.ReleaseGroup(this); } #endregion @@ -472,21 +470,30 @@ namespace DCFApixels.DragonECS } #endif #endregion - } - #region Extensions - public static class EcsGroupExtensions - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Normalize(this EcsGroup self, ref T[] array) + #region DebuggerProxy + internal class DebuggerProxy { - if (array.Length < self.CapacityDense) Array.Resize(ref array, self.CapacityDense); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Normalize(this EcsReadonlyGroup self, ref T[] array) - { - if (array.Length < self.CapacityDense) Array.Resize(ref array, self.CapacityDense); + private EcsGroup _group; + public EcsWorld World => _group.World; + public bool IsReleased => _group.IsReleased; + public entlong[] Entities + { + get + { + entlong[] result = new entlong[_group.Count]; + int i = 0; + foreach (var e in _group) + result[i++] = _group.World.GetEntityLong(e); + return result; + } + } + public int Count => _group.Count; + public int CapacityDense => _group.CapacityDense; + public int CapacitySparce => _group.CapacitySparce; + + public DebuggerProxy(EcsGroup group) => _group = group; } + #endregion } - #endregion -} +} \ No newline at end of file diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 42d4aab..1d88b3c 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -322,15 +322,16 @@ namespace DCFApixels.DragonECS } #endregion - #region Groups + #region Groups Pool internal void RegisterGroup(EcsGroup group) { _groups.Add(new WeakReference(group)); } internal EcsGroup GetGroupFromPool() { - if (_groupsPool.Count <= 0) return new EcsGroup(this); - return _groupsPool.Pop(); + EcsGroup result = _groupsPool.Count <= 0 ? new EcsGroup(this) : _groupsPool.Pop(); + result._isReleased = false; + return result; } internal void ReleaseGroup(EcsGroup group) { @@ -338,6 +339,7 @@ namespace DCFApixels.DragonECS if (group.World != this) throw new ArgumentException("groupFilter.WorldIndex != this"); #endif + group._isReleased = true; group.Clear(); _groupsPool.Push(group); } From 62ceb3384e9af688b8eaca6798805942a3a4d9d4 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 28 May 2023 06:35:33 +0800 Subject: [PATCH 7/7] refactoring --- src/EcsPipeline.cs | 24 +----------------------- src/EcsWorld.cs | 8 ++++++++ src/Utils/IntExtensions.cs | 10 ---------- 3 files changed, 9 insertions(+), 33 deletions(-) delete mode 100644 src/Utils/IntExtensions.cs diff --git a/src/EcsPipeline.cs b/src/EcsPipeline.cs index 2af0ecd..ab1e3fe 100644 --- a/src/EcsPipeline.cs +++ b/src/EcsPipeline.cs @@ -20,7 +20,6 @@ namespace DCFApixels.DragonECS private bool _isInit; private bool _isDestoryed; - private bool _isEmptyDummy; #region Properties public ReadOnlyCollection AllSystems => _allSystemsSealed; @@ -39,7 +38,6 @@ namespace DCFApixels.DragonECS _allRunnersSealed = new ReadOnlyDictionary(_runners); _isInit = false; - _isEmptyDummy = false; _isDestoryed = false; } #endregion @@ -64,9 +62,6 @@ namespace DCFApixels.DragonECS #region LifeCycle public void Init() { - if (_isEmptyDummy) - return; - if (_isInit == true) { EcsDebug.Print("[Warning]", $"This {nameof(EcsPipeline)} has already been initialized"); @@ -98,9 +93,6 @@ namespace DCFApixels.DragonECS } public void Destroy() { - if (_isEmptyDummy) - return; - #if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS CheckBeforeInitForMethod(nameof(Run)); #endif @@ -135,10 +127,7 @@ namespace DCFApixels.DragonECS #endregion #region Builder - public static Builder New() - { - return new Builder(); - } + public static Builder New() => new Builder(); public class Builder { private const int KEYS_CAPACITY = 4; @@ -149,16 +138,12 @@ namespace DCFApixels.DragonECS public Builder() { _basicLayer = EcsConsts.BASIC_LAYER; - Layers = new LayerList(this, _basicLayer); - Layers.Insert(EcsConsts.BASIC_LAYER, EcsConsts.PRE_BEGIN_LAYER, EcsConsts.BEGIN_LAYER); Layers.InsertAfter(EcsConsts.BASIC_LAYER, EcsConsts.END_LAYER, EcsConsts.POST_END_LAYER); - _uniqueTypes = new HashSet(); _systems = new Dictionary>(KEYS_CAPACITY); } - public Builder Add(IEcsSystem system, string layerName = null) { AddInternal(system, layerName, false); @@ -192,20 +177,16 @@ namespace DCFApixels.DragonECS if (system is IEcsModule module)//если система одновременно явялется и системой и модулем то за один Add будет вызван Add и AddModule AddModule(module); } - public Builder AddModule(IEcsModule module) { module.ImportSystems(this); return this; } - public EcsPipeline Build() { Add(new DeleteEmptyEntitesSystem(), EcsConsts.POST_END_LAYER); - List result = new List(32); List basicBlockList = _systems[_basicLayer]; - foreach (var item in _systems) { if (!Layers.Has(item.Key)) @@ -216,17 +197,14 @@ namespace DCFApixels.DragonECS if(_systems.TryGetValue(item, out var list)) result.AddRange(list); } - return new EcsPipeline(result.ToArray()); } - public class LayerList : IEnumerable { private const string ADD_LAYER = nameof(ADD_LAYER); // автоматический слой нужный только для метода Add private Builder _source; private List _layers; - private string _basicLayerName; public LayerList(Builder source, string basicLayerName) diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 1d88b3c..ccae5fa 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -566,4 +566,12 @@ namespace DCFApixels.DragonECS } } #endregion + + #region Extensions + public static class IntExtensions + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static entlong ToEntityLong(this int self, EcsWorld world) => world.GetEntityLong(self); + } + #endregion } diff --git a/src/Utils/IntExtensions.cs b/src/Utils/IntExtensions.cs deleted file mode 100644 index 2c42f57..0000000 --- a/src/Utils/IntExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace DCFApixels.DragonECS -{ - public static class IntExtensions - { - public static entlong ToEntityLong(this int self, EcsWorld world) - { - return world.GetEntityLong(self); - } - } -}