From 39861492672f636217658dd73dc6ee825a5c0593 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 17 Mar 2025 11:06:52 +0800 Subject: [PATCH 01/50] update mask, add world.TryFindPoolInstance --- src/EcsAspect.cs | 12 ++++++------ src/EcsMask.cs | 20 +++++++++++++++----- src/EcsWorld.pools.cs | 11 +++++++++++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index 1f56e26..13f38e4 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -272,13 +272,13 @@ namespace DCFApixels.DragonECS public TPool IncludePool() where TPool : IEcsPoolImplementation, new() { var pool = CachePool(); - IncludeImplicit(pool.ComponentType); + SetMaskInclude(pool.ComponentType); return pool; } public TPool ExcludePool() where TPool : IEcsPoolImplementation, new() { var pool = CachePool(); - ExcludeImplicit(pool.ComponentType); + SetMaskExclude(pool.ComponentType); return pool; } public TPool OptionalPool() where TPool : IEcsPoolImplementation, new() @@ -291,14 +291,14 @@ namespace DCFApixels.DragonECS var pool = _world.GetPoolInstance(); return pool; } - private void IncludeImplicit(Type type) + public void SetMaskInclude(Type type) { if (_maskBuilder.IsNull == false) { _maskBuilder.Inc(type); } } - private void ExcludeImplicit(Type type) + public void SetMaskExclude(Type type) { if (_maskBuilder.IsNull == false) { @@ -334,8 +334,8 @@ namespace DCFApixels.DragonECS IncludePool(); ExcludePool(); OptionalPool(); - IncludeImplicit(null); - ExcludeImplicit(null); + SetMaskInclude(null); + SetMaskExclude(null); } #endregion } diff --git a/src/EcsMask.cs b/src/EcsMask.cs index acd36e6..3a88fdc 100644 --- a/src/EcsMask.cs +++ b/src/EcsMask.cs @@ -488,7 +488,7 @@ namespace DCFApixels.DragonECS [Il2CppSetOption(Option.NullChecks, false)] [Il2CppSetOption(Option.ArrayBoundsChecks, false)] #endif - public class EcsMaskIterator + public class EcsMaskIterator : IDisposable { // TODO есть идея перенести эти ChunckBuffer-ы в стек, // для этого нужно проработать дизайн так чтобы память в стеке выделялась за пределами итератора и GetEnumerator, @@ -555,6 +555,15 @@ namespace DCFApixels.DragonECS } } unsafe ~EcsMaskIterator() + { + Cleanup(false); + } + public void Dispose() + { + Cleanup(true); + GC.SuppressFinalize(this); + } + private void Cleanup(bool disposing) { _sortIncBuffer.ReadonlyDispose(); //_sortExcBuffer.ReadonlyDispose();// использует общую памяять с _sortIncBuffer; @@ -563,7 +572,7 @@ namespace DCFApixels.DragonECS } #endregion - #region SortConstraints + #region SortConstraints/TryFindEntityStorage private unsafe int SortConstraints_Internal() { UnsafeArray sortIncBuffer = _sortIncBuffer; @@ -611,7 +620,7 @@ namespace DCFApixels.DragonECS // Поэтому исключающее ограничение игнорируется для maxEntites. return maxEntites; } - private unsafe bool TryGetEntityStorage(out IEntityStorage storage) + private unsafe bool TryFindEntityStorage(out IEntityStorage storage) { if (_isHasAnyEntityStorage) { @@ -737,7 +746,7 @@ namespace DCFApixels.DragonECS { return new Enumerator(_span.Slice(0, 0), _iterator); } - if (_iterator.TryGetEntityStorage(out IEntityStorage storage)) + if (_iterator.TryFindEntityStorage(out IEntityStorage storage)) { return new Enumerator(storage.ToSpan(), _iterator); } @@ -811,6 +820,7 @@ namespace DCFApixels.DragonECS #region Iterate/Enumerable OnlyInc [MethodImpl(MethodImplOptions.AggressiveInlining)] public OnlyIncEnumerable IterateOnlyInc(EcsSpan span) { return new OnlyIncEnumerable(this, span); } + #if ENABLE_IL2CPP [Il2CppSetOption(Option.NullChecks, false)] [Il2CppSetOption(Option.ArrayBoundsChecks, false)] @@ -876,7 +886,7 @@ namespace DCFApixels.DragonECS { return new Enumerator(_span.Slice(0, 0), _iterator); } - if (_iterator.TryGetEntityStorage(out IEntityStorage storage)) + if (_iterator.TryFindEntityStorage(out IEntityStorage storage)) { return new Enumerator(storage.ToSpan(), _iterator); } diff --git a/src/EcsWorld.pools.cs b/src/EcsWorld.pools.cs index 1c1d047..357b891 100644 --- a/src/EcsWorld.pools.cs +++ b/src/EcsWorld.pools.cs @@ -40,6 +40,17 @@ namespace DCFApixels.DragonECS { return FindPoolInstance_Internal(GetComponentTypeID(componentType)); } + public bool TryFindPoolInstance(int componentTypeID, out IEcsPool pool) + { + pool = FindPoolInstance(componentTypeID); + return pool.IsNullOrDummy() == false; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryFindPoolInstance(Type componentType, out IEcsPool pool) + { + pool = FindPoolInstance(componentType); + return pool.IsNullOrDummy() == false; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] private IEcsPool FindPoolInstance_Internal(int componentTypeID) { From b331f4fda1a0e766945f9ada29b6361ff7d23196 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 17 Mar 2025 13:05:23 +0800 Subject: [PATCH 02/50] update component interfaaces --- src/DataInterfaces.cs | 6 +++--- src/EcsWorld.static.cs | 1 + src/Pools/EcsPool.cs | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/DataInterfaces.cs b/src/DataInterfaces.cs index c2ce421..3a46db5 100644 --- a/src/DataInterfaces.cs +++ b/src/DataInterfaces.cs @@ -3,7 +3,7 @@ #endif using System.Runtime.CompilerServices; -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS.Core { #region IEcsWorldComponent public interface IEcsWorldComponent @@ -44,11 +44,11 @@ namespace DCFApixels.DragonECS void Enable(ref T component); void Disable(ref T component); } - public static class EcsComponentResetHandler + public static class EcsComponentLifecycleHandler { public static readonly IEcsComponentLifecycle instance; public static readonly bool isHasHandler; - static EcsComponentResetHandler() + static EcsComponentLifecycleHandler() { T def = default; if (def is IEcsComponentLifecycle intrf) diff --git a/src/EcsWorld.static.cs b/src/EcsWorld.static.cs index 6e26f9f..cdfe30c 100644 --- a/src/EcsWorld.static.cs +++ b/src/EcsWorld.static.cs @@ -1,6 +1,7 @@ #if DISABLE_DEBUG #undef DEBUG #endif +using DCFApixels.DragonECS.Core; using DCFApixels.DragonECS.Internal; using System; using System.Collections.Generic; diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index f22a3a8..cb4bb09 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -45,8 +45,8 @@ namespace DCFApixels.DragonECS private int[] _recycledItems; private int _recycledItemsCount = 0; - private readonly IEcsComponentLifecycle _componentLifecycleHandler = EcsComponentResetHandler.instance; - private readonly bool _isHasComponentLifecycleHandler = EcsComponentResetHandler.isHasHandler; + private readonly IEcsComponentLifecycle _componentLifecycleHandler = EcsComponentLifecycleHandler.instance; + private readonly bool _isHasComponentLifecycleHandler = EcsComponentLifecycleHandler.isHasHandler; private readonly IEcsComponentCopy _componentCopyHandler = EcsComponentCopyHandler.instance; private readonly bool _isHasComponentCopyHandler = EcsComponentCopyHandler.isHasHandler; From b14adb01ca497e368519c14d720f11e8d00bf952 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 17 Mar 2025 20:00:27 +0800 Subject: [PATCH 03/50] update TypeMeta --- .../MetaDescriptionAttribute.cs | 1 + src/DebugUtils/TypeMeta.cs | 44 ++++++++++++++++++- src/EcsPipeline.cs | 1 + 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/DebugUtils/MetaAttributes/MetaDescriptionAttribute.cs b/src/DebugUtils/MetaAttributes/MetaDescriptionAttribute.cs index 4119212..6b5352a 100644 --- a/src/DebugUtils/MetaAttributes/MetaDescriptionAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaDescriptionAttribute.cs @@ -28,6 +28,7 @@ namespace DCFApixels.DragonECS { get { return string.IsNullOrEmpty(Author) == false; } } + public MetaDescription(string text) : this(null, text) { } public MetaDescription(string author, string text) { if (author == null) { author = string.Empty; } diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index 1a822ba..78c7577 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -65,6 +65,9 @@ namespace DCFApixels.DragonECS private string _metaID; private EcsTypeCode _typeCode; + private bool _isProcess; + private bool _isComponent; + private InitFlag _initFlags = InitFlag.None; #region Constructors @@ -287,6 +290,33 @@ namespace DCFApixels.DragonECS } #endregion + #region ReflectionInfo + public bool IsComponent + { + get + { + if (_initFlags.HasFlag(InitFlag.ReflectionInfo) == false) + { + MetaGenerator.GetReflectionInfo(this); + _initFlags |= InitFlag.ReflectionInfo; + } + return _isComponent; + } + } + public bool IsProcess + { + get + { + if (_initFlags.HasFlag(InitFlag.ReflectionInfo) == false) + { + MetaGenerator.GetReflectionInfo(this); + _initFlags |= InitFlag.ReflectionInfo; + } + return _isProcess; + } + } + #endregion + #region InitializeAll public TypeMeta InitializeAll() { @@ -316,9 +346,10 @@ namespace DCFApixels.DragonECS Tags = 1 << 4, MetaID = 1 << 5, TypeCode = 1 << 6, - //MemberType = 1 << 7, + ReflectionInfo = 1 << 7, + //MemberType = 1 << 8, - All = Name | Group | Color | Description | Tags | TypeCode | MetaID //| MemberType + All = Name | Group | Color | Description | Tags | TypeCode | MetaID | ReflectionInfo //| MemberType } #endregion @@ -548,6 +579,15 @@ namespace DCFApixels.DragonECS #endif } #endregion + + #region GetReflectionInfo + public static void GetReflectionInfo(TypeMeta meta) + { + var interfaces = meta.Type.GetInterfaces(); + meta._isComponent = Array.IndexOf(interfaces, typeof(IEcsComponentMember)) >= 0; + meta._isProcess = Array.IndexOf(interfaces, typeof(IEcsProcess)) >= 0; + } + #endregion } #endregion } diff --git a/src/EcsPipeline.cs b/src/EcsPipeline.cs index 6ad2331..45a6527 100644 --- a/src/EcsPipeline.cs +++ b/src/EcsPipeline.cs @@ -14,6 +14,7 @@ using static DCFApixels.DragonECS.EcsConsts; namespace DCFApixels.DragonECS { public interface IEcsMember { } + public interface IEcsComponentMember : IEcsMember { } public interface INamedMember { string Name { get; } From 4f84f139e17fe7f8381554d1214885591f4e1243 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 17 Mar 2025 20:00:40 +0800 Subject: [PATCH 04/50] update MetaID --- .../MetaAttributes/MetaIDAttribute.cs | 202 ++++++++++++++++++ 1 file changed, 202 insertions(+) diff --git a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs index 55f4b71..05593e9 100644 --- a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs @@ -4,6 +4,10 @@ using DCFApixels.DragonECS.Core; using DCFApixels.DragonECS.Internal; using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using System.Runtime.InteropServices; using System.Text.RegularExpressions; @@ -37,6 +41,12 @@ namespace DCFApixels.DragonECS [ThreadStatic] private static bool _isInit; + public static CollisionList FindMetaIDCollisions(IEnumerable metas) + { + return new CollisionList(metas); + } + + public static bool IsGenericID(string id) { return Regex.IsMatch(id, @"^[^,<>\s]*$"); @@ -74,5 +84,197 @@ namespace DCFApixels.DragonECS { return IDToAttribute(GenerateNewUniqueID()); } + + #region CollisionList + [DebuggerTypeProxy(typeof(DebuggerProxy))] + public class CollisionList : IEnumerable + { + private ListInternal[] _linkedLists; + private Entry[] _linkedEntries; + private int _collisionsCount; + private int _listsCount; + public int CollisionsCount + { + get { return _collisionsCount; } + } + public int ListsCount + { + get { return _listsCount; } + } + public bool IsHasAnyCollision + { + get { return _listsCount > 0; } + } + + public CollisionList(IEnumerable metas) + { + var metasCount = metas.Count(); + Dictionary listIndexes = new Dictionary(metasCount); + _linkedLists = new ListInternal[metasCount]; + _linkedEntries = new Entry[metasCount]; + + bool hasCollision = false; + + _listsCount = 0; + foreach (var meta in metas) + { + if (listIndexes.TryGetValue(meta.MetaID, out int headIndex)) + { + hasCollision = true; + } + else + { + headIndex = _listsCount++; + listIndexes.Add(meta.MetaID, headIndex); + } + ref var list = ref _linkedLists[headIndex]; + int nodeIndex = _collisionsCount++; + ref Entry entry = ref _linkedEntries[nodeIndex]; + if (list.count == 0) + { + entry.next = -1; + } + entry.meta = meta; + list.head = headIndex; + list.count++; + } + + if (hasCollision) + { + for (int i = 0; i < _listsCount; i++) + { + ref var list = ref _linkedLists[i]; + if (list.count <= 1) + { + _linkedLists[i] = _linkedLists[--_listsCount]; + } + } + } + else + { + _listsCount = 0; + } + } + + private struct ListInternal + { + public int count; + public int head; + } + public struct Entry + { + public TypeMeta meta; + public int next; + } + + #region Enumerator + public Enumerator GetEnumerator() { return new Enumerator(); } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + public struct Enumerator : IEnumerator + { + private readonly CollisionList _collisions; + private readonly int _count; + private int _index; + public List Current + { + get + { + var list = _collisions._linkedLists[_index]; + return new List(_collisions, list.head, list.count); + } + } + object IEnumerator.Current { get { return Current; } } + public Enumerator(CollisionList collisions, int count) + { + _collisions = collisions; + _count = count; + _index = -1; + } + public bool MoveNext() { return _index++ < _count; } + public void Dispose() { } + public void Reset() { _index = -1; } + } + #endregion + + public readonly struct List : IEnumerable + { + private readonly CollisionList _collisions; + private readonly int _head; + private readonly int _count; + public int Count + { + get { return _count; } + } + internal List(CollisionList collisions, int head, int count) + { + _collisions = collisions; + _head = count == 0 ? -1 : head; + _head = head; + _count = count; + } + + #region Enumerator + public Enumerator GetEnumerator() { return new Enumerator(_collisions._linkedEntries, _head); } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + public struct Enumerator : IEnumerator + { + private readonly Entry[] _linkedEntries; + private readonly int _head; + private int _nextIndex; + private int _index; + public TypeMeta Current { get { return _linkedEntries[_index].meta; } } + object IEnumerator.Current { get { return Current; } } + public Enumerator(Entry[] linkedEntries, int head) + { + _linkedEntries = linkedEntries; + _head = head; + _nextIndex = _head; + _index = -1; + } + public bool MoveNext() + { + if (_nextIndex < 0) { return false; } + _index = _nextIndex; + _nextIndex = _linkedEntries[_index].next; + return true; + } + public void Dispose() { } + public void Reset() + { + _nextIndex = _head; + _index = -1; + } + } + #endregion + } + + #region DebuggerProxy + private class DebuggerProxy + { + private CollisionList _collisions; + public TypeMeta[][] Lists; + public DebuggerProxy(CollisionList collisions) + { + _collisions = collisions; + Lists = new TypeMeta[collisions.ListsCount][]; + int i = 0; + foreach (var list in collisions) + { + int j = 0; + Lists[i] = new TypeMeta[list.Count]; + foreach (var typeMeta in list) + { + Lists[i][j] = typeMeta; + j++; + } + i++; + } + } + } + #endregion + } + #endregion } } \ No newline at end of file From 51bf6092c5c0d33292a268da80a0ee97264f685f Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 17 Mar 2025 21:46:51 +0800 Subject: [PATCH 05/50] update meta id --- .../MetaAttributes/MetaIDAttribute.cs | 93 +++++++++++++------ src/DebugUtils/TypeMeta.cs | 9 -- 2 files changed, 64 insertions(+), 38 deletions(-) diff --git a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs index 05593e9..f2ffc29 100644 --- a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs @@ -41,12 +41,17 @@ namespace DCFApixels.DragonECS [ThreadStatic] private static bool _isInit; + + public static bool TryFindMetaIDCollisions(IEnumerable metas, out CollisionList collisions) + { + collisions = new CollisionList(metas); + return collisions.IsHasAnyCollision; + } public static CollisionList FindMetaIDCollisions(IEnumerable metas) { return new CollisionList(metas); } - public static bool IsGenericID(string id) { return Regex.IsMatch(id, @"^[^,<>\s]*$"); @@ -87,17 +92,18 @@ namespace DCFApixels.DragonECS #region CollisionList [DebuggerTypeProxy(typeof(DebuggerProxy))] - public class CollisionList : IEnumerable + [DebuggerDisplay("HasAnyCollision: {IsHasAnyCollision} ListsCount: {ListsCount}")] + public class CollisionList : IEnumerable { - private ListInternal[] _linkedLists; - private Entry[] _linkedEntries; + private LinkedList[] _linkedLists; + private Entry[] _entries; private int _collisionsCount; private int _listsCount; public int CollisionsCount { get { return _collisionsCount; } } - public int ListsCount + public int Count { get { return _listsCount; } } @@ -105,13 +111,21 @@ namespace DCFApixels.DragonECS { get { return _listsCount > 0; } } + public Collision this[int index] + { + get + { + var list = _linkedLists[index]; + return new Collision(this, list.headNode, list.count); + } + } public CollisionList(IEnumerable metas) { var metasCount = metas.Count(); Dictionary listIndexes = new Dictionary(metasCount); - _linkedLists = new ListInternal[metasCount]; - _linkedEntries = new Entry[metasCount]; + _linkedLists = new LinkedList[metasCount]; + _entries = new Entry[metasCount]; bool hasCollision = false; @@ -127,15 +141,21 @@ namespace DCFApixels.DragonECS headIndex = _listsCount++; listIndexes.Add(meta.MetaID, headIndex); } - ref var list = ref _linkedLists[headIndex]; int nodeIndex = _collisionsCount++; - ref Entry entry = ref _linkedEntries[nodeIndex]; + + ref var list = ref _linkedLists[headIndex]; + ref Entry entry = ref _entries[nodeIndex]; if (list.count == 0) { entry.next = -1; } + else + { + entry.next = list.headNode; + } entry.meta = meta; - list.head = headIndex; + list.headNode = nodeIndex; + listIndexes[meta.MetaID] = headIndex; list.count++; } @@ -146,7 +166,7 @@ namespace DCFApixels.DragonECS ref var list = ref _linkedLists[i]; if (list.count <= 1) { - _linkedLists[i] = _linkedLists[--_listsCount]; + _linkedLists[i--] = _linkedLists[--_listsCount]; } } } @@ -156,11 +176,13 @@ namespace DCFApixels.DragonECS } } - private struct ListInternal + [DebuggerDisplay("Count: {count}")] + private struct LinkedList { public int count; - public int head; + public int headNode; } + [DebuggerDisplay("ID: {meta.MetaID} next: {next}")] public struct Entry { public TypeMeta meta; @@ -168,20 +190,20 @@ namespace DCFApixels.DragonECS } #region Enumerator - public Enumerator GetEnumerator() { return new Enumerator(); } + public Enumerator GetEnumerator() { return new Enumerator(this, _listsCount); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } - IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } - public struct Enumerator : IEnumerator + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + public struct Enumerator : IEnumerator { private readonly CollisionList _collisions; private readonly int _count; private int _index; - public List Current + public Collision Current { get { var list = _collisions._linkedLists[_index]; - return new List(_collisions, list.head, list.count); + return new Collision(_collisions, list.headNode, list.count); } } object IEnumerator.Current { get { return Current; } } @@ -191,31 +213,46 @@ namespace DCFApixels.DragonECS _count = count; _index = -1; } - public bool MoveNext() { return _index++ < _count; } + public bool MoveNext() { return ++_index < _count; } public void Dispose() { } public void Reset() { _index = -1; } } #endregion - public readonly struct List : IEnumerable + [DebuggerDisplay("Count: {Count}")] + public readonly struct Collision : IEnumerable { private readonly CollisionList _collisions; + private readonly string _metaID; private readonly int _head; private readonly int _count; public int Count { get { return _count; } } - internal List(CollisionList collisions, int head, int count) + public string MetaID + { + get { return _metaID; } + } + internal Collision(CollisionList collisions, int head, int count) { _collisions = collisions; - _head = count == 0 ? -1 : head; + if(count == 0) + { + _head = 0; + _metaID = string.Empty; + } + else + { + _head = head; + _metaID = collisions._entries[_head].meta.MetaID; + } _head = head; _count = count; } #region Enumerator - public Enumerator GetEnumerator() { return new Enumerator(_collisions._linkedEntries, _head); } + public Enumerator GetEnumerator() { return new Enumerator(_collisions._entries, _head); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public struct Enumerator : IEnumerator @@ -253,20 +290,18 @@ namespace DCFApixels.DragonECS #region DebuggerProxy private class DebuggerProxy { - private CollisionList _collisions; - public TypeMeta[][] Lists; + public string[][] Lists; public DebuggerProxy(CollisionList collisions) { - _collisions = collisions; - Lists = new TypeMeta[collisions.ListsCount][]; + Lists = new string[collisions.Count][]; int i = 0; foreach (var list in collisions) { int j = 0; - Lists[i] = new TypeMeta[list.Count]; + Lists[i] = new string[list.Count]; foreach (var typeMeta in list) { - Lists[i][j] = typeMeta; + Lists[i][j] = typeMeta.MetaID; j++; } i++; diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index 78c7577..ed6869a 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -538,9 +538,6 @@ namespace DCFApixels.DragonECS #endregion #region GetMetaID -#if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает - private static Dictionary _idTypePairs = new Dictionary(); -#endif public static string GetMetaID(Type type) { #if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает @@ -565,12 +562,6 @@ namespace DCFApixels.DragonECS id = $"{id}<{string.Join(", ", metaIds)}>"; } } - if (string.IsNullOrEmpty(id) == false && - _idTypePairs.TryGetValue(id, out Type otherType) && type != otherType) - { - Throw.Exception($"Types {type.ToMeta().TypeName} and {otherType.ToMeta().TypeName} have duplicate {atr.ID} MetaID."); - } - _idTypePairs[id] = type; return id; } #else From 26f141fca9f286eb3e8349a1e3fffe855f538368 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 19 Mar 2025 09:38:53 +0800 Subject: [PATCH 06/50] Update TypeMeta.cs --- src/DebugUtils/TypeMeta.cs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index ed6869a..5d658f5 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -3,6 +3,7 @@ #endif using DCFApixels.DragonECS.Core; using DCFApixels.DragonECS.Internal; +using DCFApixels.DragonECS.PoolsCore; using System; using System.Collections.Generic; using System.Diagnostics; @@ -67,6 +68,7 @@ namespace DCFApixels.DragonECS private bool _isProcess; private bool _isComponent; + private bool _isPool; private InitFlag _initFlags = InitFlag.None; @@ -315,6 +317,18 @@ namespace DCFApixels.DragonECS return _isProcess; } } + public bool IsPool + { + get + { + if (_initFlags.HasFlag(InitFlag.ReflectionInfo) == false) + { + MetaGenerator.GetReflectionInfo(this); + _initFlags |= InitFlag.ReflectionInfo; + } + return _isPool; + } + } #endregion #region InitializeAll @@ -574,9 +588,9 @@ namespace DCFApixels.DragonECS #region GetReflectionInfo public static void GetReflectionInfo(TypeMeta meta) { - var interfaces = meta.Type.GetInterfaces(); - meta._isComponent = Array.IndexOf(interfaces, typeof(IEcsComponentMember)) >= 0; - meta._isProcess = Array.IndexOf(interfaces, typeof(IEcsProcess)) >= 0; + meta._isComponent = typeof(IEcsComponentMember).IsAssignableFrom(meta.Type); + meta._isProcess = typeof(IEcsProcess).IsAssignableFrom(meta.Type); + meta._isPool = typeof(IEcsPoolImplementation).IsAssignableFrom(meta.Type); } #endregion } From 760e3d7e0f0bc93843b5e9f2635e52dd65b26eab Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 19 Mar 2025 09:39:14 +0800 Subject: [PATCH 07/50] add static pool.apply --- src/Pools/EcsPool.cs | 11 +++++++++++ src/Pools/EcsTagPool.cs | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index cb4bb09..7bad6f4 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -370,6 +370,17 @@ namespace DCFApixels.DragonECS public static implicit operator EcsPool(OptionalMarker a) { return a.GetInstance>(); } public static implicit operator EcsPool(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance>(); } #endregion + + #region Apply + public static void Apply(ref T component, int entityID, short worldID) + { + EcsWorld.GetPoolInstance>(worldID).TryAddOrGet(entityID) = component; + } + public static void Apply(ref T component, int entityID, EcsPool pool) + { + pool.TryAddOrGet(entityID) = component; + } + #endregion } public static class EcsPoolExtensions diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index b7626d3..74d5f28 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -317,6 +317,17 @@ namespace DCFApixels.DragonECS public static implicit operator EcsTagPool(OptionalMarker a) { return a.GetInstance>(); } public static implicit operator EcsTagPool(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance>(); } #endregion + + #region Apply + public static void Apply(ref T component, int entityID, short worldID) + { + EcsWorld.GetPoolInstance>(worldID).TryAdd(entityID); + } + public static void Apply(ref T component, int entityID, EcsTagPool pool) + { + pool.TryAdd(entityID); + } + #endregion } public static class EcsTagPoolExtensions From 02d2c646cce2cb0df11779602bda7a98dd92cf87 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 19 Mar 2025 11:18:25 +0800 Subject: [PATCH 08/50] refactoring --- src/Collections/EcsGroup.cs | 6 ++-- src/Collections/EcsSpan.cs | 4 +-- src/EcsWorld.cs | 4 +-- src/Internal/ArrayUtility.cs | 53 ++++++++++-------------------------- src/Internal/IdDispenser.cs | 2 +- src/Internal/StructList.cs | 4 +-- src/Pools/EcsPool.cs | 2 +- 7 files changed, 25 insertions(+), 50 deletions(-) diff --git a/src/Collections/EcsGroup.cs b/src/Collections/EcsGroup.cs index 7334897..5d70cfe 100644 --- a/src/Collections/EcsGroup.cs +++ b/src/Collections/EcsGroup.cs @@ -400,7 +400,7 @@ namespace DCFApixels.DragonECS { if (++_count >= _dense.Length) { - Array.Resize(ref _dense, ArrayUtility.NormalizeSizeToPowerOfTwo(_count << 1)); + Array.Resize(ref _dense, ArrayUtility.NextPow2(_count << 1)); } _dense[_count] = entityID; @@ -531,7 +531,7 @@ namespace DCFApixels.DragonECS { if (minSize >= _dense.Length) { - Array.Resize(ref _dense, ArrayUtility.NormalizeSizeToPowerOfTwo_ClampOverflow(minSize)); + Array.Resize(ref _dense, ArrayUtility.NextPow2_ClampOverflow(minSize)); } } @@ -618,7 +618,7 @@ namespace DCFApixels.DragonECS { if (dynamicBuffer.Length < _count) { - Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_count)); + Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_count)); } int i = 0; foreach (var e in this) diff --git a/src/Collections/EcsSpan.cs b/src/Collections/EcsSpan.cs index 58bc198..48c26c4 100644 --- a/src/Collections/EcsSpan.cs +++ b/src/Collections/EcsSpan.cs @@ -97,7 +97,7 @@ namespace DCFApixels.DragonECS { if (dynamicBuffer.Length < _values.Length) { - Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_values.Length)); + Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_values.Length)); } int i = 0; foreach (var e in this) @@ -246,7 +246,7 @@ namespace DCFApixels.DragonECS { if (dynamicBuffer.Length < _source.Count) { - Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_source.Count)); + Array.Resize(ref dynamicBuffer, ArrayUtility.NextPow2(_source.Count)); } int i = 0; foreach (var e in this) diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index e4d6ff9..25015ad 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -198,12 +198,12 @@ namespace DCFApixels.DragonECS _poolsMediator = new PoolsMediator(this); - int poolsCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.PoolsCapacity); + int poolsCapacity = ArrayUtility.NextPow2(config.PoolsCapacity); _pools = new IEcsPoolImplementation[poolsCapacity]; _poolSlots = new PoolSlot[poolsCapacity]; ArrayUtility.Fill(_pools, _nullPool); - int entitiesCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.EntitiesCapacity); + int entitiesCapacity = ArrayUtility.NextPow2(config.EntitiesCapacity); _entityDispenser = new IdDispenser(entitiesCapacity, 0, OnEntityDispenserResized); _executorCoures = new Dictionary<(Type, object), IQueryExecutorImplementation>(config.PoolComponentsCapacity); diff --git a/src/Internal/ArrayUtility.cs b/src/Internal/ArrayUtility.cs index 4927430..33dc2a0 100644 --- a/src/Internal/ArrayUtility.cs +++ b/src/Internal/ArrayUtility.cs @@ -92,58 +92,33 @@ namespace DCFApixels.DragonECS.Internal Array.Copy(array, array.Length - rightHeadLength, result, array.Length - rightHeadLength, rightHeadLength); // copy right head array = result; } - private static int GetHighBitNumber(uint bits) - { - if (bits == 0) - { - return -1; - } - int bit = 0; - if ((bits & 0xFFFF0000) != 0) - { - bits >>= 16; - bit |= 16; - } - if ((bits & 0xFF00) != 0) - { - bits >>= 8; - bit |= 8; - } - if ((bits & 0xF0) != 0) - { - bits >>= 4; - bit |= 4; - } - if ((bits & 0xC) != 0) - { - bits >>= 2; - bit |= 2; - } - if ((bits & 0x2) != 0) - { - bit |= 1; - } - return bit; - } - public static int NormalizeSizeToPowerOfTwo(int minSize) + + public static int NextPow2(int v) { unchecked { - return 1 << (GetHighBitNumber((uint)minSize - 1u) + 1); + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + return ++v; } } - public static int NormalizeSizeToPowerOfTwo_ClampOverflow(int minSize) + public static int NextPow2_ClampOverflow(int v) { unchecked { - int hibit = (GetHighBitNumber((uint)minSize - 1u) + 1); - if (hibit >= 32) + const int NO_SIGN_HIBIT = 0x40000000; + if ((v & NO_SIGN_HIBIT) != 0) { return int.MaxValue; } - return 1 << hibit; + return NextPow2(v); } } + public static void Fill(T[] array, T value, int startIndex = 0, int length = -1) { if (length < 0) diff --git a/src/Internal/IdDispenser.cs b/src/Internal/IdDispenser.cs index 3ac1a83..1d4aa21 100644 --- a/src/Internal/IdDispenser.cs +++ b/src/Internal/IdDispenser.cs @@ -247,7 +247,7 @@ namespace DCFApixels.DragonECS.Internal [MethodImpl(MethodImplOptions.NoInlining)] private void Upsize_Internal(int minSize) { - Resize(ArrayUtility.NormalizeSizeToPowerOfTwo_ClampOverflow(minSize)); + Resize(ArrayUtility.NextPow2_ClampOverflow(minSize)); } private void Resize(int newSize) { diff --git a/src/Internal/StructList.cs b/src/Internal/StructList.cs index d7ad9aa..7488304 100644 --- a/src/Internal/StructList.cs +++ b/src/Internal/StructList.cs @@ -26,7 +26,7 @@ namespace DCFApixels.DragonECS.Internal set { if (value <= _items.Length) { return; } - value = ArrayUtility.NormalizeSizeToPowerOfTwo(value); + value = ArrayUtility.NextPow2(value); Array.Resize(ref _items, value); } } @@ -53,7 +53,7 @@ namespace DCFApixels.DragonECS.Internal [MethodImpl(MethodImplOptions.AggressiveInlining)] public StructList(int capacity) { - _items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(capacity)]; + _items = new T[ArrayUtility.NextPow2(capacity)]; _count = 0; } diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index cb4bb09..e7a1218 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -266,7 +266,7 @@ namespace DCFApixels.DragonECS _maskBit = EcsMaskChunck.FromID(componentTypeID); _mapping = new int[world.Capacity]; - _items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(world.Configs.GetWorldConfigOrDefault().PoolComponentsCapacity)]; + _items = new T[ArrayUtility.NextPow2(world.Configs.GetWorldConfigOrDefault().PoolComponentsCapacity)]; _recycledItems = new int[world.Configs.GetWorldConfigOrDefault().PoolRecycledComponentsCapacity]; } void IEcsPoolImplementation.OnWorldResize(int newSize) From b008643900462e1c891850cb82f97f7014aabbbe Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 19 Mar 2025 13:47:22 +0800 Subject: [PATCH 09/50] Update TypeMeta.cs --- src/DebugUtils/TypeMeta.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index 5d658f5..f1ac422 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -566,16 +566,17 @@ namespace DCFApixels.DragonECS string id = atr.ID; if (type.IsGenericType && type.IsGenericTypeDefinition == false) { - var metaIds = type.GetGenericArguments().Select(o => GetMetaID(o)); - if (metaIds.Any(o => string.IsNullOrEmpty(o))) + var metaIDs = type.GetGenericArguments().Select(o => GetMetaID(o)); + if (metaIDs.Any(o => string.IsNullOrEmpty(o))) { id = string.Empty; } else { - id = $"{id}<{string.Join(", ", metaIds)}>"; + id = $"{id}<{string.Join(", ", metaIDs)}>"; } } + id = string.Intern(id); return id; } #else From 70520d38c6828a6bde26b0a34df80d856b28e6e5 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 19 Mar 2025 16:16:33 +0800 Subject: [PATCH 10/50] Update MetaIDAttribute.cs --- .../MetaAttributes/MetaIDAttribute.cs | 157 ++++++++++++------ 1 file changed, 109 insertions(+), 48 deletions(-) diff --git a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs index f2ffc29..be810e0 100644 --- a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs @@ -21,25 +21,124 @@ namespace DCFApixels.DragonECS { if (string.IsNullOrEmpty(id)) { - Throw.ArgumentNull(nameof(id)); + EcsDebug.PrintError("The identifier cannot be empty or null"); + id = string.Empty; } - if (MetaID.IsGenericID(id) == false) + if (MetaID.IsValidID(id) == false) { - Throw.ArgumentException($"Identifier {id} contains invalid characters: ,<>"); + EcsDebug.PrintError($"Identifier {id} contains invalid characters. Allowed charset: {MetaID.ALLOWED_CHARSET}"); + id = string.Empty; } - id = string.Intern(id); ID = id; } } - public static class MetaID + public static unsafe class MetaID { + public const string ALLOWED_CHARSET = "_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + public static bool IsFixedNameType(Type type) + { + if (type.IsPrimitive) + { + return true; + } + if(type == typeof(string)) + { + return true; + } + return false; + } + public static bool IsGenericID(string id) + { + return Regex.IsMatch(id, @"^[^,<>\s]*$"); + } + public static bool IsValidID(string input) + { + return input[input.Length - 1] == '>' || Regex.IsMatch(input, @"^[a-zA-Z0-9_]+$"); + } + + [ThreadStatic] - private static Random _randon; - [ThreadStatic] - private static byte[] _buffer; - [ThreadStatic] - private static bool _isInit; + private static uint _randonState; + public static string GenerateNewUniqueID() + { + const int BYTES = 16; + const int CHARS = BYTES * 2; + const string CHARSET = "0123456789ABCDEF"; + + if (_randonState == 0) + { + IntPtr prt = Marshal.AllocHGlobal(1); + long alloc = (long)prt; + Marshal.FreeHGlobal(prt); + _randonState = (uint)alloc ^ (uint)DateTime.Now.Millisecond; + } + + byte* bytes = stackalloc byte[BYTES]; + Span x = new Span(bytes, BYTES); + long* bytesLong = (long*)bytes; + uint* bytesUInt = (uint*)bytes; + bytesLong[0] = DateTime.Now.Ticks; + _randonState = BitsUtility.NextXorShiftState(_randonState); + bytesUInt[2] = _randonState; + _randonState = BitsUtility.NextXorShiftState(_randonState); + bytesUInt[3] = _randonState; + + + char* str = stackalloc char[CHARS]; + for (int i = 0, j = 0; i < BYTES; i++) + { + byte b = bytes[i]; + str[j++] = CHARSET[b & 0x0000_000F]; + str[j++] = CHARSET[(b >> 4) & 0x0000_000F]; + } + + return new string(str, 0, CHARS); + } + public static string IDToAttribute(string id) + { + return $"[MetaID(\"{id}\")]"; + } + public static string ConvertIDToTypeName(string id) + { + id = id.Replace("_1", "__"); + id = id.Replace("_2", "__"); + id = id.Replace("_3", "__"); + + id = id.Replace("<", "_1"); + id = id.Replace(">", "_2"); + id = id.Replace(",", "_3"); + return "_" + id; + } + public static string ParseIDFromTypeName(string name) + { + char* buffer = TempBuffer.Get(name.Length); + int count = 0; + //skip name[0] char + for (int i = 1, iMax = name.Length; i < iMax; i++) + { + char current = name[i]; + if (current == '_') + { + if (++i >= iMax) { break; } + current = name[i]; + switch (current) + { + case '1': current = '<'; break; + case '2': current = '>'; break; + case '3': current = ','; break; + } + } + buffer[count++] = current; + } + return new string(buffer, 0, count); + } + + public static string GenerateNewUniqueIDWithAttribute() + { + return IDToAttribute(GenerateNewUniqueID()); + } public static bool TryFindMetaIDCollisions(IEnumerable metas, out CollisionList collisions) @@ -52,44 +151,6 @@ namespace DCFApixels.DragonECS return new CollisionList(metas); } - public static bool IsGenericID(string id) - { - return Regex.IsMatch(id, @"^[^,<>\s]*$"); - } - - public static unsafe string GenerateNewUniqueID() - { - if (_isInit == false) - { - IntPtr prt = Marshal.AllocHGlobal(1); - long alloc = (long)prt; - Marshal.Release(prt); - _randon = new Random((int)alloc); - _buffer = new byte[8]; - _isInit = true; - } - - byte* hibits = stackalloc byte[8]; - long* hibitsL = (long*)hibits; - hibitsL[0] = DateTime.Now.Ticks; - hibitsL[1] = _randon.Next(); - - for (int i = 0; i < 8; i++) - { - _buffer[i] = hibits[i]; - } - - return BitConverter.ToString(_buffer).Replace("-", ""); - } - public static string IDToAttribute(string id) - { - return $"[MetaID(\"id\")]"; - } - public static string GenerateNewUniqueIDWithAttribute() - { - return IDToAttribute(GenerateNewUniqueID()); - } - #region CollisionList [DebuggerTypeProxy(typeof(DebuggerProxy))] [DebuggerDisplay("HasAnyCollision: {IsHasAnyCollision} ListsCount: {ListsCount}")] From 4aeb79fd0c46d727cfffde9247101bf640ff79cb Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 19 Mar 2025 16:30:20 +0800 Subject: [PATCH 11/50] update MetaIDs --- src/Builtin/BaseProcesses.cs | 16 ++++++++-------- src/Builtin/Worlds.cs | 4 ++-- src/DebugUtils/EcsDebug.cs | 2 +- src/DebugUtils/TypeMeta.cs | 2 +- src/EcsPipeline.Builder.cs | 2 +- src/EcsPipeline.cs | 6 +++--- src/EcsRunner.cs | 6 +++--- src/EcsWorld.cs | 2 +- src/Injections/Utils/Interfaces.cs | 4 ++-- src/Pools/EcsPool.cs | 4 ++-- src/Pools/EcsPoolBase.cs | 2 +- src/Pools/EcsTagPool.cs | 4 ++-- src/Utils/EcsPipelineTemplate.cs | 2 +- 13 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Builtin/BaseProcesses.cs b/src/Builtin/BaseProcesses.cs index e1cfd1c..42fdbbd 100644 --- a/src/Builtin/BaseProcesses.cs +++ b/src/Builtin/BaseProcesses.cs @@ -10,7 +10,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Init() is called. Before Init")] - [MetaID("DE26527C92015AFDD4ECF4D81A4C946B")] + [MetaID("DragonECS_DE26527C92015AFDD4ECF4D81A4C946B")] public interface IEcsPreInit : IEcsProcess { void PreInit(); @@ -19,7 +19,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Init() is called. After PreInit")] - [MetaID("CC45527C9201DF82DCAAAEF33072F9EF")] + [MetaID("DragonECS_CC45527C9201DF82DCAAAEF33072F9EF")] public interface IEcsInit : IEcsProcess { void Init(); @@ -28,7 +28,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Run() is called.")] - [MetaID("9654527C9201BE75546322B9BB03C131")] + [MetaID("DragonECS_9654527C9201BE75546322B9BB03C131")] public interface IEcsRun : IEcsProcess { void Run(); @@ -44,7 +44,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "The process to run when EcsPipeline.Destroy() is called.")] - [MetaID("4661527C9201EE669C6EB61B19899AE5")] + [MetaID("DragonECS_4661527C9201EE669C6EB61B19899AE5")] public interface IEcsDestroy : IEcsProcess { void Destroy(); @@ -62,7 +62,7 @@ namespace DCFApixels.DragonECS.Internal [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "...")] [MetaTags(MetaTags.HIDDEN)] - [MetaID("3273527C9201285BAA0A463F700A50FB")] + [MetaID("DragonECS_3273527C9201285BAA0A463F700A50FB")] internal sealed class EcsPreInitRunner : EcsRunner, IEcsPreInit { private RunHelper _helper; @@ -83,7 +83,7 @@ namespace DCFApixels.DragonECS.Internal [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "...")] [MetaTags(MetaTags.HIDDEN)] - [MetaID("ED85527C9201A391AB8EC0B734917859")] + [MetaID("DragonECS_ED85527C9201A391AB8EC0B734917859")] internal sealed class EcsInitRunner : EcsRunner, IEcsInit { private RunHelper _helper; @@ -104,7 +104,7 @@ namespace DCFApixels.DragonECS.Internal [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "...")] [MetaTags(MetaTags.HIDDEN)] - [MetaID("2098527C9201F260C840BFD50BC7E0BA")] + [MetaID("DragonECS_2098527C9201F260C840BFD50BC7E0BA")] internal sealed class EcsRunRunner : EcsRunner, IEcsRun { private readonly struct Pair @@ -184,7 +184,7 @@ namespace DCFApixels.DragonECS.Internal [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.PROCESSES_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "...")] [MetaTags(MetaTags.HIDDEN)] - [MetaID("06A6527C92010430ACEB3DA520F272CC")] + [MetaID("DragonECS_06A6527C92010430ACEB3DA520F272CC")] internal sealed class EcsDestroyRunner : EcsRunner, IEcsDestroy { private RunHelper _helper; diff --git a/src/Builtin/Worlds.cs b/src/Builtin/Worlds.cs index e7697be..5f50cfb 100644 --- a/src/Builtin/Worlds.cs +++ b/src/Builtin/Worlds.cs @@ -10,7 +10,7 @@ namespace DCFApixels.DragonECS [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "Inherits EcsWorld without extending its functionality and is used for specific injections. Can be used to store regular game entities, can also be used as a single world in the game for all entities.")] [DebuggerTypeProxy(typeof(DebuggerProxy))] - [MetaID("4EE3527C92015BAB0299CB7B4E2663D1")] + [MetaID("DragonECS_4EE3527C92015BAB0299CB7B4E2663D1")] public sealed class EcsDefaultWorld : EcsWorld, IInjectionUnit { public EcsDefaultWorld() : base() { } @@ -23,7 +23,7 @@ namespace DCFApixels.DragonECS [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "Inherits EcsWorld without extending its functionality and is used for specific injections. Can be used to store event entities.")] [DebuggerTypeProxy(typeof(DebuggerProxy))] - [MetaID("D7CE527C920160BCD765EFA72DBF8B89")] + [MetaID("DragonECS_D7CE527C920160BCD765EFA72DBF8B89")] public sealed class EcsEventWorld : EcsWorld, IInjectionUnit { public EcsEventWorld() : base() { } diff --git a/src/DebugUtils/EcsDebug.cs b/src/DebugUtils/EcsDebug.cs index 3eac63d..c3fd1ec 100644 --- a/src/DebugUtils/EcsDebug.cs +++ b/src/DebugUtils/EcsDebug.cs @@ -79,7 +79,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(PACK_GROUP, DEBUG_GROUP)] [MetaDescription(AUTHOR, "Debugging utility. To modify or change the behavior, create a new class inherited from DebugService and set this service using DebugService.Set().")] - [MetaID("10A4587C92013B55820D8604D718A1C3")] + [MetaID("DragonECS_10A4587C92013B55820D8604D718A1C3")] public static class EcsDebug { public static void Set() where T : DebugService, new() diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index f1ac422..bdbb7d2 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -37,7 +37,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DEBUG_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "Intended for extending meta information of types, for customization of type display in the editor. You can get it by using the object.GetMeta() or Type.ToMeta() extension method. Meta information is collected from meta attributes.")] - [MetaID("248D587C9201EAEA881F27871B4D18A6")] + [MetaID("DragonECS_248D587C9201EAEA881F27871B4D18A6")] [DebuggerTypeProxy(typeof(DebuggerProxy))] public sealed class TypeMeta : ITypeMeta { diff --git a/src/EcsPipeline.Builder.cs b/src/EcsPipeline.Builder.cs index d66f6d3..55c5be4 100644 --- a/src/EcsPipeline.Builder.cs +++ b/src/EcsPipeline.Builder.cs @@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(PACK_GROUP, OTHER_GROUP)] [MetaDescription(AUTHOR, "...")] - [MetaID("FC38597C9201C15D1A14D133237BD67F")] + [MetaID("DragonECS_FC38597C9201C15D1A14D133237BD67F")] public interface IEcsDefaultAddParams { AddParams AddParams { get; } diff --git a/src/EcsPipeline.cs b/src/EcsPipeline.cs index 45a6527..ca8af5f 100644 --- a/src/EcsPipeline.cs +++ b/src/EcsPipeline.cs @@ -23,7 +23,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(PACK_GROUP, OTHER_GROUP)] [MetaDescription(AUTHOR, "...")] - [MetaID("F064557C92010419AB677453893D00AE")] + [MetaID("DragonECS_F064557C92010419AB677453893D00AE")] public interface IEcsPipelineMember : IEcsProcess { EcsPipeline Pipeline { get; set; } @@ -32,7 +32,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(PACK_GROUP, OTHER_GROUP)] [MetaDescription(AUTHOR, "Container and engine for systems. Responsible for configuring the execution order of systems, providing a mechanism for messaging between systems, and a dependency injection mechanism.")] - [MetaID("9F5A557C9201C5C3D9BCAC2FF1CC07D4")] + [MetaID("DragonECS_9F5A557C9201C5C3D9BCAC2FF1CC07D4")] public sealed partial class EcsPipeline { private readonly IConfigContainer _configs; @@ -289,7 +289,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.Black)] [MetaGroup(PACK_GROUP, OTHER_GROUP)] [MetaDescription(AUTHOR, "An auxiliary type of system for dividing a pipeline into layers. This system is automatically added to the EcsPipeline.")] - [MetaID("42596C7C9201D0B85D1335E6E4704B57")] + [MetaID("DragonECS_42596C7C9201D0B85D1335E6E4704B57")] public class SystemsLayerMarkerSystem : IEcsProcess { public readonly string name; diff --git a/src/EcsRunner.cs b/src/EcsRunner.cs index 1b457ae..3398c43 100644 --- a/src/EcsRunner.cs +++ b/src/EcsRunner.cs @@ -14,7 +14,7 @@ namespace DCFApixels.DragonECS [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "...")] [MetaTags(MetaTags.HIDDEN)] - [MetaID("EF8A557C9201E6F04D4A76DC670BDE19")] + [MetaID("DragonECS_EF8A557C9201E6F04D4A76DC670BDE19")] public interface IEcsProcess : IEcsMember { } namespace RunnersCore @@ -69,7 +69,7 @@ namespace DCFApixels.DragonECS [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "...")] [MetaTags(MetaTags.HIDDEN)] - [MetaID("E49B557C92010E46DF1602972BC988BC")] + [MetaID("DragonECS_E49B557C92010E46DF1602972BC988BC")] public interface IEcsRunner : IEcsProcess { EcsPipeline Pipeline { get; } @@ -84,7 +84,7 @@ namespace DCFApixels.DragonECS [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.OTHER_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "...")] [MetaTags(MetaTags.HIDDEN)] - [MetaID("7DB3557C9201F85E0E1C17D7B19D9CEE")] + [MetaID("DragonECS_7DB3557C9201F85E0E1C17D7B19D9CEE")] public abstract class EcsRunner : EcsRunner, IEcsRunner, IEcsProcess where TProcess : IEcsProcess { diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 25015ad..9c5d932 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -48,7 +48,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.WORLDS_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "Container for entities and components.")] - [MetaID("AEF3557C92019C976FC48F90E95A9DA6")] + [MetaID("DragonECS_AEF3557C92019C976FC48F90E95A9DA6")] [DebuggerTypeProxy(typeof(DebuggerProxy))] public partial class EcsWorld : IEntityStorage, IEcsMember, INamedMember { diff --git a/src/Injections/Utils/Interfaces.cs b/src/Injections/Utils/Interfaces.cs index 14f07f0..6a8a18b 100644 --- a/src/Injections/Utils/Interfaces.cs +++ b/src/Injections/Utils/Interfaces.cs @@ -9,7 +9,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DI_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "The interface of the dependency injection process.")] - [MetaID("4C86537C92019AA24383CBF53CBD456C")] + [MetaID("DragonECS_4C86537C92019AA24383CBF53CBD456C")] public interface IEcsInject : IEcsInjectProcess { void Inject(T obj); @@ -22,7 +22,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.DI_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "The process interface that signals the completion of injection during pipeline initialization via the EcsPipeline.Init() method.")] - [MetaID("05C3537C920155AFC044C900E4F17D90")] + [MetaID("DragonECS_05C3537C920155AFC044C900E4F17D90")] public interface IOnInitInjectionComplete : IEcsProcess { void OnBeforeInitInjection(); diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index 73c9714..26f1793 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -20,7 +20,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "Standard component.")] - [MetaID("84D2537C9201D6F6B92FEC1C8883A07A")] + [MetaID("DragonECS_84D2537C9201D6F6B92FEC1C8883A07A")] public interface IEcsComponent : IEcsMember { } /// Pool for IEcsComponent components @@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "Pool for IEcsComponent components.")] - [MetaID("C501547C9201A4B03FC25632E4FAAFD7")] + [MetaID("DragonECS_C501547C9201A4B03FC25632E4FAAFD7")] [DebuggerDisplay("Count: {Count} Type: {ComponentType}")] public sealed class EcsPool : IEcsPoolImplementation, IEcsStructPool, IEnumerable //IEnumerable - IntelliSense hack where T : struct, IEcsComponent diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs index 172f933..cdb1948 100644 --- a/src/Pools/EcsPoolBase.cs +++ b/src/Pools/EcsPoolBase.cs @@ -74,7 +74,7 @@ namespace DCFApixels.DragonECS.Internal [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "A placeholder type, an instance of this type replaces the null ref.")] [MetaTags(MetaTags.HIDDEN)] - [MetaID("460E547C9201227A4956AC297F67B484")] + [MetaID("DragonECS_460E547C9201227A4956AC297F67B484")] [DebuggerDisplay("-")] public sealed class EcsNullPool : IEcsPoolImplementation { diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index 74d5f28..ffd32ac 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -20,7 +20,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "Tag component or component without data.")] - [MetaID("8D3E547C92013C6A2C2DFC8D2F1FA297")] + [MetaID("DragonECS_8D3E547C92013C6A2C2DFC8D2F1FA297")] public interface IEcsTagComponent : IEcsMember { } /// Pool for IEcsTagComponent components. @@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS [MetaColor(MetaColor.DragonRose)] [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "Pool for IEcsTagComponent components. EcsTagPool is optimized for storing tag components or components without data.")] - [MetaID("9D80547C9201E852E4F17324EAC1E15A")] + [MetaID("DragonECS_9D80547C9201E852E4F17324EAC1E15A")] [DebuggerDisplay("Count: {Count} Type: {ComponentType}")] public sealed class EcsTagPool : IEcsPoolImplementation, IEcsStructPool, IEnumerable //IEnumerable - IntelliSense hack where T : struct, IEcsTagComponent diff --git a/src/Utils/EcsPipelineTemplate.cs b/src/Utils/EcsPipelineTemplate.cs index d24b065..59617df 100644 --- a/src/Utils/EcsPipelineTemplate.cs +++ b/src/Utils/EcsPipelineTemplate.cs @@ -13,7 +13,7 @@ namespace DCFApixels.DragonECS [MetaTags(MetaTags.HIDDEN)] [MetaDescription(AUTHOR, "...")] [MetaGroup(PACK_GROUP, OTHER_GROUP)] - [MetaID("128D547C9201EEAC49B05F89E4A253DF")] + [MetaID("DragonECS_128D547C9201EEAC49B05F89E4A253DF")] [MetaColor(MetaColor.DragonRose)] public class EcsPipelineTemplate : IEcsModule { From ea679594f158d3fd1a428d3059d2093c500f964a Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 19 Mar 2025 16:32:25 +0800 Subject: [PATCH 12/50] add IEcsComponentMember --- src/Pools/EcsPool.cs | 2 +- src/Pools/EcsTagPool.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index 26f1793..b88a319 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -21,7 +21,7 @@ namespace DCFApixels.DragonECS [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "Standard component.")] [MetaID("DragonECS_84D2537C9201D6F6B92FEC1C8883A07A")] - public interface IEcsComponent : IEcsMember { } + public interface IEcsComponent : IEcsComponentMember { } /// Pool for IEcsComponent components #if ENABLE_IL2CPP diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index ffd32ac..8f1f0b4 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -21,7 +21,7 @@ namespace DCFApixels.DragonECS [MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)] [MetaDescription(EcsConsts.AUTHOR, "Tag component or component without data.")] [MetaID("DragonECS_8D3E547C92013C6A2C2DFC8D2F1FA297")] - public interface IEcsTagComponent : IEcsMember { } + public interface IEcsTagComponent : IEcsComponentMember { } /// Pool for IEcsTagComponent components. #if ENABLE_IL2CPP From d1a874e62e3cc4f03fbf60baf46094605ae647a5 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 19 Mar 2025 16:51:08 +0800 Subject: [PATCH 13/50] remove MetaID.IsFixedNameType --- .../MetaAttributes/MetaIDAttribute.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs index be810e0..8e57fff 100644 --- a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs @@ -37,18 +37,18 @@ namespace DCFApixels.DragonECS { public const string ALLOWED_CHARSET = "_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - public static bool IsFixedNameType(Type type) - { - if (type.IsPrimitive) - { - return true; - } - if(type == typeof(string)) - { - return true; - } - return false; - } + //public static bool IsFixedNameType(Type type) + //{ + // if (type.IsPrimitive) + // { + // return true; + // } + // if(type == typeof(string)) + // { + // return true; + // } + // return false; + //} public static bool IsGenericID(string id) { return Regex.IsMatch(id, @"^[^,<>\s]*$"); From 78b49e3f7bbd54171beb4b1507a87bc55b289b17 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 20 Mar 2025 10:55:43 +0800 Subject: [PATCH 14/50] update metaID --- .../MetaAttributes/MetaIDAttribute.cs | 24 +++++++++++++----- src/DebugUtils/TypeMeta.cs | 25 +++++++++++++++++-- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs index 8e57fff..7ccdaef 100644 --- a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs @@ -51,11 +51,11 @@ namespace DCFApixels.DragonECS //} public static bool IsGenericID(string id) { - return Regex.IsMatch(id, @"^[^,<>\s]*$"); + return id[id.Length - 1] == '>' || Regex.IsMatch(id, @"^[^,<>\s]*$"); } - public static bool IsValidID(string input) + public static bool IsValidID(string id) { - return input[input.Length - 1] == '>' || Regex.IsMatch(input, @"^[a-zA-Z0-9_]+$"); + return Regex.IsMatch(id, @"^[a-zA-Z0-9_]+$"); } @@ -153,7 +153,7 @@ namespace DCFApixels.DragonECS #region CollisionList [DebuggerTypeProxy(typeof(DebuggerProxy))] - [DebuggerDisplay("HasAnyCollision: {IsHasAnyCollision} ListsCount: {ListsCount}")] + [DebuggerDisplay("HasAnyCollision: {IsHasAnyCollision} ListsCount: {Count}")] public class CollisionList : IEnumerable { private LinkedList[] _linkedLists; @@ -193,6 +193,7 @@ namespace DCFApixels.DragonECS _listsCount = 0; foreach (var meta in metas) { + if (meta.IsHasMetaID() == false) { continue; } if (listIndexes.TryGetValue(meta.MetaID, out int headIndex)) { hasCollision = true; @@ -281,6 +282,7 @@ namespace DCFApixels.DragonECS #endregion [DebuggerDisplay("Count: {Count}")] + [DebuggerTypeProxy(typeof(DebuggerProxy))] public readonly struct Collision : IEnumerable { private readonly CollisionList _collisions; @@ -298,7 +300,7 @@ namespace DCFApixels.DragonECS internal Collision(CollisionList collisions, int head, int count) { _collisions = collisions; - if(count == 0) + if (count == 0) { _head = 0; _metaID = string.Empty; @@ -346,8 +348,18 @@ namespace DCFApixels.DragonECS } } #endregion - } + #region DebuggerProxy + private class DebuggerProxy + { + public Type[] Types; + public DebuggerProxy(Collision collision) + { + Types = collision.Select(o => o.Type).ToArray(); + } + } + #endregion + } #region DebuggerProxy private class DebuggerProxy { diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index bdbb7d2..bca81fe 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -6,6 +6,7 @@ using DCFApixels.DragonECS.Internal; using DCFApixels.DragonECS.PoolsCore; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Linq; #if DEBUG || !REFLECTION_DISABLED @@ -275,6 +276,7 @@ namespace DCFApixels.DragonECS return _metaID; } } + public bool IsHasMetaID() { return string.IsNullOrEmpty(MetaID) == false; } #endregion #region TypeCode @@ -381,7 +383,17 @@ namespace DCFApixels.DragonECS return false; #endif } - public static bool IsHasMeta(Type type) + public static bool TryGetCustomMeta(Type type, out TypeMeta meta) + { + if (IsHasCustomMeta(type)) + { + meta = type.ToMeta(); + return true; + } + meta = null; + return false; + } + public static bool IsHasCustomMeta(Type type) { #if DEBUG || !REFLECTION_DISABLED return CheckEcsMemener(type) || Attribute.GetCustomAttributes(type, typeof(EcsMetaAttribute), false).Length > 0; @@ -393,7 +405,7 @@ namespace DCFApixels.DragonECS public static bool IsHasMetaID(Type type) { #if DEBUG || !REFLECTION_DISABLED - return type.HasAttribute(); + return TryGetCustomMeta(type, out TypeMeta meta) && meta.IsHasMetaID(); #else EcsDebug.PrintWarning($"Reflection is not available, the {nameof(TypeMeta)}.{nameof(IsHasMetaID)} method does not work."); return false; @@ -449,6 +461,15 @@ namespace DCFApixels.DragonECS } #endregion + #region Obsolete + [Obsolete("Use TryGetCustomMeta(type)")] + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsHasMeta(Type type) + { + return IsHasCustomMeta(type); + } + #endregion + #region MetaGenerator private static class MetaGenerator { From 6865955a568f91623a6c12b1d1b6d7eca0dda03f Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 20 Mar 2025 10:55:57 +0800 Subject: [PATCH 15/50] add pool.NewEntityLong --- src/Pools/EcsPoolBase.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs index cdb1948..8990cb5 100644 --- a/src/Pools/EcsPoolBase.cs +++ b/src/Pools/EcsPoolBase.cs @@ -261,6 +261,12 @@ namespace DCFApixels.DragonECS entityID = self.World.NewEntity(); return ref self.Add(entityID); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref T NewEntityLong(this IEcsStructPool self, out entlong entity) where T : struct + { + entity = self.World.NewEntityLong(); + return ref self.Add(entity.GetIDUnchecked()); + } } #endregion From 9078b8da323c45d400f46b2683c50fb6a57a37a5 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 20 Mar 2025 10:56:18 +0800 Subject: [PATCH 16/50] add [HideInCallstack] for EcsDebug --- src/DebugUtils/EcsDebug.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/DebugUtils/EcsDebug.cs b/src/DebugUtils/EcsDebug.cs index c3fd1ec..d25ffeb 100644 --- a/src/DebugUtils/EcsDebug.cs +++ b/src/DebugUtils/EcsDebug.cs @@ -91,6 +91,9 @@ namespace DCFApixels.DragonECS DebugService.Set(service); } +#if UNITY_2021_3_OR_NEWER + [HideInCallstack] +#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void PrintWarning(object v) { @@ -99,6 +102,9 @@ namespace DCFApixels.DragonECS DebugService.CurrentThreadInstance.PrintWarning(v); #endif } +#if UNITY_2021_3_OR_NEWER + [HideInCallstack] +#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void PrintError(object v) { @@ -107,6 +113,9 @@ namespace DCFApixels.DragonECS DebugService.CurrentThreadInstance.PrintError(v); #endif } +#if UNITY_2021_3_OR_NEWER + [HideInCallstack] +#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void PrintErrorAndBreak(object v) { @@ -115,6 +124,9 @@ namespace DCFApixels.DragonECS DebugService.CurrentThreadInstance.PrintErrorAndBreak(v); #endif } +#if UNITY_2021_3_OR_NEWER + [HideInCallstack] +#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void PrintPass(object v) { @@ -123,6 +135,9 @@ namespace DCFApixels.DragonECS DebugService.CurrentThreadInstance.PrintPass(v); #endif } +#if UNITY_2021_3_OR_NEWER + [HideInCallstack] +#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Print() { @@ -131,6 +146,9 @@ namespace DCFApixels.DragonECS DebugService.CurrentThreadInstance.Print(); #endif } +#if UNITY_2021_3_OR_NEWER + [HideInCallstack] +#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Print(object v) { @@ -139,6 +157,9 @@ namespace DCFApixels.DragonECS DebugService.CurrentThreadInstance.Print(v); #endif } +#if UNITY_2021_3_OR_NEWER + [HideInCallstack] +#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Print(string tag, object v) { From 88328d354c3b900f1f09fe2fd64c9b181c733408 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 20 Mar 2025 13:36:37 +0800 Subject: [PATCH 17/50] update MetaID.CollisionList --- src/DebugUtils/MetaAttributes/MetaIDAttribute.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs index 7ccdaef..c42f9bf 100644 --- a/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaIDAttribute.cs @@ -160,6 +160,8 @@ namespace DCFApixels.DragonECS private Entry[] _entries; private int _collisionsCount; private int _listsCount; + private HashSet _collidingIDs; + public int CollisionsCount { get { return _collisionsCount; } @@ -181,6 +183,15 @@ namespace DCFApixels.DragonECS } } + public bool IsCollidingID(string id) + { + if(_collidingIDs== null) + { + return false; + } + return _collidingIDs.Contains(id); + } + public CollisionList(IEnumerable metas) { var metasCount = metas.Count(); @@ -223,6 +234,7 @@ namespace DCFApixels.DragonECS if (hasCollision) { + _collidingIDs = new HashSet(); for (int i = 0; i < _listsCount; i++) { ref var list = ref _linkedLists[i]; @@ -231,6 +243,10 @@ namespace DCFApixels.DragonECS _linkedLists[i--] = _linkedLists[--_listsCount]; } } + for (int i = 0; i < _listsCount; i++) + { + _collidingIDs.Add(this[i].MetaID); + } } else { From a7aa1cd4cb055b9258de734f6effca172ef809e6 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Thu, 20 Mar 2025 17:05:34 +0800 Subject: [PATCH 18/50] fix --- src/DebugUtils/EcsDebug.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/DebugUtils/EcsDebug.cs b/src/DebugUtils/EcsDebug.cs index d25ffeb..1f24b1d 100644 --- a/src/DebugUtils/EcsDebug.cs +++ b/src/DebugUtils/EcsDebug.cs @@ -92,7 +92,7 @@ namespace DCFApixels.DragonECS } #if UNITY_2021_3_OR_NEWER - [HideInCallstack] + [UnityEngine.HideInCallstack] #endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void PrintWarning(object v) @@ -103,7 +103,7 @@ namespace DCFApixels.DragonECS #endif } #if UNITY_2021_3_OR_NEWER - [HideInCallstack] + [UnityEngine.HideInCallstack] #endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void PrintError(object v) @@ -114,7 +114,7 @@ namespace DCFApixels.DragonECS #endif } #if UNITY_2021_3_OR_NEWER - [HideInCallstack] + [UnityEngine.HideInCallstack] #endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void PrintErrorAndBreak(object v) @@ -125,7 +125,7 @@ namespace DCFApixels.DragonECS #endif } #if UNITY_2021_3_OR_NEWER - [HideInCallstack] + [UnityEngine.HideInCallstack] #endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void PrintPass(object v) @@ -136,7 +136,7 @@ namespace DCFApixels.DragonECS #endif } #if UNITY_2021_3_OR_NEWER - [HideInCallstack] + [UnityEngine.HideInCallstack] #endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Print() @@ -147,7 +147,7 @@ namespace DCFApixels.DragonECS #endif } #if UNITY_2021_3_OR_NEWER - [HideInCallstack] + [UnityEngine.HideInCallstack] #endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Print(object v) @@ -158,7 +158,7 @@ namespace DCFApixels.DragonECS #endif } #if UNITY_2021_3_OR_NEWER - [HideInCallstack] + [UnityEngine.HideInCallstack] #endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Print(string tag, object v) From 940e51d77aff3819fe6c19be508accc4961167bc Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 21 Mar 2025 14:32:21 +0800 Subject: [PATCH 19/50] Update EcsDebug.cs --- src/DebugUtils/EcsDebug.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/DebugUtils/EcsDebug.cs b/src/DebugUtils/EcsDebug.cs index 1f24b1d..884adc6 100644 --- a/src/DebugUtils/EcsDebug.cs +++ b/src/DebugUtils/EcsDebug.cs @@ -228,7 +228,7 @@ namespace DCFApixels.DragonECS } #endregion - #region Constructors + #region Static Constructor static DebugService() { Set(new DefaultDebugService()); @@ -262,15 +262,17 @@ namespace DCFApixels.DragonECS { service.OnNewProfilerMark(record.Value, record.Key); } - service.OnServiceSetup(oldService); + oldService.OnDisableBaseService(service); + service.OnEnableBaseService(oldService); OnServiceChanged(service); } } } #endregion - #region OnServiceSetup/CreateThreadInstance - protected virtual void OnServiceSetup(DebugService oldService) { } + #region OnEnable/OnDisable/CreateThreadInstance + protected virtual void OnEnableBaseService(DebugService prevService) { } + protected virtual void OnDisableBaseService(DebugService nextService) { } protected abstract DebugService CreateThreadInstance(); #endregion @@ -349,9 +351,11 @@ namespace DCFApixels.DragonECS } #endregion - public static OnServiceChangedHandler OnServiceChanged = delegate { }; + #region Events + public static event OnServiceChangedHandler OnServiceChanged = delegate { }; public delegate void OnServiceChangedHandler(DebugService service); + #endregion } public static class DebugServiceExtensions { From a580adffa261951ffe18b7761dee9f81b29d090c Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 21 Mar 2025 19:05:01 +0800 Subject: [PATCH 20/50] fix --- src/DebugUtils/EcsDebug.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DebugUtils/EcsDebug.cs b/src/DebugUtils/EcsDebug.cs index 884adc6..fc34c38 100644 --- a/src/DebugUtils/EcsDebug.cs +++ b/src/DebugUtils/EcsDebug.cs @@ -262,7 +262,7 @@ namespace DCFApixels.DragonECS { service.OnNewProfilerMark(record.Value, record.Key); } - oldService.OnDisableBaseService(service); + oldService?.OnDisableBaseService(service); service.OnEnableBaseService(oldService); OnServiceChanged(service); } From aeb0977d74c10c241bdaa24db713e763187db1ec Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 21 Mar 2025 19:52:34 +0800 Subject: [PATCH 21/50] Update EcsTypeCodeManager.cs --- src/Internal/EcsTypeCodeManager.cs | 77 ++++++++++++++---------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/src/Internal/EcsTypeCodeManager.cs b/src/Internal/EcsTypeCodeManager.cs index 52cb11e..d6ec595 100644 --- a/src/Internal/EcsTypeCodeManager.cs +++ b/src/Internal/EcsTypeCodeManager.cs @@ -12,46 +12,6 @@ using Unity.IL2CPP.CompilerServices; namespace DCFApixels.DragonECS.Internal { -#if ENABLE_IL2CPP - [Il2CppSetOption(Option.NullChecks, false)] - [Il2CppSetOption(Option.ArrayBoundsChecks, false)] -#endif - [DebuggerDisplay("{" + nameof(GetDebuggerDisplay) + "(),nq}")] - internal readonly struct EcsTypeCodeKey : IEquatable - { - public readonly Type Type; - public readonly string NameKey; - public EcsTypeCodeKey(Type type, string nameKey) - { - Type = type; - NameKey = nameKey; - } - public bool Equals(EcsTypeCodeKey other) - { - return Type == other.Type && NameKey == other.NameKey; - } - public override bool Equals(object obj) - { - return obj is EcsTypeCodeKey other && Equals(other); - } - public override int GetHashCode() - { - return HashCode.Combine(Type, NameKey); - } - public override string ToString() - { - if (string.IsNullOrEmpty(NameKey)) - { - return Type.ToString(); - } - return $"{Type} {NameKey}"; - } - public static implicit operator EcsTypeCodeKey(Type type) { return new EcsTypeCodeKey(type, string.Empty); } - private string GetDebuggerDisplay() - { - return ToString(); - } - } //TODO разработать возможность ручного устанавливания ID типам. //это может быть полезно как детерминированность для сети #if ENABLE_IL2CPP @@ -83,7 +43,6 @@ namespace DCFApixels.DragonECS.Internal [MethodImpl(MethodImplOptions.AggressiveInlining)] 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 EcsTypeCodeKey FindTypeOfCode(EcsTypeCode typeCode) { foreach (var item in _codes) @@ -123,4 +82,40 @@ namespace DCFApixels.DragonECS.Internal return this.AutoToString(false); } } +#if ENABLE_IL2CPP + [Il2CppSetOption(Option.NullChecks, false)] + [Il2CppSetOption(Option.ArrayBoundsChecks, false)] +#endif + [DebuggerDisplay("{" + nameof(ToString) + "()}")] + internal readonly struct EcsTypeCodeKey : IEquatable + { + public readonly Type Type; + public readonly string NameKey; + public EcsTypeCodeKey(Type type, string nameKey) + { + Type = type; + NameKey = nameKey; + } + public bool Equals(EcsTypeCodeKey other) + { + return Type == other.Type && NameKey == other.NameKey; + } + public override bool Equals(object obj) + { + return obj is EcsTypeCodeKey other && Equals(other); + } + public override int GetHashCode() + { + return HashCode.Combine(Type, NameKey); + } + public override string ToString() + { + if (string.IsNullOrEmpty(NameKey)) + { + return Type.ToString(); + } + return $"{Type} {NameKey}"; + } + public static implicit operator EcsTypeCodeKey(Type type) { return new EcsTypeCodeKey(type, string.Empty); } + } } \ No newline at end of file From d675be71461cb2e36746773b03d18f721a2cc6a6 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 23 Mar 2025 19:19:35 +0800 Subject: [PATCH 22/50] add inheriting for meta color & group --- .../MetaAttributes/MetaColorAttribute.cs | 5 ++ .../MetaAttributes/MetaGroupAttribute.cs | 69 +++++++++++++++---- src/DebugUtils/TypeMeta.cs | 17 +++-- 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs b/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs index 7d5e930..94f3431 100644 --- a/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs @@ -26,6 +26,7 @@ namespace DCFApixels.DragonECS public sealed class MetaColorAttribute : EcsMetaAttribute, IMetaColor { public readonly MetaColor color; + public readonly Type InheritingColorType; #region Properties public byte R @@ -71,6 +72,10 @@ namespace DCFApixels.DragonECS { color = new MetaColor(colorCode, true); } + public MetaColorAttribute(Type inheritingColorType) + { + InheritingColorType = inheritingColorType; + } #endregion } [Serializable] diff --git a/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs b/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs index f2545d7..f94546c 100644 --- a/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs @@ -12,61 +12,102 @@ namespace DCFApixels.DragonECS [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] public sealed class MetaGroupAttribute : EcsMetaAttribute { - public const char SEPARATOR = '/'; - public readonly MetaGroup Data; + public const char SEPARATOR = MetaGroup.SEPARATOR; + public readonly Type InheritingGroupType = null; + public readonly string RelativeName = string.Empty; [Obsolete(EcsMetaAttributeHalper.EMPTY_NO_SENSE_MESSAGE)] - public MetaGroupAttribute() { Data = MetaGroup.Empty; } - public MetaGroupAttribute(string name) { Data = new MetaGroup(name); } - public MetaGroupAttribute(params string[] path) : this(string.Join(SEPARATOR, path)) { } + public MetaGroupAttribute() { } + public MetaGroupAttribute(string name) { RelativeName = name; } + public MetaGroupAttribute(params string[] path) { RelativeName = string.Join(SEPARATOR, path); } + public MetaGroupAttribute(Type inheritingGroupType) { InheritingGroupType = inheritingGroupType; } + public MetaGroupAttribute(Type inheritingGroupType, string relativeName) + { + InheritingGroupType = inheritingGroupType; + RelativeName = relativeName; + } + public MetaGroupAttribute(Type inheritingGroupType, params string[] relativePath) + { + InheritingGroupType = inheritingGroupType; + RelativeName = string.Join(SEPARATOR, relativePath); + } } [DebuggerDisplay("{Name}")] public class MetaGroup { - public const char SEPARATOR = MetaGroupAttribute.SEPARATOR; + public const char SEPARATOR = '/'; + private const string SEPARATOR_STR = "/"; public const string UNGROUPED = ""; private const string PATTERN = @"Module(?=/)"; - public static readonly MetaGroup Empty = new MetaGroup(UNGROUPED); + public static readonly MetaGroup Empty = new MetaGroup(null, UNGROUPED); + public readonly MetaGroup ParentGroup; public readonly string Name; - private string[] _path = null; + private string[] _splited = null; public IReadOnlyCollection Splited { get { - if (_path == null) + if (_splited == null) { - _path = EcsMetaAttributeHalper.Split(SEPARATOR, Name); + _splited = EcsMetaAttributeHalper.Split(SEPARATOR, Name); } - return _path; + return _splited; } } public bool IsEmpty { get { return this == Empty; } } - public MetaGroup(string name) + private MetaGroup(MetaGroup parentGroup, string name) { if (string.IsNullOrEmpty(name)) { Name = UNGROUPED; return; } - name = name.Replace('\\', SEPARATOR); + name = Regex.Replace(name, @"(\s*[\/\\]+\s*)+", SEPARATOR_STR).Trim(); if (name[name.Length - 1] != SEPARATOR) { name += SEPARATOR; } + if (name[0] == SEPARATOR) + { + name = name.Substring(1); + } Name = Regex.Replace(name, PATTERN, ""); Name = string.Intern(Name); } + public static MetaGroup FromName(string name) + { + return FromName(null, name); + } + public static MetaGroup FromName(MetaGroup parentGroup, string name) + { + if(parentGroup == null || parentGroup == Empty) + { + if (string.IsNullOrWhiteSpace(name)) + { + return Empty; + } + return new MetaGroup(null, name); + } + else + { + if (string.IsNullOrWhiteSpace(name)) + { + return new MetaGroup(parentGroup, parentGroup.Name); + } + return new MetaGroup(parentGroup, parentGroup.Name + name); + } + } public static MetaGroup FromNameSpace(Type type) { if (string.IsNullOrWhiteSpace(type.Namespace)) { return Empty; } - return new MetaGroup(type.Namespace.Replace('.', SEPARATOR)); + return new MetaGroup(null, type.Namespace.Replace('.', SEPARATOR)); } public override string ToString() { return Name; } } diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index bca81fe..373482a 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -86,7 +86,7 @@ namespace DCFApixels.DragonECS _typeName = NULL_NAME, _color = new MetaColor(MetaColor.Black), _description = new MetaDescription("", NULL_NAME), - _group = new MetaGroup(""), + _group = MetaGroup.Empty, _tags = Array.Empty(), _metaID = string.Empty, _typeCode = EcsTypeCodeManager.Get(typeof(void)), @@ -508,7 +508,6 @@ namespace DCFApixels.DragonECS #endregion #region GetColor - private static MetaColor AutoColor(TypeMeta meta) { int hash; @@ -522,14 +521,22 @@ namespace DCFApixels.DragonECS } return MetaColor.FromHashCode(hash).UpContrast(); } + private static MetaColor GetColorFromAttribute(MetaColorAttribute atr) + { + if(atr.InheritingColorType == null) + { + return atr.color; + } + return atr.InheritingColorType.ToMeta().Color; + } public static (MetaColor, bool) GetColor(TypeMeta meta) { #if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает bool isCustom = meta.Type.TryGetAttribute(out MetaColorAttribute atr); - return (isCustom ? atr.color : AutoColor(meta), isCustom); + return (isCustom ? GetColorFromAttribute(atr) : AutoColor(meta), isCustom); #else EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetColor)} method does not work."); - return (AutoColor(type), false); + return (MetaColor.White, false); #endif } #endregion @@ -538,7 +545,7 @@ namespace DCFApixels.DragonECS public static MetaGroup GetGroup(Type type) { #if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает - return type.TryGetAttribute(out MetaGroupAttribute atr) ? atr.Data : MetaGroup.FromNameSpace(type); + return type.TryGetAttribute(out MetaGroupAttribute atr) ? MetaGroup.FromName(atr.InheritingGroupType.GetMeta().Group, atr.RelativeName) : MetaGroup.FromNameSpace(type); #else EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetGroup)} method does not work."); return MetaGroup.Empty; From 3e59e7a5bd0b4946e41922791f8314a429a07506 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 23 Mar 2025 21:12:43 +0800 Subject: [PATCH 23/50] remove inheriting meta --- .../MetaAttributes/MetaColorAttribute.cs | 5 -- .../MetaAttributes/MetaGroupAttribute.cs | 46 ++++--------------- src/DebugUtils/TypeMeta.cs | 19 ++++---- 3 files changed, 18 insertions(+), 52 deletions(-) diff --git a/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs b/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs index 94f3431..7d5e930 100644 --- a/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaColorAttribute.cs @@ -26,7 +26,6 @@ namespace DCFApixels.DragonECS public sealed class MetaColorAttribute : EcsMetaAttribute, IMetaColor { public readonly MetaColor color; - public readonly Type InheritingColorType; #region Properties public byte R @@ -72,10 +71,6 @@ namespace DCFApixels.DragonECS { color = new MetaColor(colorCode, true); } - public MetaColorAttribute(Type inheritingColorType) - { - InheritingColorType = inheritingColorType; - } #endregion } [Serializable] diff --git a/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs b/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs index f94546c..832c3da 100644 --- a/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs +++ b/src/DebugUtils/MetaAttributes/MetaGroupAttribute.cs @@ -13,24 +13,12 @@ namespace DCFApixels.DragonECS public sealed class MetaGroupAttribute : EcsMetaAttribute { public const char SEPARATOR = MetaGroup.SEPARATOR; - public readonly Type InheritingGroupType = null; - public readonly string RelativeName = string.Empty; + public readonly string Name = string.Empty; [Obsolete(EcsMetaAttributeHalper.EMPTY_NO_SENSE_MESSAGE)] public MetaGroupAttribute() { } - public MetaGroupAttribute(string name) { RelativeName = name; } - public MetaGroupAttribute(params string[] path) { RelativeName = string.Join(SEPARATOR, path); } - public MetaGroupAttribute(Type inheritingGroupType) { InheritingGroupType = inheritingGroupType; } - public MetaGroupAttribute(Type inheritingGroupType, string relativeName) - { - InheritingGroupType = inheritingGroupType; - RelativeName = relativeName; - } - public MetaGroupAttribute(Type inheritingGroupType, params string[] relativePath) - { - InheritingGroupType = inheritingGroupType; - RelativeName = string.Join(SEPARATOR, relativePath); - } + public MetaGroupAttribute(string name) { Name = name; } + public MetaGroupAttribute(params string[] path) { Name = string.Join(SEPARATOR, path); } } [DebuggerDisplay("{Name}")] public class MetaGroup @@ -39,9 +27,8 @@ namespace DCFApixels.DragonECS private const string SEPARATOR_STR = "/"; public const string UNGROUPED = ""; private const string PATTERN = @"Module(?=/)"; - public static readonly MetaGroup Empty = new MetaGroup(null, UNGROUPED); + public static readonly MetaGroup Empty = new MetaGroup(UNGROUPED); - public readonly MetaGroup ParentGroup; public readonly string Name; private string[] _splited = null; public IReadOnlyCollection Splited @@ -59,7 +46,7 @@ namespace DCFApixels.DragonECS { get { return this == Empty; } } - private MetaGroup(MetaGroup parentGroup, string name) + private MetaGroup(string name) { if (string.IsNullOrEmpty(name)) { @@ -80,26 +67,11 @@ namespace DCFApixels.DragonECS } public static MetaGroup FromName(string name) { - return FromName(null, name); - } - public static MetaGroup FromName(MetaGroup parentGroup, string name) - { - if(parentGroup == null || parentGroup == Empty) + if (string.IsNullOrWhiteSpace(name)) { - if (string.IsNullOrWhiteSpace(name)) - { - return Empty; - } - return new MetaGroup(null, name); - } - else - { - if (string.IsNullOrWhiteSpace(name)) - { - return new MetaGroup(parentGroup, parentGroup.Name); - } - return new MetaGroup(parentGroup, parentGroup.Name + name); + return Empty; } + return new MetaGroup(name); } public static MetaGroup FromNameSpace(Type type) { @@ -107,7 +79,7 @@ namespace DCFApixels.DragonECS { return Empty; } - return new MetaGroup(null, type.Namespace.Replace('.', SEPARATOR)); + return new MetaGroup(type.Namespace.Replace('.', SEPARATOR)); } public override string ToString() { return Name; } } diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index 373482a..ca26c08 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -521,19 +521,11 @@ namespace DCFApixels.DragonECS } return MetaColor.FromHashCode(hash).UpContrast(); } - private static MetaColor GetColorFromAttribute(MetaColorAttribute atr) - { - if(atr.InheritingColorType == null) - { - return atr.color; - } - return atr.InheritingColorType.ToMeta().Color; - } public static (MetaColor, bool) GetColor(TypeMeta meta) { #if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает bool isCustom = meta.Type.TryGetAttribute(out MetaColorAttribute atr); - return (isCustom ? GetColorFromAttribute(atr) : AutoColor(meta), isCustom); + return (isCustom ? atr.color : AutoColor(meta), isCustom); #else EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetColor)} method does not work."); return (MetaColor.White, false); @@ -545,7 +537,14 @@ namespace DCFApixels.DragonECS public static MetaGroup GetGroup(Type type) { #if DEBUG || !REFLECTION_DISABLED //в дебажных утилитах REFLECTION_DISABLED только в релизном билде работает - return type.TryGetAttribute(out MetaGroupAttribute atr) ? MetaGroup.FromName(atr.InheritingGroupType.GetMeta().Group, atr.RelativeName) : MetaGroup.FromNameSpace(type); + if (type.TryGetAttribute(out MetaGroupAttribute atr)) + { + return MetaGroup.FromName(atr.Name); + } + else + { + return MetaGroup.FromNameSpace(type); + } #else EcsDebug.PrintWarning($"Reflection is not available, the {nameof(MetaGenerator)}.{nameof(GetGroup)} method does not work."); return MetaGroup.Empty; From dd8b126c27de2bbcb407717263541e928c813c92 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 23 Mar 2025 21:12:58 +0800 Subject: [PATCH 24/50] add deep debug for GetMeta --- src/DebugUtils/EcsDebugUtility.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DebugUtils/EcsDebugUtility.cs b/src/DebugUtils/EcsDebugUtility.cs index 9d9e3ed..f7303dd 100644 --- a/src/DebugUtils/EcsDebugUtility.cs +++ b/src/DebugUtils/EcsDebugUtility.cs @@ -1,6 +1,7 @@ #if DISABLE_DEBUG #undef DEBUG #endif +using DCFApixels.DragonECS.Internal; using System; using System.Collections.Generic; #if DEBUG || !REFLECTION_DISABLED @@ -312,6 +313,9 @@ namespace DCFApixels.DragonECS { public static TypeMeta GetMeta(this object self) { +#if DEBUG && DRAGONECS_DEEP_DEBUG + if (self is Type type) { Throw.DeepDebugException(); } +#endif return EcsDebugUtility.GetTypeMeta(self); } public static TypeMeta ToMeta(this Type self) From 615d2014241dcdc56dd245c48f127f8e3be9fe16 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 24 Mar 2025 14:26:40 +0800 Subject: [PATCH 25/50] refactoring --- src/DebugUtils/EcsDebug.cs | 48 ++++++++++++++++++++---------- src/DebugUtils/TypeMeta.cs | 4 +-- src/EcsAspect.cs | 2 +- src/EcsPipeline.cs | 14 ++++----- src/EcsWorld.cs | 16 +++------- src/EcsWorld.static.cs | 9 +++--- src/Internal/ArrayUtility.cs | 33 ++++++++++++++++++++ src/Internal/EcsTypeCodeManager.cs | 2 +- src/Internal/UnsafeArray.cs | 1 + 9 files changed, 86 insertions(+), 43 deletions(-) diff --git a/src/DebugUtils/EcsDebug.cs b/src/DebugUtils/EcsDebug.cs index fc34c38..0f5608e 100644 --- a/src/DebugUtils/EcsDebug.cs +++ b/src/DebugUtils/EcsDebug.cs @@ -1,16 +1,18 @@ #if DISABLE_DEBUG #undef DEBUG #endif +using DCFApixels.DragonECS.Core; using DCFApixels.DragonECS.Internal; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; +using static DCFApixels.DragonECS.EcsConsts; namespace DCFApixels.DragonECS { - using static EcsConsts; + #region EcsProfilerMarker public readonly struct EcsProfilerMarker { #if DEBUG || DRAGONECS_ENABLE_DEBUG_SERVICE @@ -75,6 +77,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator EcsProfilerMarker(string markerName) { return new EcsProfilerMarker(markerName); } } + #endregion [MetaColor(MetaColor.DragonRose)] [MetaGroup(PACK_GROUP, DEBUG_GROUP)] @@ -82,6 +85,7 @@ namespace DCFApixels.DragonECS [MetaID("DragonECS_10A4587C92013B55820D8604D718A1C3")] public static class EcsDebug { + #region Set public static void Set() where T : DebugService, new() { DebugService.Set(); @@ -90,7 +94,9 @@ namespace DCFApixels.DragonECS { DebugService.Set(service); } + #endregion + #region Print #if UNITY_2021_3_OR_NEWER [UnityEngine.HideInCallstack] #endif @@ -168,6 +174,9 @@ namespace DCFApixels.DragonECS DebugService.CurrentThreadInstance.Print(tag, v); #endif } + #endregion + + #region Other [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Break() { @@ -175,9 +184,12 @@ namespace DCFApixels.DragonECS DebugService.CurrentThreadInstance.Break(); #endif } + #endregion + #region Events public static OnPrintHandler OnPrint = delegate { }; public delegate void OnPrintHandler(string tag, object v); + #endregion } //------------------------------------------------------------------------------------------------------------// @@ -185,19 +197,23 @@ namespace DCFApixels.DragonECS public abstract class DebugService { private static DebugService _instance; - private static object _lock = new object(); + private readonly static object _lock = new object(); - private static HashSet _threadServiceClonesSet = new HashSet(); + private readonly static HashSet _threadServiceClonesSet = new HashSet(); [ThreadStatic] private static DebugService _currentThreadInstanceClone; [ThreadStatic] private static DebugService _currentThreadInstance; // для сравнения - private static IdDispenser _idDispenser = new IdDispenser(16, 0); - private static Dictionary _nameIdTable = new Dictionary(); + private readonly static IdDispenser _idDispenser = new IdDispenser(16, 0); + private readonly static Dictionary _nameIdTable = new Dictionary(); #region Properties + public static bool IsNullOrDefault + { + get { return _instance == null || _instance is NullDebugService || _instance is DefaultDebugService; } + } public static DebugService Instance { get { return _instance; } @@ -231,7 +247,11 @@ namespace DCFApixels.DragonECS #region Static Constructor static DebugService() { +#if !UNITY_5_3_OR_NEWER + Set(new NullDebugService()); +#else Set(new DefaultDebugService()); +#endif } #endregion @@ -357,6 +377,11 @@ namespace DCFApixels.DragonECS public delegate void OnServiceChangedHandler(DebugService service); #endregion } +} + +namespace DCFApixels.DragonECS.Core +{ + #region DebugServiceExtensions public static class DebugServiceExtensions { public static void PrintWarning(this DebugService self, object v) @@ -386,7 +411,9 @@ namespace DCFApixels.DragonECS } //TODO PrintJson возможно будет добавлено когда-то } + #endregion + #region DefaultServices //------------------------------------------------------------------------------------------------------------// public sealed class NullDebugService : DebugService @@ -404,7 +431,6 @@ namespace DCFApixels.DragonECS public sealed class DefaultDebugService : DebugService { -#if !UNITY_5_3_OR_NEWER private const string PROFILER_MARKER = "ProfilerMark"; private const string PROFILER_MARKER_CACHE = "[" + PROFILER_MARKER + "] "; @@ -573,14 +599,6 @@ namespace DCFApixels.DragonECS return this.AutoToString(); } } -#else - protected sealed override DebugService CreateThreadInstance() { return this; } - public sealed override void Break() { } - public sealed override void Print(string tag, object v) { } - public sealed override void ProfilerMarkBegin(int id) { } - public sealed override void ProfilerMarkEnd(int id) { } - protected sealed override void OnDelProfilerMark(int id) { } - protected sealed override void OnNewProfilerMark(int id, string name) { } -#endif } + #endregion } \ No newline at end of file diff --git a/src/DebugUtils/TypeMeta.cs b/src/DebugUtils/TypeMeta.cs index ca26c08..8eceb19 100644 --- a/src/DebugUtils/TypeMeta.cs +++ b/src/DebugUtils/TypeMeta.cs @@ -45,7 +45,7 @@ namespace DCFApixels.DragonECS private const string NULL_NAME = "NULL"; public static readonly TypeMeta NullTypeMeta; - private static object _lock = new object(); + private static readonly object _lock = new object(); private static readonly Dictionary _metaCache = new Dictionary(); private static int _increment = 1; @@ -84,7 +84,7 @@ namespace DCFApixels.DragonECS _name = NULL_NAME, _typeName = NULL_NAME, - _color = new MetaColor(MetaColor.Black), + _color = MetaColor.Black, _description = new MetaDescription("", NULL_NAME), _group = MetaGroup.Empty, _tags = Array.Empty(), diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index 13f38e4..c1dc6e1 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -125,7 +125,7 @@ namespace DCFApixels.DragonECS #endregion //Инициализация аспектов проходит в синхронизированном состоянии, поэтому использование _staticMaskCache потоко безопасно. - private static Dictionary _staticMaskCache = new Dictionary(); + private readonly static Dictionary _staticMaskCache = new Dictionary(); internal EcsWorld _source; internal EcsMask _mask; diff --git a/src/EcsPipeline.cs b/src/EcsPipeline.cs index ca8af5f..0bebeec 100644 --- a/src/EcsPipeline.cs +++ b/src/EcsPipeline.cs @@ -114,20 +114,18 @@ namespace DCFApixels.DragonECS private static IEcsProcess[] _buffer; private T[] CreateProcess() where T : IEcsProcess { - if (_buffer == null || _buffer.Length < _allSystems.Length) - { - Array.Resize(ref _buffer, _allSystems.Length); - } - int l = 0; + ArrayUtility.UpsizeWithoutCopy(ref _buffer, _allSystems.Length); + int bufferLength = 0; for (int i = 0, iMax = _allSystems.Length; i < iMax; i++) { if (_allSystems[i] is T) { - _buffer[l++] = _allSystems[i]; + _buffer[bufferLength++] = _allSystems[i]; } } - T[] result = new T[l]; - Array.Copy(_buffer, result, l); + T[] result = new T[bufferLength]; + Array.Copy(_buffer, result, bufferLength); + Array.Clear(_buffer, 0, bufferLength); return result; } #endregion diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 9c5d932..8965082 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -955,10 +955,8 @@ namespace DCFApixels.DragonECS public ReadOnlySpan GetComponentsFor(int entityID) { int count = GetComponentTypeIDsFor_Internal(entityID, ref _componentIDsBuffer); - if (_componentsBuffer == null || _componentsBuffer.Length < count) - { - _componentsBuffer = new object[count]; - } + ArrayUtility.UpsizeWithoutCopy(ref _componentIDsBuffer, count); + for (int i = 0; i < count; i++) { _componentsBuffer[i] = _pools[_componentIDsBuffer[i]].GetRaw(entityID); @@ -986,14 +984,7 @@ namespace DCFApixels.DragonECS private unsafe int GetComponentTypeIDsFor_Internal(int entityID, ref int[] componentIDs) { var itemsCount = GetComponentsCount(entityID); - if (componentIDs == null) - { - componentIDs = new int[itemsCount]; - } - if (componentIDs.Length < itemsCount) - { - Array.Resize(ref componentIDs, itemsCount); - } + ArrayUtility.UpsizeWithoutCopy(ref componentIDs, itemsCount); if (itemsCount <= 0) { return 0; } @@ -1170,6 +1161,7 @@ namespace DCFApixels.DragonECS public long Version { get { return _world.Version; } } public IEcsPool[] Pools { get { return _world._pools; } } public short ID { get { return _world.ID; } } + public bool IsDestroyed { get { return _world._isDestroyed; } } public List MaskQueries { get { return _queries; } } public DebuggerProxy(EcsWorld world) { diff --git a/src/EcsWorld.static.cs b/src/EcsWorld.static.cs index cdfe30c..c87882d 100644 --- a/src/EcsWorld.static.cs +++ b/src/EcsWorld.static.cs @@ -26,11 +26,11 @@ namespace DCFApixels.DragonECS private static EcsWorld[] _worlds = Array.Empty(); private static readonly IdDispenser _worldIdDispenser = new IdDispenser(4, 0, n => Array.Resize(ref _worlds, n)); - private static StructList _allWorldComponentPools = new StructList(64); + private static readonly object _worldLock = new object(); + private StructList _worldComponentPools; private int _builtinWorldComponentsCount = 0; - private static readonly object _worldLock = new object(); static EcsWorld() { @@ -92,6 +92,7 @@ namespace DCFApixels.DragonECS } world = null; } + _worlds = Array.Empty(); _worldIdDispenser.ReleaseAll(); } @@ -137,8 +138,8 @@ namespace DCFApixels.DragonECS private static short _count; private static short[] _recycledItems = new short[4]; private static short _recycledItemsCount; - private static IEcsWorldComponent _interface = EcsWorldComponentHandler.instance; - private static Abstract _controller = new Abstract(); + private static readonly IEcsWorldComponent _interface = EcsWorldComponentHandler.instance; + private static readonly Abstract _controller = new Abstract(); static WorldComponentPool() { _allWorldComponentPools.Add(_controller); diff --git a/src/Internal/ArrayUtility.cs b/src/Internal/ArrayUtility.cs index 33dc2a0..16cfb46 100644 --- a/src/Internal/ArrayUtility.cs +++ b/src/Internal/ArrayUtility.cs @@ -134,6 +134,39 @@ namespace DCFApixels.DragonECS.Internal array[i] = value; } } + + + public static void UpsizeWithoutCopy(ref T[] array, int minSize) + { + if (array == null || minSize > array.Length) + { + array = new T[minSize]; + } + } + public static void Upsize(ref T[] array, int minSize) + { + if (array == null) + { + array = new T[minSize]; + } + else if (minSize > array.Length) + { + Array.Resize(ref array, minSize); + } + } + public static void UpsizeToNextPow2(ref T[] array, int minSize) + { + if (array == null) + { + minSize = NextPow2(minSize); + array = new T[minSize]; + } + else if (minSize > array.Length) + { + minSize = NextPow2(minSize); + Array.Resize(ref array, minSize); + } + } } internal readonly struct EnumerableInt : IEnumerable { diff --git a/src/Internal/EcsTypeCodeManager.cs b/src/Internal/EcsTypeCodeManager.cs index d6ec595..1bafb05 100644 --- a/src/Internal/EcsTypeCodeManager.cs +++ b/src/Internal/EcsTypeCodeManager.cs @@ -22,7 +22,7 @@ namespace DCFApixels.DragonECS.Internal { private static readonly Dictionary _codes = new Dictionary(); private static int _increment = 1; - private static object _lock = new object(); + private static readonly object _lock = new object(); public static int Count { [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Internal/UnsafeArray.cs b/src/Internal/UnsafeArray.cs index ad8e385..9f00cbe 100644 --- a/src/Internal/UnsafeArray.cs +++ b/src/Internal/UnsafeArray.cs @@ -44,6 +44,7 @@ namespace DCFApixels.DragonECS.Internal } } } + #if ENABLE_IL2CPP [Il2CppSetOption(Option.NullChecks, false)] [Il2CppSetOption(Option.ArrayBoundsChecks, false)] From 2fa250b64839099ed9773d17cee8755e55ae331e Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 24 Mar 2025 19:29:58 +0800 Subject: [PATCH 26/50] fix --- src/EcsWorld.static.cs | 4 +++- src/Internal/IdDispenser.cs | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/EcsWorld.static.cs b/src/EcsWorld.static.cs index c87882d..9d3b3f9 100644 --- a/src/EcsWorld.static.cs +++ b/src/EcsWorld.static.cs @@ -81,6 +81,7 @@ namespace DCFApixels.DragonECS public static void ResetStaticState() { + var nullworld = _worlds[0]; for (int i = 1; i < _worlds.Length; i++) { var world = _worlds[i]; @@ -92,7 +93,8 @@ namespace DCFApixels.DragonECS } world = null; } - _worlds = Array.Empty(); + _worlds = new EcsWorld[_worldIdDispenser.Capacity]; + _worlds[0] = nullworld; _worldIdDispenser.ReleaseAll(); } diff --git a/src/Internal/IdDispenser.cs b/src/Internal/IdDispenser.cs index 1d4aa21..47e993b 100644 --- a/src/Internal/IdDispenser.cs +++ b/src/Internal/IdDispenser.cs @@ -35,7 +35,7 @@ namespace DCFApixels.DragonECS.Internal [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _usedCount; } } - public int Size + public int Capacity { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _size; } @@ -339,7 +339,7 @@ namespace DCFApixels.DragonECS.Internal { get { - Pair[] result = new Pair[_target.Size]; + Pair[] result = new Pair[_target.Capacity]; for (int i = 0; i < result.Length; i++) { result[i] = new Pair( @@ -354,7 +354,7 @@ namespace DCFApixels.DragonECS.Internal { get { - ID[] result = new ID[_target.Size]; + ID[] result = new ID[_target.Capacity]; for (int i = 0; i < result.Length; i++) { int id = _target._dense[i]; @@ -365,7 +365,7 @@ namespace DCFApixels.DragonECS.Internal } public bool IsValid => _target.IsValid(); public int Count => _target.Count; - public int Size => _target.Size; + public int Capacity => _target.Capacity; public int NullID => _target._nullID; internal readonly struct ID { From 7fbdbcf0246a90680a10051cd6d7bb3e158783f9 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 28 Mar 2025 10:40:49 +0800 Subject: [PATCH 27/50] Update ITemplateNode.cs --- src/Utils/ITemplateNode.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Utils/ITemplateNode.cs b/src/Utils/ITemplateNode.cs index bd5cb8a..ff0392b 100644 --- a/src/Utils/ITemplateNode.cs +++ b/src/Utils/ITemplateNode.cs @@ -20,6 +20,20 @@ namespace DCFApixels.DragonECS self.Apply(worldID, entityID); return (EcsWorld.GetWorld(worldID), entityID); } + public static void Apply(this ITemplateNode self, EcsWorld world, int entityID) + { + self.Apply(world.ID, entityID); + } + public static int ApplyAndReturn(this ITemplateNode self, EcsWorld world, int entityID) + { + self.Apply(world.ID, entityID); + return entityID; + } + public static entlong ApplyAndReturnLong(this ITemplateNode self, EcsWorld world, int entityID) + { + self.Apply(world.ID, entityID); + return (world, entityID); + } public static int NewEntity(this EcsWorld world, ITemplateNode template) { int e = world.NewEntity(); From 2c046a47e57abb73f48d71f854b2cbe39e8e9114 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 28 Mar 2025 11:51:51 +0800 Subject: [PATCH 28/50] update world.IsMatchesMask --- src/EcsWorld.cs | 52 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 8965082..6ed6fe3 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -481,20 +481,60 @@ namespace DCFApixels.DragonECS #elif DRAGONECS_STABILITY_MODE if (mask.WorldID != ID) { return false; } #endif - for (int i = 0, iMax = mask._incs.Length; i < iMax; i++) + + +#if DEBUG && DRAGONECS_DEEP_DEBUG + bool IsMatchesMaskDeepDebug(EcsMask mask_, int entityID_) { - if (!_pools[mask._incs[i]].Has(entityID)) + for (int i = 0, iMax = mask_._incs.Length; i < iMax; i++) { + if (!_pools[mask_._incs[i]].Has(entityID_)) + { + return false; + } + } + for (int i = 0, iMax = mask_._excs.Length; i < iMax; i++) + { + if (_pools[mask_._excs[i]].Has(entityID_)) + { + return false; + } + } + return true; + } + bool deepDebug = IsMatchesMaskDeepDebug(mask, entityID); +#endif + + var incChuncks = mask._incChunckMasks; + var excChuncks = mask._excChunckMasks; + var componentMaskStartIndex = entityID << _entityComponentMaskLengthBitShift; + + for (int i = 0; i < incChuncks.Length; i++) + { + var bit = incChuncks[i]; + if ((_entityComponentMasks[componentMaskStartIndex + bit.chunkIndex] & bit.mask) != bit.mask) + { +#if DEBUG && DRAGONECS_DEEP_DEBUG + if (false != deepDebug) { Throw.DeepDebugException(); } +#endif return false; } } - for (int i = 0, iMax = mask._excs.Length; i < iMax; i++) + for (int i = 0; i < excChuncks.Length; i++) { - if (_pools[mask._excs[i]].Has(entityID)) + var bit = excChuncks[i]; + if ((_entityComponentMasks[componentMaskStartIndex + bit.chunkIndex] & bit.mask) != 0) { +#if DEBUG && DRAGONECS_DEEP_DEBUG + if (false != deepDebug) { Throw.DeepDebugException(); } +#endif return false; } } + +#if DEBUG && DRAGONECS_DEEP_DEBUG + if (true != deepDebug) { Throw.DeepDebugException(); } +#endif return true; } #endregion @@ -999,8 +1039,8 @@ namespace DCFApixels.DragonECS int arrayIndex = 0; for (int chunkIndex = entityID << _entityComponentMaskLengthBitShift, chunkIndexMax = chunkIndex + _entityComponentMaskLength; - chunkIndex < chunkIndexMax; - chunkIndex++) + chunkIndex < chunkIndexMax; + chunkIndex++) { int chunk = _entityComponentMasks[chunkIndex]; if (chunk == 0) From d394ec6b21bcfdadad96f0717be1498285875ca5 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 28 Mar 2025 11:52:18 +0800 Subject: [PATCH 29/50] move IEcsReadonlyPool.Copy to IEcsPool.Copy --- src/Pools/EcsPoolBase.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs index 8990cb5..ec9e23c 100644 --- a/src/Pools/EcsPoolBase.cs +++ b/src/Pools/EcsPoolBase.cs @@ -135,13 +135,13 @@ namespace DCFApixels.DragonECS.Internal throw new NullInstanceException(); #endif } - void IEcsReadonlyPool.Copy(int fromEntityID, int toEntityID) + void IEcsPool.Copy(int fromEntityID, int toEntityID) { #if DEBUG throw new NullInstanceException(); #endif } - void IEcsReadonlyPool.Copy(int fromEntityID, EcsWorld toWorld, int toEntityID) + void IEcsPool.Copy(int fromEntityID, EcsWorld toWorld, int toEntityID) { #if DEBUG throw new NullInstanceException(); @@ -189,11 +189,10 @@ namespace DCFApixels.DragonECS #region Methods bool Has(int entityID); object GetRaw(int entityID); - void Copy(int fromEntityID, int toEntityID); - void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID); #endregion #if !DRAGONECS_DISABLE_POOLS_EVENTS + #region Add/Remove Listeners void AddListener(IEcsPoolEventListener listener); void RemoveListener(IEcsPoolEventListener listener); @@ -209,6 +208,8 @@ namespace DCFApixels.DragonECS void SetRaw(int entityID, object dataRaw); void Del(int entityID); void ClearAll(); + void Copy(int fromEntityID, int toEntityID); + void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID); #endregion } From fad8c48318b6107a573f828f08fe9b762f7b5e67 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 28 Mar 2025 12:10:16 +0800 Subject: [PATCH 30/50] add readonly pool wrappers --- src/Pools/EcsPool.cs | 72 ++++++++++++++++++++++++++++++++++++++-- src/Pools/EcsPoolBase.cs | 7 ++++ src/Pools/EcsTagPool.cs | 71 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 147 insertions(+), 3 deletions(-) diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index b88a319..3345981 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -294,7 +294,7 @@ namespace DCFApixels.DragonECS { Add(entityID) = dataRaw == null ? default : (T)dataRaw; } - object IEcsReadonlyPool.GetRaw(int entityID) { return Get(entityID); } + object IEcsReadonlyPool.GetRaw(int entityID) { return Read(entityID); } void IEcsPool.SetRaw(int entityID, object dataRaw) { Get(entityID) = dataRaw == null ? default : (T)dataRaw; @@ -364,7 +364,7 @@ namespace DCFApixels.DragonECS IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); } #endregion - #region MarkersConverter + #region Convertors public static implicit operator EcsPool(IncludeMarker a) { return a.GetInstance>(); } public static implicit operator EcsPool(ExcludeMarker a) { return a.GetInstance>(); } public static implicit operator EcsPool(OptionalMarker a) { return a.GetInstance>(); } @@ -383,6 +383,74 @@ namespace DCFApixels.DragonECS #endregion } +#if ENABLE_IL2CPP + [Il2CppSetOption(Option.NullChecks, false)] +#endif + public readonly struct ReadonlyEcsPool : IEcsReadonlyPool //IEnumerable - IntelliSense hack + where T : struct, IEcsComponent + { + private readonly EcsPool _pool; + + #region Properties + public int ComponentTypeID + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _pool.ComponentTypeID; } + } + public Type ComponentType + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _pool.ComponentType; } + } + public EcsWorld World + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _pool.World; } + } + public int Count + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _pool.Count; } + } + public bool IsReadOnly + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _pool.IsReadOnly; } + } + #endregion + + #region Constructors + internal ReadonlyEcsPool(EcsPool pool) + { + _pool = pool; + } + #endregion + + #region Methods + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Has(int entityID) { return _pool.Has(entityID); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref readonly T Get(int entityID) { return ref _pool.Read(entityID); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref readonly T Read(int entityID) { return ref _pool.Read(entityID); } + object IEcsReadonlyPool.GetRaw(int entityID) { return _pool.Read(entityID); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RemoveListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); } + #endregion + + #region Convertors + public static implicit operator ReadonlyEcsPool(EcsPool a) { return new ReadonlyEcsPool(a); } + public static implicit operator ReadonlyEcsPool(IncludeMarker a) { return a.GetInstance>(); } + public static implicit operator ReadonlyEcsPool(ExcludeMarker a) { return a.GetInstance>(); } + public static implicit operator ReadonlyEcsPool(OptionalMarker a) { return a.GetInstance>(); } + public static implicit operator ReadonlyEcsPool(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance>(); } + #endregion + } + + public static class EcsPoolExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Pools/EcsPoolBase.cs b/src/Pools/EcsPoolBase.cs index ec9e23c..4793eaf 100644 --- a/src/Pools/EcsPoolBase.cs +++ b/src/Pools/EcsPoolBase.cs @@ -26,6 +26,13 @@ namespace DCFApixels.DragonECS.PoolsCore /// Component type. public interface IEcsPoolImplementation : IEcsPoolImplementation { } + //TODO + //public interface IEcsReadonlyPoolImplementation : IEcsReadonlyPool + // where TPool : IEcsReadonlyPoolImplementation + //{ + // void Init(ref TPool pool); + //} + #region EcsPoolThrowHelper public static class EcsPoolThrowHelper { diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index 8f1f0b4..bade114 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -311,7 +311,7 @@ namespace DCFApixels.DragonECS IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); } #endregion - #region MarkersConverter + #region Convertors public static implicit operator EcsTagPool(IncludeMarker a) { return a.GetInstance>(); } public static implicit operator EcsTagPool(ExcludeMarker a) { return a.GetInstance>(); } public static implicit operator EcsTagPool(OptionalMarker a) { return a.GetInstance>(); } @@ -330,6 +330,75 @@ namespace DCFApixels.DragonECS #endregion } +#if ENABLE_IL2CPP + [Il2CppSetOption(Option.NullChecks, false)] +#endif + public readonly struct ReadonlyEcsTagPool : IEcsReadonlyPool //IEnumerable - IntelliSense hack + where T : struct, IEcsTagComponent + { + private readonly EcsTagPool _pool; + + #region Properties + public int ComponentTypeID + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _pool.ComponentTypeID; } + } + public Type ComponentType + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _pool.ComponentType; } + } + public EcsWorld World + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _pool.World; } + } + public int Count + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _pool.Count; } + } + public bool IsReadOnly + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _pool.IsReadOnly; } + } + #endregion + + #region Constructors + internal ReadonlyEcsTagPool(EcsTagPool pool) + { + _pool = pool; + } + #endregion + + #region Methods + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Has(int entityID) { return _pool.Has(entityID); } + object IEcsReadonlyPool.GetRaw(int entityID) + { +#if DEBUG + if (Has(entityID) == false) { EcsPoolThrowHelper.ThrowNotHaveComponent(entityID); } +#endif + return default; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AddListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void RemoveListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); } + #endregion + + #region Convertors + public static implicit operator ReadonlyEcsTagPool(EcsTagPool a) { return new ReadonlyEcsTagPool(a); } + public static implicit operator ReadonlyEcsTagPool(IncludeMarker a) { return a.GetInstance>(); } + public static implicit operator ReadonlyEcsTagPool(ExcludeMarker a) { return a.GetInstance>(); } + public static implicit operator ReadonlyEcsTagPool(OptionalMarker a) { return a.GetInstance>(); } + public static implicit operator ReadonlyEcsTagPool(EcsWorld.GetPoolInstanceMarker a) { return a.GetInstance>(); } + #endregion + } + public static class EcsTagPoolExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] From 63459776f25e8b7b11d71f3cbe103394f125b870 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 28 Mar 2025 12:12:32 +0800 Subject: [PATCH 31/50] add newer browsable for readonly pool wrappers --- src/Pools/EcsPool.cs | 1 + src/Pools/EcsTagPool.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index 3345981..62a258c 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -386,6 +386,7 @@ namespace DCFApixels.DragonECS #if ENABLE_IL2CPP [Il2CppSetOption(Option.NullChecks, false)] #endif + [EditorBrowsable(EditorBrowsableState.Never)] public readonly struct ReadonlyEcsPool : IEcsReadonlyPool //IEnumerable - IntelliSense hack where T : struct, IEcsComponent { diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index bade114..b8bce1d 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -333,6 +333,7 @@ namespace DCFApixels.DragonECS #if ENABLE_IL2CPP [Il2CppSetOption(Option.NullChecks, false)] #endif + [EditorBrowsable(EditorBrowsableState.Never)] public readonly struct ReadonlyEcsTagPool : IEcsReadonlyPool //IEnumerable - IntelliSense hack where T : struct, IEcsTagComponent { From c36642ad8389b2522b03b93351b9b41ab9317812 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 29 Mar 2025 10:15:04 +0800 Subject: [PATCH 32/50] add indexers for pool readonly wrappers --- src/Pools/EcsPool.cs | 4 ++++ src/Pools/EcsTagPool.cs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index 62a258c..8b3a7f1 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -418,6 +418,10 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _pool.IsReadOnly; } } + public ref readonly T this[int entityID] + { + get { return ref _pool.Read(entityID); } + } #endregion #region Constructors diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index b8bce1d..81c33a4 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -365,6 +365,10 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _pool.IsReadOnly; } } + public bool this[int entityID] + { + get { return _pool.Has(entityID); } + } #endregion #region Constructors From 9e9f9a77b6d1f75fbdcfa802c71d1e44d8428b2a Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 29 Mar 2025 15:55:26 +0800 Subject: [PATCH 33/50] fixes --- src/Builtin/BaseProcesses.cs | 5 +++-- src/EcsRunner.cs | 20 ++++++++++++-------- src/Pools/EcsPool.cs | 4 +++- src/Pools/EcsTagPool.cs | 2 ++ 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/Builtin/BaseProcesses.cs b/src/Builtin/BaseProcesses.cs index 42fdbbd..52344b5 100644 --- a/src/Builtin/BaseProcesses.cs +++ b/src/Builtin/BaseProcesses.cs @@ -150,9 +150,10 @@ namespace DCFApixels.DragonECS.Internal catch (Exception e) { #if DRAGONECS_DISABLE_CATH_EXCEPTIONS - throw; -#endif + throw e; +#else EcsDebug.PrintError(e); +#endif } finally { diff --git a/src/EcsRunner.cs b/src/EcsRunner.cs index 3398c43..227a53a 100644 --- a/src/EcsRunner.cs +++ b/src/EcsRunner.cs @@ -211,9 +211,10 @@ namespace DCFApixels.DragonECS catch (Exception e) { #if DRAGONECS_DISABLE_CATH_EXCEPTIONS - throw; -#endif + throw e; +#else EcsDebug.PrintError(e); +#endif } _markers[i].End(); } @@ -251,9 +252,10 @@ namespace DCFApixels.DragonECS catch (Exception e) { #if DRAGONECS_DISABLE_CATH_EXCEPTIONS - throw; -#endif + throw e; +#else EcsDebug.PrintError(e); +#endif } _markers[i].End(); } @@ -378,9 +380,10 @@ namespace DCFApixels.DragonECS catch (Exception e) { #if DRAGONECS_DISABLE_CATH_EXCEPTIONS - throw; -#endif + throw e; +#else EcsDebug.PrintError(e); +#endif } finally { @@ -433,9 +436,10 @@ namespace DCFApixels.DragonECS catch (Exception e) { #if DRAGONECS_DISABLE_CATH_EXCEPTIONS - throw; -#endif + throw e; +#else EcsDebug.PrintError(e); +#endif } finally { diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index 8b3a7f1..655e44a 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -440,11 +440,13 @@ namespace DCFApixels.DragonECS public ref readonly T Read(int entityID) { return ref _pool.Read(entityID); } object IEcsReadonlyPool.GetRaw(int entityID) { return _pool.Read(entityID); } +#if !DRAGONECS_DISABLE_POOLS_EVENTS [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void RemoveListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); } - #endregion +#endif +#endregion #region Convertors public static implicit operator ReadonlyEcsPool(EcsPool a) { return new ReadonlyEcsPool(a); } diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index 81c33a4..1bec619 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -389,10 +389,12 @@ namespace DCFApixels.DragonECS return default; } +#if !DRAGONECS_DISABLE_POOLS_EVENTS [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void RemoveListener(IEcsPoolEventListener listener) { _pool.AddListener(listener); } +#endif #endregion #region Convertors From dca386f0d2e4169ccd26ac3b79b7b684a34c7093 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 29 Mar 2025 16:14:19 +0800 Subject: [PATCH 34/50] up version to 0.9.5 --- DragonECS.csproj | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DragonECS.csproj b/DragonECS.csproj index f0b44cf..6620a71 100644 --- a/DragonECS.csproj +++ b/DragonECS.csproj @@ -10,7 +10,7 @@ DCFApixels.DragonECS DragonECS - 0.9.1 + 0.9.5 DCFApixels ECS Framework for Game Engines with C# and .Net Platform DCFApixels diff --git a/package.json b/package.json index ace3df9..4bae9f7 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "displayName": "DragonECS", "description": "C# Entity Component System Framework", "unity": "2020.3", - "version": "0.9.4", + "version": "0.9.5", "repository": { "type": "git", "url": "https://github.com/DCFApixels/DragonECS.git" From 17813b29cb21486c8938ef94e64b0fdd32ba4a5a Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:40:39 +0800 Subject: [PATCH 35/50] hot fixes --- src/Builtin/Worlds.cs | 14 +++++----- src/EcsWorld.cs | 33 ++++++++++++++++++++++++ src/Executors/EcsWhereToGroupExecutor.cs | 18 +++++++++++++ src/Executors/MaskQueryExecutor.cs | 32 ++++++++++++----------- 4 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/Builtin/Worlds.cs b/src/Builtin/Worlds.cs index 5f50cfb..75e5e4d 100644 --- a/src/Builtin/Worlds.cs +++ b/src/Builtin/Worlds.cs @@ -13,9 +13,10 @@ namespace DCFApixels.DragonECS [MetaID("DragonECS_4EE3527C92015BAB0299CB7B4E2663D1")] public sealed class EcsDefaultWorld : EcsWorld, IInjectionUnit { - public EcsDefaultWorld() : base() { } - public EcsDefaultWorld(EcsWorldConfig config = null, string name = null, short worldID = -1) : base(config, name == null ? "Default" : name, worldID) { } - public EcsDefaultWorld(IConfigContainer configs, string name = null, short worldID = -1) : base(configs, name == null ? "Default" : name, worldID) { } + private const string DEFAULT_NAME = "Default"; + public EcsDefaultWorld() : base(default(EcsWorldConfig), DEFAULT_NAME) { } + public EcsDefaultWorld(EcsWorldConfig config = null, string name = null, short worldID = -1) : base(config, name == null ? DEFAULT_NAME : name, worldID) { } + public EcsDefaultWorld(IConfigContainer configs, string name = null, short worldID = -1) : base(configs, name == null ? DEFAULT_NAME : name, worldID) { } void IInjectionUnit.InitInjectionNode(InjectionGraph nodes) { nodes.AddNode(this); } } /// EcsWrold for store event entities. @@ -26,9 +27,10 @@ namespace DCFApixels.DragonECS [MetaID("DragonECS_D7CE527C920160BCD765EFA72DBF8B89")] public sealed class EcsEventWorld : EcsWorld, IInjectionUnit { - public EcsEventWorld() : base() { } - public EcsEventWorld(EcsWorldConfig config = null, string name = null, short worldID = -1) : base(config, name == null ? "Events" : name, worldID) { } - public EcsEventWorld(IConfigContainer configs, string name = null, short worldID = -1) : base(configs, name == null ? "Events" : name, worldID) { } + private const string DEFAULT_NAME = "Events"; + public EcsEventWorld() : base(default(EcsWorldConfig), DEFAULT_NAME) { } + public EcsEventWorld(EcsWorldConfig config = null, string name = null, short worldID = -1) : base(config, name == null ? DEFAULT_NAME : name, worldID) { } + public EcsEventWorld(IConfigContainer configs, string name = null, short worldID = -1) : base(configs, name == null ? DEFAULT_NAME : name, worldID) { } void IInjectionUnit.InitInjectionNode(InjectionGraph nodes) { nodes.AddNode(this); } } } diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 6ed6fe3..a07e9ab 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -257,6 +257,38 @@ namespace DCFApixels.DragonECS { return Get>().Instance; } + public void GetAspects(out TAspect0 a0) + where TAspect0 : new() + { + a0 = GetAspect(); + } + public void GetAspects(out TAspect0 a0, out TAspect1 a1) + where TAspect0 : new() + where TAspect1 : new() + { + a0 = GetAspect(); + a1 = GetAspect(); + } + public void GetAspects(out TAspect0 a0, out TAspect1 a1, out TAspect2 a2) + where TAspect0 : new() + where TAspect1 : new() + where TAspect2 : new() + { + a0 = GetAspect(); + a1 = GetAspect(); + a2 = GetAspect(); + } + public void GetAspects(out TAspect0 a0, out TAspect1 a1, out TAspect2 a2, out TAspect3 a3) + where TAspect0 : new() + where TAspect1 : new() + where TAspect2 : new() + where TAspect3 : new() + { + a0 = GetAspect(); + a1 = GetAspect(); + a2 = GetAspect(); + a3 = GetAspect(); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public TAspect GetAspect(out EcsMask mask) where TAspect : new() { @@ -1185,6 +1217,7 @@ namespace DCFApixels.DragonECS { private EcsWorld _world; private List _queries; + public string Name { get { return _world.Name; } } public EntitySlotInfo[] Entities { get diff --git a/src/Executors/EcsWhereToGroupExecutor.cs b/src/Executors/EcsWhereToGroupExecutor.cs index 7765503..8d57c6e 100644 --- a/src/Executors/EcsWhereToGroupExecutor.cs +++ b/src/Executors/EcsWhereToGroupExecutor.cs @@ -68,6 +68,24 @@ namespace DCFApixels.DragonECS.Internal { _version++; _iterator.IterateTo(World.Entities, _filteredAllGroup); +#if DEBUG && DRAGONECS_DEEP_DEBUG + if(_filteredGroup == null) + { + _filteredGroup = EcsGroup.New(World); + } + _filteredGroup.Clear(); + foreach (var e in World.Entities) + { + if(World.IsMatchesMask(Mask, e)) + { + _filteredGroup.Add(e); + } + } + if(_filteredAllGroup.SetEquals(_filteredGroup) == false) + { + throw new System.InvalidOperationException(); + } +#endif } } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Executors/MaskQueryExecutor.cs b/src/Executors/MaskQueryExecutor.cs index de96a69..849b8ed 100644 --- a/src/Executors/MaskQueryExecutor.cs +++ b/src/Executors/MaskQueryExecutor.cs @@ -158,17 +158,17 @@ namespace DCFApixels.DragonECS.Core { *_versions = _world.Version; - long* ptr = _versions; + long* versionsPtr = _versions; var slots = _world._poolSlots; foreach (var slotIndex in _maskInc) { - ptr++; - *ptr = slots[slotIndex].version; + versionsPtr++; + *versionsPtr = slots[slotIndex].version; } foreach (var slotIndex in _maskExc) { - ptr++; - *ptr = slots[slotIndex].version; + versionsPtr++; + *versionsPtr = slots[slotIndex].version; } } public bool CheckAndNext() @@ -179,26 +179,28 @@ namespace DCFApixels.DragonECS.Core } *_versions = _world.Version; - long* ptr = _versions; + long* versionsPtr = _versions; var slots = _world._poolSlots; bool result = _count != 1; foreach (var slotIndex in _maskInc) { - ptr++; - if (*ptr != slots[slotIndex].version) + versionsPtr++; + if (*versionsPtr != slots[slotIndex].version) { result = false; - *ptr = slots[slotIndex].version; + *versionsPtr = slots[slotIndex].version; } } foreach (var slotIndex in _maskExc) { - ptr++; - if (*ptr != slots[slotIndex].version) - { - result = false; - *ptr = slots[slotIndex].version; - } + return false; //TODO hotfix, не правильная логика проверки версия для EXC, потому сейчас она скипается + + //versionsPtr++; + //if (*versionsPtr != slots[slotIndex].version) + //{ + // result = false; + // *versionsPtr = slots[slotIndex].version; + //} } return result; } From 90746306f1c015f60c0d19fdd87be21f63b40644 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sun, 30 Mar 2025 22:41:40 +0800 Subject: [PATCH 36/50] up version to 0.9.6 --- DragonECS.csproj | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DragonECS.csproj b/DragonECS.csproj index 6620a71..ed6ae31 100644 --- a/DragonECS.csproj +++ b/DragonECS.csproj @@ -10,7 +10,7 @@ DCFApixels.DragonECS DragonECS - 0.9.5 + 0.9.6 DCFApixels ECS Framework for Game Engines with C# and .Net Platform DCFApixels diff --git a/package.json b/package.json index 4bae9f7..6a7646c 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "displayName": "DragonECS", "description": "C# Entity Component System Framework", "unity": "2020.3", - "version": "0.9.5", + "version": "0.9.6", "repository": { "type": "git", "url": "https://github.com/DCFApixels/DragonECS.git" From 2b4ec6377fe551cde543c4c68d45b565e013a9cc Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 31 Mar 2025 11:58:16 +0800 Subject: [PATCH 37/50] fix cache versions check --- src/Executors/MaskQueryExecutor.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Executors/MaskQueryExecutor.cs b/src/Executors/MaskQueryExecutor.cs index 849b8ed..5676805 100644 --- a/src/Executors/MaskQueryExecutor.cs +++ b/src/Executors/MaskQueryExecutor.cs @@ -125,6 +125,7 @@ namespace DCFApixels.DragonECS.Core _maskInc = mask._incs; _maskExc = mask._excs; _count = 1 + mask._incs.Length + mask._excs.Length; + _versions = UnmanagedArrayUtility.NewAndInit(_count); } public bool Check() @@ -181,7 +182,9 @@ namespace DCFApixels.DragonECS.Core long* versionsPtr = _versions; var slots = _world._poolSlots; - bool result = _count != 1; + // Так как проверки EXC работают не правильно при отсутсвии INC, + // то проверки без INC должны всегда возвращать false. + bool result = _maskInc.Length > 0; foreach (var slotIndex in _maskInc) { versionsPtr++; @@ -193,14 +196,12 @@ namespace DCFApixels.DragonECS.Core } foreach (var slotIndex in _maskExc) { - return false; //TODO hotfix, не правильная логика проверки версия для EXC, потому сейчас она скипается - - //versionsPtr++; - //if (*versionsPtr != slots[slotIndex].version) - //{ - // result = false; - // *versionsPtr = slots[slotIndex].version; - //} + versionsPtr++; + if (*versionsPtr != slots[slotIndex].version) + { + result = false; + *versionsPtr = slots[slotIndex].version; + } } return result; } From 3a9fed3c480e28d4466981a872bdbc6e46b29ae6 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 31 Mar 2025 12:02:19 +0800 Subject: [PATCH 38/50] rework deleting empty entities --- src/EcsWorld.cs | 39 ++++++++++++++++++++++++++++++++++++--- src/EcsWorld.pools.cs | 16 ++++++++++++---- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index a07e9ab..fa2cae6 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -65,6 +65,8 @@ namespace DCFApixels.DragonECS private int[] _delEntBuffer = Array.Empty(); private int _delEntBufferCount = 0; + private int[] _emptyEntities = Array.Empty(); + private int _emptyEntitiesCount = 0; private bool _isEnableAutoReleaseDelEntBuffer = true; internal int _entityComponentMaskLength; @@ -384,6 +386,7 @@ namespace DCFApixels.DragonECS slot.gen |= GEN_SLEEP_MASK; } _entityListeners.InvokeOnNewEntity(entityID); + MoveToEmptyEntities(entityID); } @@ -416,7 +419,7 @@ namespace DCFApixels.DragonECS public void DelEntity(int entityID) { #if DEBUG - if (IsUsed(entityID) == false) { Throw.World_EntityIsAlreadyСontained(entityID); } + if (IsUsed(entityID) == false) { Throw.World_EntityIsNotContained(entityID); } #elif DRAGONECS_STABILITY_MODE if (IsUsed(entityID) == false) { return; } #endif @@ -426,6 +429,24 @@ namespace DCFApixels.DragonECS _entitiesCount--; _entityListeners.InvokeOnDelEntity(entityID); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void MoveToEmptyEntities(int entityID) + { + _emptyEntities[_emptyEntitiesCount++] = entityID; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private bool RemoveFromEmptyEntities(int entityID) + { + for (int i = _emptyEntitiesCount - 1; i >= 0; i--) + { + if(_emptyEntities[i] == entityID) + { + _emptyEntities[i] = _emptyEntities[--_emptyEntitiesCount]; + return true; + } + } + return false; + } #endregion #region Other @@ -821,13 +842,24 @@ namespace DCFApixels.DragonECS } public void ReleaseDelEntityBufferAll() { - ReleaseDelEntityBuffer(_delEntBufferCount); + ReleaseDelEntityBuffer(-1); } public unsafe void ReleaseDelEntityBuffer(int count) { - if (_delEntBufferCount <= 0) { return; } + if (_emptyEntitiesCount <= 0 && _delEntBufferCount <= 0) { return; } unchecked { _version++; } + for (int i = 0; i < _emptyEntitiesCount; i++) + { + TryDelEntity(_emptyEntities[i]); + } + _emptyEntitiesCount = 0; + + if(count < 0) + { + count = _delEntBufferCount; + } + count = Math.Max(0, Math.Min(count, _delEntBufferCount)); _delEntBufferCount -= count; int slisedCount = count; @@ -907,6 +939,7 @@ namespace DCFApixels.DragonECS SetEntityComponentMaskLength(CalcEntityComponentMaskLength()); //_pools.Length / COMPONENT_MASK_CHUNK_SIZE + 1; Array.Resize(ref _entities, newSize); Array.Resize(ref _delEntBuffer, newSize); + Array.Resize(ref _emptyEntities, newSize); Array.Resize(ref _entityComponentMasks, newSize * _entityComponentMaskLength); ArrayUtility.Fill(_entities, EntitySlot.Empty, _entitiesCapacity); diff --git a/src/EcsWorld.pools.cs b/src/EcsWorld.pools.cs index 357b891..d2216d5 100644 --- a/src/EcsWorld.pools.cs +++ b/src/EcsWorld.pools.cs @@ -278,7 +278,11 @@ namespace DCFApixels.DragonECS ref PoolSlot slot = ref _poolSlots[componentTypeID]; slot.count++; slot.version++; - _entities[entityID].componentsCount++; + var count = _entities[entityID].componentsCount++; + if (count == 0 && IsUsed(entityID)) + { + RemoveFromEmptyEntities(entityID); + } _entityComponentMasks[(entityID << _entityComponentMaskLengthBitShift) + maskBit.chunkIndex] |= maskBit.mask; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -293,7 +297,7 @@ namespace DCFApixels.DragonECS if (count == 0 && IsUsed(entityID)) { - DelEntity(entityID); + MoveToEmptyEntities(entityID); } CheckUnregisterValid(count, entityID); } @@ -309,7 +313,11 @@ namespace DCFApixels.DragonECS ref PoolSlot slot = ref _poolSlots[componentTypeID]; slot.count++; slot.version++; - _entities[entityID].componentsCount++; + var count = _entities[entityID].componentsCount++; + if(count == 0 && IsUsed(entityID)) + { + RemoveFromEmptyEntities(entityID); + } return true; } return false; @@ -330,7 +338,7 @@ namespace DCFApixels.DragonECS if (count == 0 && IsUsed(entityID)) { - DelEntity(entityID); + MoveToEmptyEntities(entityID); } CheckUnregisterValid(count, entityID); return true; From b46cbcb38b8dcb72e858f3c8b9ac67d7ff340f0c Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Mon, 31 Mar 2025 12:15:06 +0800 Subject: [PATCH 39/50] up version to 0.9.7 --- DragonECS.csproj | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DragonECS.csproj b/DragonECS.csproj index ed6ae31..dbdece2 100644 --- a/DragonECS.csproj +++ b/DragonECS.csproj @@ -10,7 +10,7 @@ DCFApixels.DragonECS DragonECS - 0.9.6 + 0.9.7 DCFApixels ECS Framework for Game Engines with C# and .Net Platform DCFApixels diff --git a/package.json b/package.json index 6a7646c..b7f2c0d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "displayName": "DragonECS", "description": "C# Entity Component System Framework", "unity": "2020.3", - "version": "0.9.6", + "version": "0.9.7", "repository": { "type": "git", "url": "https://github.com/DCFApixels/DragonECS.git" From f18abe931e878ea89ebcb95cf3a99b422fc1e6d8 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 1 Apr 2025 19:29:52 +0800 Subject: [PATCH 40/50] update LinkedListIterator --- src/Internal/ArrayUtility.cs | 56 ++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/Internal/ArrayUtility.cs b/src/Internal/ArrayUtility.cs index 16cfb46..c761f77 100644 --- a/src/Internal/ArrayUtility.cs +++ b/src/Internal/ArrayUtility.cs @@ -14,13 +14,13 @@ namespace DCFApixels.DragonECS.Internal { int Next { get; } } - internal readonly struct LinkedListIterator : IEnumerable + internal readonly struct LinkedListCountIterator : IEnumerable where T : ILinkedNext { public readonly T[] Array; public readonly int Count; public readonly int StartIndex; - public LinkedListIterator(T[] array, int count, int startIndex) + public LinkedListCountIterator(T[] array, int count, int startIndex) { Array = array; Count = count; @@ -66,6 +66,58 @@ namespace DCFApixels.DragonECS.Internal void IEnumerator.Reset() { throw new NotSupportedException(); } } } + internal readonly struct LinkedListIterator : IEnumerable + where T : ILinkedNext + { + public readonly T[] Array; + public readonly int EndIndex; + public readonly int StartIndex; + public LinkedListIterator(T[] array, int endIndex, int startIndex) + { + Array = array; + EndIndex = endIndex; + StartIndex = startIndex; + } + public Enumerator GetEnumerator() + { + return new Enumerator(Array, EndIndex, StartIndex); + } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + public struct Enumerator : IEnumerator + { + private readonly T[] _array; + private readonly int _endIndex; + private readonly int _startIndex; + private int _nextIndex; + private int _index; + public ref T Current { get { return ref _array[_index]; } } + T IEnumerator.Current { get { return Current; } } + object IEnumerator.Current { get { return Current; } } + public Enumerator(T[] array, int endIndex, int head) + { + _array = array; + _startIndex = head; + _nextIndex = _startIndex; + _endIndex = endIndex; + _index = _endIndex; + } + public bool MoveNext() + { + if (_nextIndex < 0) { return false; } + _index = _nextIndex; + _nextIndex = _array[_index].Next; + return true; + } + public void Dispose() { } + public void Reset() + { + _nextIndex = _startIndex; + _index = _endIndex; + } + } + } + internal static class ArrayUtility { From 48e364bfc97bae24a941a938e599770d47707585 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:22:36 +0800 Subject: [PATCH 41/50] update deep debug --- src/Executors/EcsWhereExecutor.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Executors/EcsWhereExecutor.cs b/src/Executors/EcsWhereExecutor.cs index c35a6d6..9c88512 100644 --- a/src/Executors/EcsWhereExecutor.cs +++ b/src/Executors/EcsWhereExecutor.cs @@ -89,6 +89,16 @@ namespace DCFApixels.DragonECS.Internal public EcsSpan Execute() { Execute_Iternal(); +#if DEBUG || DRAGONECS_DEEP_DEBUG + var newSpan = new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount); + foreach (var e in newSpan) + { + if (World.IsMatchesMask(Mask, e) == false) + { + Throw.DeepDebugException(); + } + } +#endif return new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -99,6 +109,16 @@ namespace DCFApixels.DragonECS.Internal return Execute(); } ExecuteFor_Iternal(span); +#if DEBUG || DRAGONECS_DEEP_DEBUG + var newSpan = new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount); + foreach (var e in newSpan) + { + if (World.IsMatchesMask(Mask, e) == false) + { + Throw.DeepDebugException(); + } + } +#endif return new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount); } From 738e6a7080dbc5d41b94d773f42739abc24aecd3 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:40:53 +0800 Subject: [PATCH 42/50] fix/update exceptions --- src/EcsWorld.cs | 8 ++++++-- src/Executors/EcsWhereExecutor.cs | 16 ++++++++++++++-- src/Pools/EcsPool.cs | 1 + src/Pools/EcsTagPool.cs | 1 + src/Utils/Exceptions.cs | 5 +++++ 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index fa2cae6..f440b2b 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -365,6 +365,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public int NewEntity(int entityID) { + _entityDispenser.Upsize(entityID + 1); #if DEBUG if (IsUsed(entityID)) { Throw.World_EntityIsAlreadyСontained(entityID); } #elif DRAGONECS_STABILITY_MODE @@ -1257,9 +1258,12 @@ namespace DCFApixels.DragonECS { EntitySlotInfo[] result = new EntitySlotInfo[_world.Count]; int i = 0; - foreach (var e in _world.ToSpan()) + using (_world.DisableAutoReleaseDelEntBuffer()) { - result[i++] = _world.GetEntitySlotInfoDebug(e); + foreach (var e in _world.ToSpan()) + { + result[i++] = _world.GetEntitySlotInfoDebug(e); + } } return result; } diff --git a/src/Executors/EcsWhereExecutor.cs b/src/Executors/EcsWhereExecutor.cs index 9c88512..66d84d7 100644 --- a/src/Executors/EcsWhereExecutor.cs +++ b/src/Executors/EcsWhereExecutor.cs @@ -91,10 +91,22 @@ namespace DCFApixels.DragonECS.Internal Execute_Iternal(); #if DEBUG || DRAGONECS_DEEP_DEBUG var newSpan = new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount); - foreach (var e in newSpan) + using (EcsGroup group = EcsGroup.New(World)) { - if (World.IsMatchesMask(Mask, e) == false) + foreach (var e in World.Entities) { + if (World.IsMatchesMask(Mask, e)) + { + group.Add(e); + } + } + + if (group.SetEquals(newSpan) == false) + { + int[] array = new int[_filteredAllEntities.Length]; + var count = _iterator.IterateTo(World.Entities, ref array); + + EcsDebug.PrintError(newSpan.ToString() + "\r\n" + group.ToSpan().ToString()); Throw.DeepDebugException(); } } diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index 655e44a..bca9c8c 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -95,6 +95,7 @@ namespace DCFApixels.DragonECS { ref int itemIndex = ref _mapping[entityID]; #if DEBUG + if (_source.IsUsed(entityID) == false) { Throw.Ent_ThrowIsNotAlive(_source, entityID); } if (itemIndex > 0) { EcsPoolThrowHelper.ThrowAlreadyHasComponent(entityID); } if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } #elif DRAGONECS_STABILITY_MODE diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index 1bec619..64aa373 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -104,6 +104,7 @@ namespace DCFApixels.DragonECS public void Add(int entityID) { #if DEBUG + if (_source.IsUsed(entityID) == false) { Throw.Ent_ThrowIsNotAlive(_source, entityID); } if (Has(entityID)) { EcsPoolThrowHelper.ThrowAlreadyHasComponent(entityID); } if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } #elif DRAGONECS_STABILITY_MODE diff --git a/src/Utils/Exceptions.cs b/src/Utils/Exceptions.cs index ef53bf6..d4086a3 100644 --- a/src/Utils/Exceptions.cs +++ b/src/Utils/Exceptions.cs @@ -118,6 +118,11 @@ namespace DCFApixels.DragonECS.Internal throw new InvalidOperationException($"The method {methodName} can only be executed before creating entities in the world."); } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void Ent_ThrowIsNotAlive(EcsWorld world, int entityID) + { + Ent_ThrowIsNotAlive((world, entityID)); + } [MethodImpl(MethodImplOptions.NoInlining)] internal static void Ent_ThrowIsNotAlive(entlong entity) { From 6c3386cb4f42cc9bf115f298cf522cb6a7e40414 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:41:05 +0800 Subject: [PATCH 43/50] fix filter --- src/EcsMask.cs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/EcsMask.cs b/src/EcsMask.cs index 3a88fdc..fcc4220 100644 --- a/src/EcsMask.cs +++ b/src/EcsMask.cs @@ -962,29 +962,30 @@ namespace DCFApixels.DragonECS.Internal internal const int STACK_BUFFER_THRESHOLD = 100; [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void ConvertToChuncks(EcsMaskChunck* ptr, UnsafeArray input, UnsafeArray output) + internal static void ConvertToChuncks(EcsMaskChunck* bufferPtr, UnsafeArray input, UnsafeArray output) { for (int i = 0; i < input.Length; i++) { - ptr[i] = EcsMaskChunck.FromID(input.ptr[i]); + bufferPtr[i] = EcsMaskChunck.FromID(input.ptr[i]); } - for (int inputI = 0, outputI = 0; outputI < output.Length; inputI++, ptr++) + for (int inputI = 0, outputI = 0; outputI < output.Length; inputI++, bufferPtr++) { - int maskX = ptr->mask; - if (maskX == 0) { continue; } - int chunkIndexX = ptr->chunkIndex; + int stackingMask = bufferPtr->mask; + if (stackingMask == 0) { continue; } + int stackingChunkIndex = bufferPtr->chunkIndex; - EcsMaskChunck* subptr = ptr; - for (int j = 1; j < input.Length - inputI; j++, subptr++) + EcsMaskChunck* bufferSpanPtr = bufferPtr + 1; + for (int j = 1; j < input.Length - inputI; j++, bufferSpanPtr++) { - if (subptr->chunkIndex == chunkIndexX) + if (bufferSpanPtr->chunkIndex == stackingChunkIndex) { - maskX |= subptr->mask; - *subptr = default; + stackingMask |= bufferSpanPtr->mask; + *bufferSpanPtr = default; } } - output.ptr[outputI] = new EcsMaskChunck(chunkIndexX, maskX); + + output.ptr[outputI] = new EcsMaskChunck(stackingChunkIndex, stackingMask); outputI++; } } From fb797349359d4978bf17e341b469e0a740d554ca Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:42:44 +0800 Subject: [PATCH 44/50] update --- src/Pools/EcsPool.cs | 2 +- src/Pools/EcsTagPool.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index bca9c8c..964c20f 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -100,7 +100,7 @@ namespace DCFApixels.DragonECS if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } #elif DRAGONECS_STABILITY_MODE if (itemIndex > 0) { return ref Get(entityID); } - if (_isLocked) { return ref _items[0]; } + if (_isLocked || _source.IsUsed(entityID) == false) { return ref _items[0]; } #endif if (_recycledItemsCount > 0) { diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index 64aa373..8f84bd9 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -108,7 +108,7 @@ namespace DCFApixels.DragonECS if (Has(entityID)) { EcsPoolThrowHelper.ThrowAlreadyHasComponent(entityID); } if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } #elif DRAGONECS_STABILITY_MODE - if (Has(entityID) || _isLocked) { return; } + if (Has(entityID) || _source.IsUsed(entityID) == false || _isLocked) { return; } #endif _count++; _mapping[entityID] = true; From 13f7dbc5f2a27f9e317c1a0ab9882110ae1787f9 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:46:35 +0800 Subject: [PATCH 45/50] update --- src/Pools/EcsPool.cs | 2 +- src/Pools/EcsTagPool.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Pools/EcsPool.cs b/src/Pools/EcsPool.cs index 964c20f..90980b9 100644 --- a/src/Pools/EcsPool.cs +++ b/src/Pools/EcsPool.cs @@ -100,7 +100,7 @@ namespace DCFApixels.DragonECS if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } #elif DRAGONECS_STABILITY_MODE if (itemIndex > 0) { return ref Get(entityID); } - if (_isLocked || _source.IsUsed(entityID) == false) { return ref _items[0]; } + if (_isLocked | _source.IsUsed(entityID) == false) { return ref _items[0]; } #endif if (_recycledItemsCount > 0) { diff --git a/src/Pools/EcsTagPool.cs b/src/Pools/EcsTagPool.cs index 8f84bd9..72100cc 100644 --- a/src/Pools/EcsTagPool.cs +++ b/src/Pools/EcsTagPool.cs @@ -108,7 +108,7 @@ namespace DCFApixels.DragonECS if (Has(entityID)) { EcsPoolThrowHelper.ThrowAlreadyHasComponent(entityID); } if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } #elif DRAGONECS_STABILITY_MODE - if (Has(entityID) || _source.IsUsed(entityID) == false || _isLocked) { return; } + if (Has(entityID) | _source.IsUsed(entityID) == false | _isLocked) { return; } #endif _count++; _mapping[entityID] = true; From 323a21c7fbb7729185eeac6ede2499176402172b Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 4 Apr 2025 14:59:36 +0800 Subject: [PATCH 46/50] fix --- src/EcsPipeline.Builder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EcsPipeline.Builder.cs b/src/EcsPipeline.Builder.cs index 55c5be4..f81533b 100644 --- a/src/EcsPipeline.Builder.cs +++ b/src/EcsPipeline.Builder.cs @@ -726,7 +726,7 @@ namespace DCFApixels.DragonECS #region SerializableTemplate public EcsPipelineTemplate GenerateSerializableTemplate() { - var it = new LinkedListIterator(_systemNodes, _systemNodesCount, _startIndex); + var it = new LinkedListCountIterator(_systemNodes, _systemNodesCount, _startIndex); EcsPipelineTemplate result = new EcsPipelineTemplate(); result.layers = new string[Layers.Count]; result.records = new EcsPipelineTemplate.Record[it.Count]; From 3b4ae9ddb6636a22e7d5a4182fb8c8a3ade8ea40 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 4 Apr 2025 15:05:23 +0800 Subject: [PATCH 47/50] up version to 0.9.8 --- DragonECS.csproj | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DragonECS.csproj b/DragonECS.csproj index dbdece2..073cb45 100644 --- a/DragonECS.csproj +++ b/DragonECS.csproj @@ -10,7 +10,7 @@ DCFApixels.DragonECS DragonECS - 0.9.7 + 0.9.8 DCFApixels ECS Framework for Game Engines with C# and .Net Platform DCFApixels diff --git a/package.json b/package.json index b7f2c0d..e687b50 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "displayName": "DragonECS", "description": "C# Entity Component System Framework", "unity": "2020.3", - "version": "0.9.7", + "version": "0.9.8", "repository": { "type": "git", "url": "https://github.com/DCFApixels/DragonECS.git" From ed4b101e9036cf4066240d77595faffdfa75d8da Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 4 Apr 2025 15:07:48 +0800 Subject: [PATCH 48/50] fix defines --- src/Executors/EcsWhereExecutor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Executors/EcsWhereExecutor.cs b/src/Executors/EcsWhereExecutor.cs index 66d84d7..d439441 100644 --- a/src/Executors/EcsWhereExecutor.cs +++ b/src/Executors/EcsWhereExecutor.cs @@ -89,7 +89,7 @@ namespace DCFApixels.DragonECS.Internal public EcsSpan Execute() { Execute_Iternal(); -#if DEBUG || DRAGONECS_DEEP_DEBUG +#if DEBUG && DRAGONECS_DEEP_DEBUG var newSpan = new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount); using (EcsGroup group = EcsGroup.New(World)) { @@ -121,7 +121,7 @@ namespace DCFApixels.DragonECS.Internal return Execute(); } ExecuteFor_Iternal(span); -#if DEBUG || DRAGONECS_DEEP_DEBUG +#if DEBUG && DRAGONECS_DEEP_DEBUG var newSpan = new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount); foreach (var e in newSpan) { From 6b42dc07b9578dae61c148a96f84cfa3faaf5981 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 5 Apr 2025 00:18:50 +0800 Subject: [PATCH 49/50] Update entlong.cs --- src/entlong.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/entlong.cs b/src/entlong.cs index d7e64d3..9b25a94 100644 --- a/src/entlong.cs +++ b/src/entlong.cs @@ -147,6 +147,20 @@ namespace DCFApixels.DragonECS return IsAlive; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Unpack(out int id) + { +#if DEBUG + if (IsAlive == false) { Throw.Ent_ThrowIsNotAlive(this); } +#elif DRAGONECS_STABILITY_MODE + if (IsAlive == false) + { + id = EcsConsts.NULL_ENTITY_ID; + return; + } +#endif + id = _id; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Unpack(out int id, out EcsWorld world) { @@ -216,6 +230,12 @@ namespace DCFApixels.DragonECS id = _id; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryUnpack(out int id) + { + id = _id; + return IsAlive; + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryUnpack(out int id, out EcsWorld world) { From ee9c9d598a6f3495149a2ac52f5def3795900a62 Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 5 Apr 2025 00:19:55 +0800 Subject: [PATCH 50/50] up version to 0.9.9 --- DragonECS.csproj | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DragonECS.csproj b/DragonECS.csproj index 073cb45..41358e5 100644 --- a/DragonECS.csproj +++ b/DragonECS.csproj @@ -10,7 +10,7 @@ DCFApixels.DragonECS DragonECS - 0.9.8 + 0.9.9 DCFApixels ECS Framework for Game Engines with C# and .Net Platform DCFApixels diff --git a/package.json b/package.json index e687b50..fcffa56 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "displayName": "DragonECS", "description": "C# Entity Component System Framework", "unity": "2020.3", - "version": "0.9.8", + "version": "0.9.9", "repository": { "type": "git", "url": "https://github.com/DCFApixels/DragonECS.git"