diff --git a/src/EcsEntityArchetype.cs b/src/EcsEntityArchetype.cs new file mode 100644 index 0000000..a8f13c8 --- /dev/null +++ b/src/EcsEntityArchetype.cs @@ -0,0 +1,108 @@ +using DCFApixels.DragonECS; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace DCFApixels.DragonECS +{ + public abstract class EcsEntityArchetypeBuilder + { + public abstract inc Include() where TComponent : struct; + public abstract exc Exclude() where TComponent : struct; + public abstract opt Optional() where TComponent : struct; + } + public interface IEcsEntityArchetype + { + internal void AddEntity(int entityID); + internal void RemoveEntity(int entityID); + } + public class EcsEntityArchetype : IEcsEntityArchetype + where TWorldArchetype : EcsWorld + { + private int _id; + internal EcsGroup group; + + public int ID => _id; + public EcsReadonlyGroup entities + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => group.Readonly; + } + + public EcsEntityArchetype(Builder b) + { + } + + public EcsGroup.Enumerator GetEnumerator() => group.GetEnumerator(); + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IEcsEntityArchetype.AddEntity(int entityID) => group.Add(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IEcsEntityArchetype.RemoveEntity(int entityID) => group.Remove(entityID); + + #region Builder + public sealed class Builder : EcsEntityArchetypeBuilder + { + private IEcsWorld _world; + private List _inc; + private List _exc; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Builder(IEcsWorld world) + { + _world = world; + _inc = new List(8); + _exc = new List(4); + } + + public override inc Include() where TComponent : struct + { + _inc.Add(_world.GetComponentID()); + return new inc(_world.GetPool()); + } + public override exc Exclude() where TComponent : struct + { + _exc.Add(_world.GetComponentID()); + return new exc(_world.GetPool()); + } + public override opt Optional() where TComponent : struct + { + return new opt(_world.GetPool()); + } + + internal void End(out EcsEntityArhetypeMask mask) + { + _inc.Sort(); + _exc.Sort(); + mask = new EcsEntityArhetypeMask(_world.ArchetypeType, _inc.ToArray(), _exc.ToArray()); + _world = null; + _inc.Clear(); + _inc = null; + _exc.Clear(); + _exc = null; + } + } + #endregion + } + + public class EcsEntityArhetypeMask + { + internal readonly Type WorldArchetypeType; + internal readonly int[] Inc; + internal readonly int[] Exc; + + public int IncCount => Inc.Length; + public int ExcCount => Exc.Length; + public EcsEntityArhetypeMask(Type worldArchetypeType, int[] inc, int[] exc) + { + WorldArchetypeType = worldArchetypeType; + Inc = inc; + Exc = exc; + } + } + +} diff --git a/src/EcsFields.cs b/src/EcsFields.cs new file mode 100644 index 0000000..cf04da3 --- /dev/null +++ b/src/EcsFields.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace DCFApixels.DragonECS +{ + public interface IEcsFiled + where TComponent : struct + { + public ref TComponent Write(int entityID); + public ref readonly TComponent Read(int entityID); + public bool Has(int entityID); + public void Del(int entityID); + } + + [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] + public readonly struct inc : IEcsFiled + where TComponent : struct + { + private readonly EcsPool _pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal inc(EcsPool pool) => _pool = pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref TComponent Write(int entityID) => ref _pool.Write(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Has(int entityID) => _pool.Has(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Del(int entityID) => _pool.Del(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}inc<{typeof(TComponent).Name}>"; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator inc(EcsEntityArchetypeBuilder buider) => buider.Include(); + } + + [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] + public readonly struct exc : IEcsFiled + where TComponent : struct + { + private readonly EcsPool _pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal exc(EcsPool pool) => _pool = pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref TComponent Write(int entityID) => ref _pool.Write(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Has(int entityID) => _pool.Has(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Del(int entityID) => _pool.Del(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}exc<{typeof(TComponent).Name}>"; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator exc(EcsEntityArchetypeBuilder buider) => buider.Exclude(); + } + + [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] + public readonly struct opt : IEcsFiled + where TComponent : struct + { + private readonly EcsPool _pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal opt(EcsPool pool) => _pool = pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref TComponent Write(int entityID) => ref _pool.Write(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Has(int entityID) => _pool.Has(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Del(int entityID) => _pool.Del(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}opt<{typeof(TComponent).Name}>"; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator opt(EcsEntityArchetypeBuilder buider) => buider.Optional(); + } +} diff --git a/src/EcsRelationTable.cs b/src/EcsRelationTable.cs index 8f2e430..2eb4002 100644 --- a/src/EcsRelationTable.cs +++ b/src/EcsRelationTable.cs @@ -10,8 +10,8 @@ namespace DCFApixels.DragonECS public EcsFilter Relations() where TComponent : struct; rr } - public sealed class EcsRelationTable : IEcsRealationTable - where TArchetype : EcsRelationTableArchetypeBase + public sealed class EcsRelationTable : IEcsRealationTable + where TWorldArchetype : EcsRelationTableArchetypeBase { public readonly IEcsWorld leftWorld; public readonly IEcsWorld rightWorld; @@ -26,7 +26,7 @@ namespace DCFApixels.DragonECS private EcsNullPool _nullPool; #region Properties - public Type ArchetypeType => typeof(TArchetype); + public Type ArchetypeType => typeof(TWorldArchetype); public int EntitesCount => _relationsCount; public int EntitesCapacity => _relations.Length; #endregion diff --git a/src/EcsTable.cs b/src/EcsTable.cs deleted file mode 100644 index 69bb40a..0000000 --- a/src/EcsTable.cs +++ /dev/null @@ -1,265 +0,0 @@ -using DCFApixels.DragonECS; -/*using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http.Headers; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -using UnityEngine.WSA; -using static UnityEditor.Experimental.GraphView.Port; - -namespace DCFApixels.Assets.DragonECS.src -{ - public struct Pose { } - public struct Health { } - public struct Mana { } - public struct EnemyTag { } - - public class TestArhetype : EcsEntityArhetype - { - public inc pose; - public inc health; - public opt mana; - public exc enemyTag; - - public TestArhetype(Builder b) : base(b) - { - pose = b.Include(); - health = b.Include(); - mana = b.Optional(); - enemyTag = b.Exclude(); - } - } - public class TestSystem : IEcsRunSystem - { - private TestArhetype test; - public void Run(EcsPipeline pipeline) - { - foreach (var e in test) - { - test.health.Read(e.id); - test.pose.Write(e.id) = new Pose(); - } - } - } - - - - - - - - - - - public abstract class EcsWorldArhetype - { - public EcsWorldArhetype(IEcsWorld world) { } - } - - public interface IFakeWorld { } - public class FakeWorld : IFakeWorld - where TWorldArhetype : EcsWorldArhetype - { - public readonly TWorldArhetype data; - - private EcsEntityArhetype[] _arhetypes; - - - public FakeWorld() - { - _arhetypes = new EcsEntityArhetype[ArhetypeID.capacity]; - } - - public TArhetype Arhetype() where TArhetype : EcsEntityArhetype - { - int id = ArhetypeID.id; - if (_arhetypes.Length < ArhetypeID.capacity) - Array.Resize(ref _arhetypes, ArhetypeID.capacity); - - if (_arhetypes[id] == null) - { - EcsEntityArhetype.Builder builder = new EcsEntityArhetype.Builder(this); - _arhetypes[id] = (TArhetype)Activator.CreateInstance(typeof(TArhetype), builder); - builder.End(); - } - - return (TArhetype)_arhetypes[id]; - } - - - #region ArhetypeID - private static class ArhetypeID - { - public static int count = 0; - public static int capacity = 128; - } - private static class ArhetypeID - { - public static int id; - static ArhetypeID() - { - id = ArhetypeID.count++; - if (ArhetypeID.count > ArhetypeID.capacity) - ArhetypeID.capacity <<= 1; - } - } - #endregion - } - - public interface IEcsEntityArhetype - { - internal void AddEntity(int entityID); - internal void RemoveEntity(int entityID); - } - public class EcsEntityArhetype : IEcsEntityArhetype - where TWorldArhetype : EcsWorldArhetype - { - private int _id; - private EcsGroup _group; - - public int ID => _id; - public EcsReadonlyGroup entities - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _group.Readonly; - } - - public EcsEntityArhetype(Builder b) { } - - public EcsGroup.Enumerator GetEnumerator() => _group.GetEnumerator(); - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - void IEcsEntityArhetype.AddEntity(int entityID) => _group.Add(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - void IEcsEntityArhetype.RemoveEntity(int entityID) => _group.Remove(entityID); - - #region Builder - public class Builder - { - private IFakeWorld _world; - private List _inc; - private List _exc; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal Builder(IFakeWorld world) - { - _world = world; - } - - public inc Include() where TComponent : struct - { - _inc.Add(_world.GetComponentID()); - return new inc(_world.GetPool()); - } - public exc Exclude() where TComponent : struct - { - _exc.Add(_world.GetComponentID()); - return new exc(_world.GetPool()); - } - public opt Optional() where TComponent : struct - { - return new opt(_world.GetPool()); - } - - internal void End(out EcsEntityArhetypeMask mask) - { - _inc.Sort(); - _exc.Sort(); - mask = new EcsEntityArhetypeMask(_world.ArchetypeType, _inc.ToArray(), _exc.ToArray()); - - _world = null; - _inc.Clear(); - _inc = null; - _exc.Clear(); - _exc = null; - } - } - #endregion - } - - - public interface IEcsFiled - where TComponent : struct - { - public ref TComponent Write(int entityID); - public ref readonly TComponent Read(int entityID); - public bool Has(int entityID); - public void Del(int entityID); - } - - [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] - public readonly struct inc : IEcsFiled - where TComponent : struct - { - private readonly EcsPool _pool; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal inc(EcsPool pool) => _pool = pool; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref TComponent Write(int entityID) => ref _pool.Write(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Has(int entityID) => _pool.Has(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Del(int entityID) => _pool.Del(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}inc<{typeof(TComponent).Name}>"; - } - - [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] - public readonly struct exc : IEcsFiled - where TComponent : struct - { - private readonly EcsPool _pool; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal exc(EcsPool pool) => _pool = pool; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref TComponent Write(int entityID) => ref _pool.Write(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Has(int entityID) => _pool.Has(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Del(int entityID) => _pool.Del(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}exc<{typeof(TComponent).Name}>"; - } - - [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] - public readonly struct opt : IEcsFiled - where TComponent : struct - { - private readonly EcsPool _pool; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal opt(EcsPool pool) => _pool = pool; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref TComponent Write(int entityID) => ref _pool.Write(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Has(int entityID) => _pool.Has(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Del(int entityID) => _pool.Del(entityID); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}opt<{typeof(TComponent).Name}>"; - } - - public class EcsEntityArhetypeMask - { - internal readonly Type WorldArchetypeType; - internal readonly int[] Inc; - internal readonly int[] Exc; - public EcsEntityArhetypeMask(Type worldArchetypeType, int[] inc, int[] exc) - { - WorldArchetypeType = worldArchetypeType; - Inc = inc; - Exc = exc; - } - } - -} -*/ \ No newline at end of file diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index bad403f..9f27d4c 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS #endregion #region Entities - public EcsFilter Entities() where TComponent : struct; + public TArhetype Entities(out TArhetype entities) where TArhetype : IEcsEntityArchetype; public ent NewEntity(); public void DelEntity(ent entity); @@ -56,8 +56,8 @@ namespace DCFApixels.DragonECS } } - public abstract class EcsWorld : EcsWorld, IEcsWorld - where TArchetype : EcsWorld + public abstract class EcsWorld : EcsWorld, IEcsWorld + where TWorldArchetype : EcsWorld { private IntDispenser _entityDispenser; private int[] _denseEntities; @@ -69,10 +69,10 @@ namespace DCFApixels.DragonECS private IEcsPool[] _pools; private EcsNullPool _nullPool; - private List[] _filtersByIncludedComponents; - private List[] _filtersByExcludedComponents; + private List[] _filtersByIncludedComponents; + private List[] _filtersByExcludedComponents; - private EcsFilter[] _filters; + private IEcsEntityArchetype[] _archetypes; private EcsPipeline _pipeline; @@ -96,7 +96,7 @@ namespace DCFApixels.DragonECS #endregion #region Properties - public Type ArchetypeType => typeof(TArchetype); + public Type ArchetypeType => typeof(TWorldArchetype); public int ID => id; public EcsPipeline Pipeline => _pipeline; @@ -115,18 +115,18 @@ namespace DCFApixels.DragonECS FillArray(_pools, _nullPool); _gens = new short[512]; - _filters = new EcsFilter[64]; + _archetypes = new EcsEntityArchetype[EntityArhetype.capacity]; _groups = new List(128); _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(); _entityDestry = _pipeline.GetRunner(); - _pipeline.GetRunner>().Inject((TArchetype)this); + _pipeline.GetRunner>().Inject((TWorldArchetype)this); _pipeline.GetRunner>().Inject(this); _pipeline.GetRunner().OnWorldCreate(this); } @@ -159,61 +159,70 @@ namespace DCFApixels.DragonECS } #endregion - #region GetFilter - public EcsFilter Entities() where TComponent : struct => Filter, Exc>(); - public EcsFilter Filter() where TInc : struct, IInc => Filter(); - public EcsFilter Filter() where TInc : struct, IInc where TExc : struct, IExc + #region Entities + public TEntityArhetype Entities(out TEntityArhetype entities) where TEntityArhetype : IEcsEntityArchetype { - var mask = EcsMaskMap.GetMask(); + int uniqueID = EntityArhetype.uniqueID; + if (_archetypes.Length < EntityArhetype.capacity) + Array.Resize(ref _archetypes, EntityArhetype.capacity); - if (_filters.Length <= EcsMaskMap.Capacity) + if (_archetypes[uniqueID] == null) { - Array.Resize(ref _filters, EcsMaskMap.Capacity); - } + EcsEntityArchetype.Builder builder = new EcsEntityArchetype.Builder(this); + _archetypes[uniqueID] = (TEntityArhetype)Activator.CreateInstance(typeof(TEntityArhetype), builder); + builder.End(out EcsEntityArhetypeMask mask); - if (_filters[mask.UniqueID] == null) - { - _filters[mask.UniqueID] = NewFilter(mask); + var filter = new EcsGroup(this); + + ((EcsEntityArchetype)_archetypes[uniqueID]).group = filter; + + for (int i = 0; i < mask.IncCount; i++) + { + int componentID = mask.Inc[i]; + var list = _filtersByIncludedComponents[componentID]; + if (list == null) + { + list = new List(8); + _filtersByIncludedComponents[componentID] = list; + } + list.Add(filter); + } + + for (int i = 0; i < mask.ExcCount; i++) + { + int componentID = mask.Exc[i]; + var list = _filtersByExcludedComponents[componentID]; + if (list == null) + { + list = new List(8); + _filtersByExcludedComponents[componentID] = list; + } + list.Add(filter); + } + // scan exist entities for compatibility with new filter. + for (int i = 0; i < _entitiesCount && _entitiesCount <= _denseEntities.Length; i++) + { + int entity = _denseEntities[i]; + if (IsMaskCompatible(mask.Inc, mask.Exc, entity)) + filter.Add(entity); + } } - return _filters[mask.UniqueID]; + entities = (TEntityArhetype)_archetypes[uniqueID]; + return entities; } - - private EcsFilter NewFilter(EcsMask mask, int capacirty = 512) + private bool IsMaskCompatible(int[] inc, int[] exc, int entity) { - var filter = new EcsFilter(this, mask, capacirty); - - for (int i = 0; i < mask.IncCount; i++) + for (int i = 0, iMax = inc.Length; i < iMax; i++) { - int componentID = mask.Inc[i]; - var list = _filtersByIncludedComponents[componentID]; - if (list == null) - { - list = new List(8); - _filtersByIncludedComponents[componentID] = list; - } - list.Add(filter); + if (!_pools[inc[i]].Has(entity)) + return false; } - - for (int i = 0; i < mask.ExcCount; i++) + for (int i = 0, iMax = exc.Length; i < iMax; i++) { - int componentID = mask.Exc[i]; - var list = _filtersByExcludedComponents[componentID]; - if (list == null) - { - list = new List(8); - _filtersByExcludedComponents[componentID] = list; - } - list.Add(filter); + if (_pools[exc[i]].Has(entity)) + return false; } - // scan exist entities for compatibility with new filter. - for (int i = 0; i < _entitiesCount && _entitiesCount <= _denseEntities.Length; i++) - { - int entity = _denseEntities[i]; - if (IsMaskCompatible(mask, entity)) - filter.Add(entity); - } - - return filter; + return true; } #endregion @@ -221,19 +230,19 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsMaskCompatible(int entityID) where TInc : struct, IInc { - return IsMaskCompatible(EcsMaskMap.GetMask(), entityID); + return IsMaskCompatible(EcsMaskMap.GetMask(), entityID); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsMaskCompatible(int entityID) where TInc : struct, IInc where TExc : struct, IExc { - return IsMaskCompatible(EcsMaskMap.GetMask(), entityID); + return IsMaskCompatible(EcsMaskMap.GetMask(), entityID); } public bool IsMaskCompatible(EcsMask mask, int entity) { #if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS - if (mask.WorldArchetypeType != typeof(TArchetype)) - throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)"); + if (mask.WorldArchetypeType != typeof(TWorldArchetype)) + throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TWorldArchetype)"); #endif for (int i = 0, iMax = mask.IncCount; i < iMax; i++) { @@ -251,8 +260,8 @@ namespace DCFApixels.DragonECS public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherComponentID) { #if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS - if (mask.WorldArchetypeType != typeof(TArchetype)) - throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)"); + if (mask.WorldArchetypeType != typeof(TWorldArchetype)) + throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TWorldArchetype)"); #endif for (int i = 0, iMax = mask.IncCount; i < iMax; i++) { @@ -277,30 +286,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.entities.UncheckedAdd(entityID); + // } + // } + // } + // if (excludeList != null) + // { + // foreach (var filter in excludeList) + // { + // if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID)) + // { + // filter.entities.UncheckedRemove(entityID); + // } + // } + // } //TODO провести стресс тест для варианта выши и закоментированного ниже - // if (includeList != null) foreach (var filter in includeList) filter.entities.Add(entityID); - // if (excludeList != null) foreach (var filter in excludeList) filter.entities.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) @@ -308,30 +317,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.entities.UncheckedRemove(entityID); + // } + // } + // } + // if (excludeList != null) + // { + // foreach (var filter in excludeList) + // { + // if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID)) + // { + // filter.entities.UncheckedAdd(entityID); + // } + // } + // } //TODO провести стресс тест для варианта выши и закоментированного ниже - // if (includeList != null) foreach (var filter in includeList) filter.entities.Remove(entityID); - // if (excludeList != null) foreach (var filter in excludeList) filter.entities.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 @@ -386,7 +395,7 @@ namespace DCFApixels.DragonECS _nullPool = null; _filtersByIncludedComponents = null; _filtersByExcludedComponents = null; - _filters = null; + _archetypes = null; Realeze(); } public void DestryWithPipeline() @@ -396,7 +405,29 @@ namespace DCFApixels.DragonECS } #endregion + #region Other + void IEcsReadonlyTable.RegisterGroup(EcsGroup group) + { + _groups.Add(group); + } + #endregion + #region Utils + internal static class EntityArhetype + { + public static int increment = 0; + public static int capacity = 128; + } + internal static class EntityArhetype + { + public static int uniqueID; + static EntityArhetype() + { + uniqueID = EntityArhetype.increment++; + if (EntityArhetype.increment > EntityArhetype.capacity) + EntityArhetype.capacity <<= 1; + } + } internal static class ComponentType { internal static int increment = 1; @@ -416,7 +447,7 @@ namespace DCFApixels.DragonECS #if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS if (ComponentType.increment + 1 > ushort.MaxValue) { - throw new EcsFrameworkException($"No more room for new component for this {typeof(TArchetype).FullName} IWorldArchetype"); + throw new EcsFrameworkException($"No more room for new component for this {typeof(TWorldArchetype).FullName} IWorldArchetype"); } #endif if (uniqueID >= ComponentType.types.Length) @@ -443,13 +474,6 @@ namespace DCFApixels.DragonECS } } #endregion - - #region Other - void IEcsReadonlyTable.RegisterGroup(EcsGroup group) - { - _groups.Add(group); - } - #endregion } [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 24)] diff --git a/src/Interfaces/IEcsReadonlyTable.cs b/src/Interfaces/IEcsReadonlyTable.cs index 266f5e9..4d24987 100644 --- a/src/Interfaces/IEcsReadonlyTable.cs +++ b/src/Interfaces/IEcsReadonlyTable.cs @@ -20,9 +20,6 @@ namespace DCFApixels.DragonECS public EcsPool GetPool() where T : struct; public EcsPool UncheckedGetPool() where T : struct; - public EcsFilter Filter() where TInc : struct, IInc; - public EcsFilter Filter() where TInc : struct, IInc where TExc : struct, IExc; - 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); diff --git a/src/ent.cs b/src/ent.cs index 97b746b..c5aa14d 100644 --- a/src/ent.cs +++ b/src/ent.cs @@ -12,7 +12,7 @@ namespace DCFApixels.DragonECS public short Gen { get; } public short World { get; } } - // id - 32 bits + // uniqueID - 32 bits // gen - 16 bits // world - 16 bits [StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)] @@ -71,7 +71,7 @@ namespace DCFApixels.DragonECS #region ToString [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string ToString() => $"ent(id:{id} gen:{gen} world:{world})"; + public override string ToString() => $"ent(uniqueID:{id} gen:{gen} world:{world})"; #endregion #region operators