From 9805f0c7096541bfe6051b9d80ed9aa1cecf06b8 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Fri, 7 Apr 2023 15:11:48 +0800 Subject: [PATCH] fixes --- src/Debug/EcsDebug.cs | 2 +- src/EcsGroup.cs | 2 +- src/EcsMask.cs | 29 +++++-- src/EcsQuery.cs | 36 +++++---- src/EcsWorld.cs | 116 ++++++++++++++-------------- src/Interfaces/IEcsReadonlyTable.cs | 4 +- 6 files changed, 110 insertions(+), 79 deletions(-) diff --git a/src/Debug/EcsDebug.cs b/src/Debug/EcsDebug.cs index 21addfc..8646a5a 100644 --- a/src/Debug/EcsDebug.cs +++ b/src/Debug/EcsDebug.cs @@ -104,7 +104,7 @@ namespace DCFApixels.DragonECS public static Action OnServiceChanged = delegate { }; - private IntDispenser _idDispenser = new IntDispenser(0); + private IntDispenser _idDispenser = new IntDispenser(-1); private Dictionary _nameIdTable = new Dictionary(); [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs index a9d7c34..ed4425b 100644 --- a/src/EcsGroup.cs +++ b/src/EcsGroup.cs @@ -248,7 +248,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public Enumerator GetEnumerator() { - Sort(); + // Sort(); _lockCount++; return new Enumerator(this); } diff --git a/src/EcsMask.cs b/src/EcsMask.cs index 64dcfd1..f643767 100644 --- a/src/EcsMask.cs +++ b/src/EcsMask.cs @@ -289,12 +289,11 @@ namespace DCFApixels.DragonECS #endregion #region EcsMask - public sealed class EcsMask + public class EcsMaskBase { - internal readonly Type WorldArchetypeType; - internal readonly int UniqueID; - internal readonly int[] Inc; - internal readonly int[] Exc; + internal Type WorldArchetypeType; + internal int[] Inc; + internal int[] Exc; internal int IncCount { @@ -306,6 +305,26 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Exc.Length; } + } + + + public sealed class EcsMask : EcsMaskBase + { + // internal readonly Type WorldArchetypeType; + internal readonly int UniqueID; + //internal readonly int[] Inc; + //internal readonly int[] Exc; + + //internal int IncCount + //{ + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + // get => Inc.Length; + //} + //internal int ExcCount + //{ + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + // get => Exc.Length; + //} internal EcsMask(Type worldArchetypeType, int uniqueID, int[] inc, int[] exc) { WorldArchetypeType = worldArchetypeType; diff --git a/src/EcsQuery.cs b/src/EcsQuery.cs index 807800c..1c3255b 100644 --- a/src/EcsQuery.cs +++ b/src/EcsQuery.cs @@ -19,11 +19,25 @@ namespace DCFApixels.DragonECS internal void AddEntity(int entityID); internal void RemoveEntity(int entityID); } - public class EcsQuery : IEcsQuery + public abstract class EcsQueryBase : IEcsQuery + { + internal EcsGroup group; + internal EcsQueryMask mask; + + + public void AddEntity(int entityID) => group.Add(entityID); + public void RemoveEntity(int entityID) => group.Remove(entityID); + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IEcsQuery.AddEntity(int entityID) => group.Add(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IEcsQuery.RemoveEntity(int entityID) => group.Remove(entityID); + } + public abstract class EcsQuery : EcsQueryBase where TWorldArchetype : EcsWorld { private int _id; - internal EcsGroup group; public int ID => _id; public EcsReadonlyGroup entities @@ -39,10 +53,6 @@ namespace DCFApixels.DragonECS public EcsGroup.Enumerator GetEnumerator() => group.GetEnumerator(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - void IEcsQuery.AddEntity(int entityID) => group.Add(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - void IEcsQuery.RemoveEntity(int entityID) => group.Remove(entityID); #region Builder public sealed class Builder : EcsQueryBuilder @@ -89,14 +99,14 @@ namespace DCFApixels.DragonECS #endregion } - public class EcsQueryMask + public class EcsQueryMask : EcsMaskBase { - internal readonly Type WorldArchetypeType; - internal readonly int[] Inc; - internal readonly int[] Exc; - - public int IncCount => Inc.Length; - public int ExcCount => Exc.Length; + // internal readonly Type WorldArchetypeType; + // internal readonly int[] Inc; + // internal readonly int[] Exc; + // + // public int IncCount => Inc.Length; + // public int ExcCount => Exc.Length; public EcsQueryMask(Type worldArchetypeType, int[] inc, int[] exc) { WorldArchetypeType = worldArchetypeType; diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 4ad515d..06c404d 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS public abstract class EcsWorld { internal static IEcsWorld[] Worlds = new IEcsWorld[8]; - private static IntDispenser _worldIdDispenser = new IntDispenser(1); + private static IntDispenser _worldIdDispenser = new IntDispenser(0); public readonly short id; @@ -69,8 +69,8 @@ namespace DCFApixels.DragonECS private IEcsPool[] _pools; private EcsNullPool _nullPool; - private List[] _filtersByIncludedComponents; - private List[] _filtersByExcludedComponents; + private List[] _filtersByIncludedComponents; + private List[] _filtersByExcludedComponents; private IEcsQuery[] _archetypes; @@ -78,6 +78,7 @@ namespace DCFApixels.DragonECS private List _groups; + #region RunnersCache private PoolRunnres _poolRunnres; private IEcsEntityCreate _entityCreate; @@ -109,7 +110,7 @@ namespace DCFApixels.DragonECS { _pipeline = pipline ?? EcsPipeline.Empty; if (!_pipeline.IsInit) pipline.Init(); - _entityDispenser = new IntDispenser(1); + _entityDispenser = new IntDispenser(0); _nullPool = EcsNullPool.instance; _pools = new IEcsPool[512]; FillArray(_pools, _nullPool); @@ -120,8 +121,8 @@ namespace DCFApixels.DragonECS _denseEntities = new int[512]; - _filtersByIncludedComponents = new List[16]; - _filtersByExcludedComponents = new List[16]; + _filtersByIncludedComponents = new List[16]; + _filtersByExcludedComponents = new List[16]; _poolRunnres = new PoolRunnres(_pipeline); _entityCreate = _pipeline.GetRunner(); @@ -172,9 +173,10 @@ namespace DCFApixels.DragonECS _archetypes[uniqueID] = (TEntityArhetype)Activator.CreateInstance(typeof(TEntityArhetype), builder); builder.End(out EcsQueryMask mask); - var filter = new EcsGroup(this); + var filter = (EcsQueryBase)_archetypes[uniqueID]; - ((EcsQuery)_archetypes[uniqueID]).group = filter; + ((EcsQuery)_archetypes[uniqueID]).group = new EcsGroup(this); + ((EcsQuery)_archetypes[uniqueID]).mask = mask; for (int i = 0; i < mask.IncCount; i++) { @@ -182,7 +184,7 @@ namespace DCFApixels.DragonECS var list = _filtersByIncludedComponents[componentID]; if (list == null) { - list = new List(8); + list = new List(8); _filtersByIncludedComponents[componentID] = list; } list.Add(filter); @@ -194,7 +196,7 @@ namespace DCFApixels.DragonECS var list = _filtersByExcludedComponents[componentID]; if (list == null) { - list = new List(8); + list = new List(8); _filtersByExcludedComponents[componentID] = list; } list.Add(filter); @@ -204,7 +206,7 @@ namespace DCFApixels.DragonECS { int entity = _denseEntities[i]; if (IsMaskCompatible(mask.Inc, mask.Exc, entity)) - filter.Add(entity); + filter.AddEntity(entity); } } entities = (TEntityArhetype)_archetypes[uniqueID]; @@ -238,7 +240,7 @@ namespace DCFApixels.DragonECS return IsMaskCompatible(EcsMaskMap.GetMask(), entityID); } - public bool IsMaskCompatible(EcsMask mask, int entity) + public bool IsMaskCompatible(EcsMaskBase mask, int entity) { #if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS if (mask.WorldArchetypeType != typeof(TWorldArchetype)) @@ -257,7 +259,7 @@ namespace DCFApixels.DragonECS return true; } - public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherComponentID) + public bool IsMaskCompatibleWithout(EcsMaskBase mask, int entity, int otherComponentID) { #if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS if (mask.WorldArchetypeType != typeof(TWorldArchetype)) @@ -286,30 +288,30 @@ namespace DCFApixels.DragonECS var includeList = _filtersByIncludedComponents[componentID]; var excludeList = _filtersByExcludedComponents[componentID]; - // if (includeList != null) - // { - // foreach (var filter in includeList) - // { - // if (IsMaskCompatible(filter.Mask, entityID)) - // { - // filter.entities.UncheckedAdd(entityID); - // } - // } - // } - // if (excludeList != null) - // { - // foreach (var filter in excludeList) - // { - // if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID)) - // { - // filter.entities.UncheckedRemove(entityID); - // } - // } - // } + if (includeList != null) + { + foreach (var filter in includeList) + { + if (IsMaskCompatible(filter.mask, entityID)) + { + filter.AddEntity(entityID); + } + } + } + if (excludeList != null) + { + foreach (var filter in excludeList) + { + if (IsMaskCompatibleWithout(filter.mask, entityID, componentID)) + { + filter.RemoveEntity(entityID); + } + } + } //TODO провести стресс тест для варианта выши и закоментированного ниже - if (includeList != null) foreach (var filter in includeList) filter.Add(entityID); - if (excludeList != null) foreach (var filter in excludeList) filter.Remove(entityID); + // if (includeList != null) foreach (var filter in includeList) filter.Add(entityID); + // if (excludeList != null) foreach (var filter in excludeList) filter.Remove(entityID); } void IEcsReadonlyTable.OnEntityComponentRemoved(int entityID, int componentID) @@ -317,30 +319,30 @@ namespace DCFApixels.DragonECS var includeList = _filtersByIncludedComponents[componentID]; var excludeList = _filtersByExcludedComponents[componentID]; - // if (includeList != null) - // { - // foreach (var filter in includeList) - // { - // if (IsMaskCompatible(filter.Mask, entityID)) - // { - // filter.entities.UncheckedRemove(entityID); - // } - // } - // } - // if (excludeList != null) - // { - // foreach (var filter in excludeList) - // { - // if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID)) - // { - // filter.entities.UncheckedAdd(entityID); - // } - // } - // } + if (includeList != null) + { + foreach (var filter in includeList) + { + if (IsMaskCompatible(filter.mask, entityID)) + { + filter.RemoveEntity(entityID); + } + } + } + if (excludeList != null) + { + foreach (var filter in excludeList) + { + if (IsMaskCompatibleWithout(filter.mask, entityID, componentID)) + { + filter.AddEntity(entityID); + } + } + } //TODO провести стресс тест для варианта выши и закоментированного ниже - if (includeList != null) foreach (var filter in includeList) filter.Remove(entityID); - if (excludeList != null) foreach (var filter in excludeList) filter.Add(entityID); + // if (includeList != null) foreach (var filter in includeList) filter.Remove(entityID); + // if (excludeList != null) foreach (var filter in excludeList) filter.Add(entityID); } #endregion diff --git a/src/Interfaces/IEcsReadonlyTable.cs b/src/Interfaces/IEcsReadonlyTable.cs index 4d24987..48652ff 100644 --- a/src/Interfaces/IEcsReadonlyTable.cs +++ b/src/Interfaces/IEcsReadonlyTable.cs @@ -22,8 +22,8 @@ namespace DCFApixels.DragonECS public bool IsMaskCompatible(int entity) where TInc : struct, IInc; public bool IsMaskCompatible(int entity) where TInc : struct, IInc where TExc : struct, IExc; - public bool IsMaskCompatible(EcsMask mask, int entity); - public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherPoolID); + public bool IsMaskCompatible(EcsMaskBase mask, int entity); + public bool IsMaskCompatibleWithout(EcsMaskBase mask, int entity, int otherPoolID); #endregion #region Properties