diff --git a/src/EcsQuery.cs b/src/EcsQuery.cs index 1c3255b..4c3eaa5 100644 --- a/src/EcsQuery.cs +++ b/src/EcsQuery.cs @@ -1,7 +1,9 @@ using DCFApixels.DragonECS; using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -18,12 +20,14 @@ namespace DCFApixels.DragonECS { internal void AddEntity(int entityID); internal void RemoveEntity(int entityID); + public EcsQueryMask Mask { get; } } public abstract class EcsQueryBase : IEcsQuery { internal EcsGroup group; internal EcsQueryMask mask; + public EcsQueryMask Mask => mask; public void AddEntity(int entityID) => group.Add(entityID); public void RemoveEntity(int entityID) => group.Remove(entityID); @@ -34,6 +38,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] void IEcsQuery.RemoveEntity(int entityID) => group.Remove(entityID); } + public abstract class EcsQuery : EcsQueryBase where TWorldArchetype : EcsWorld { @@ -46,13 +51,12 @@ namespace DCFApixels.DragonECS get => group.Readonly; } - public EcsQuery(Builder b) - { - } public EcsGroup.Enumerator GetEnumerator() => group.GetEnumerator(); + protected virtual void Init(Builder b) { } + #region Builder public sealed class Builder : EcsQueryBuilder @@ -61,8 +65,29 @@ namespace DCFApixels.DragonECS private List _inc; private List _exc; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal Builder(IEcsWorld world) + internal static TQuery Build(IEcsWorld world) where TQuery : IEcsQuery + { + Builder builder = new Builder(world); + + Type queryType = typeof(TQuery); + ConstructorInfo constructorInfo = queryType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Builder) }, null); + EcsQuery newQuery; + if (constructorInfo != null) + { + newQuery = (EcsQuery)constructorInfo.Invoke(new object[] { builder }); + } + else + { + newQuery = (EcsQuery)Activator.CreateInstance(typeof(TQuery)); + newQuery.Init(builder); + } + + builder.End(out newQuery.mask); + newQuery.group = new EcsGroup(world); + return (TQuery)(object)newQuery; + } + + private Builder(IEcsWorld world) { _world = world; _inc = new List(8); @@ -84,11 +109,13 @@ namespace DCFApixels.DragonECS return new opt(_world.GetPool()); } - internal void End(out EcsQueryMask mask) + private void End(out EcsQueryMask mask) { _inc.Sort(); _exc.Sort(); mask = new EcsQueryMask(_world.ArchetypeType, _inc.ToArray(), _exc.ToArray()); + + _world = null; _inc.Clear(); _inc = null; diff --git a/src/EcsFields.cs b/src/EcsQueryMember.cs similarity index 93% rename from src/EcsFields.cs rename to src/EcsQueryMember.cs index e0b8af1..89bf2b7 100644 --- a/src/EcsFields.cs +++ b/src/EcsQueryMember.cs @@ -5,7 +5,7 @@ using System.Runtime.InteropServices; namespace DCFApixels.DragonECS { - public interface IEcsFiled + public interface IEcsQueryMember where TComponent : struct { public ref TComponent Write(int entityID); @@ -15,7 +15,7 @@ namespace DCFApixels.DragonECS } [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] - public readonly struct inc : IEcsFiled + public readonly struct inc : IEcsQueryMember where TComponent : struct { private readonly EcsPool _pool; @@ -37,7 +37,7 @@ namespace DCFApixels.DragonECS } [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] - public readonly struct exc : IEcsFiled + public readonly struct exc : IEcsQueryMember where TComponent : struct { private readonly EcsPool _pool; @@ -59,7 +59,7 @@ namespace DCFApixels.DragonECS } [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] - public readonly struct opt : IEcsFiled + public readonly struct opt : IEcsQueryMember where TComponent : struct { private readonly EcsPool _pool; diff --git a/src/EcsRelationTable.cs b/src/EcsRelationTable.cs index 2eb4002..7d34788 100644 --- a/src/EcsRelationTable.cs +++ b/src/EcsRelationTable.cs @@ -80,7 +80,7 @@ namespace DCFApixels.DragonECS throw new NotImplementedException(); } - public EcsFilter Entities() where TComponent : struct + public EcsFilter Query() where TComponent : struct { throw new NotImplementedException(); } diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 06c404d..53b5ec4 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS #endregion #region Entities - public TArhetype Entities(out TArhetype entities) where TArhetype : IEcsQuery; + public TQuery Query(out TQuery entities) where TQuery : IEcsQuery; public ent NewEntity(); public void DelEntity(ent entity); @@ -72,7 +72,7 @@ namespace DCFApixels.DragonECS private List[] _filtersByIncludedComponents; private List[] _filtersByExcludedComponents; - private IEcsQuery[] _archetypes; + private IEcsQuery[] _queries; private EcsPipeline _pipeline; @@ -116,7 +116,7 @@ namespace DCFApixels.DragonECS FillArray(_pools, _nullPool); _gens = new short[512]; - _archetypes = new EcsQuery[EntityArhetype.capacity]; + _queries = new EcsQuery[EntityArhetype.capacity]; _groups = new List(128); _denseEntities = new int[512]; @@ -161,22 +161,20 @@ namespace DCFApixels.DragonECS #endregion #region Entities - public TEntityArhetype Entities(out TEntityArhetype entities) where TEntityArhetype : IEcsQuery + public TQuery Query(out TQuery entities) where TQuery : IEcsQuery { - int uniqueID = EntityArhetype.uniqueID; - if (_archetypes.Length < EntityArhetype.capacity) - Array.Resize(ref _archetypes, EntityArhetype.capacity); + int uniqueID = EntityArhetype.uniqueID; + if (_queries.Length < EntityArhetype.capacity) + Array.Resize(ref _queries, EntityArhetype.capacity); - if (_archetypes[uniqueID] == null) + if (_queries[uniqueID] == null) { - EcsQuery.Builder builder = new EcsQuery.Builder(this); - _archetypes[uniqueID] = (TEntityArhetype)Activator.CreateInstance(typeof(TEntityArhetype), builder); - builder.End(out EcsQueryMask mask); + _queries[uniqueID] = EcsQuery.Builder.Build(this); + var mask = _queries[uniqueID].Mask; + var filter = (EcsQueryBase)_queries[uniqueID]; - var filter = (EcsQueryBase)_archetypes[uniqueID]; - - ((EcsQuery)_archetypes[uniqueID]).group = new EcsGroup(this); - ((EcsQuery)_archetypes[uniqueID]).mask = mask; + ((EcsQuery)_queries[uniqueID]).group = new EcsGroup(this); + ((EcsQuery)_queries[uniqueID]).mask = mask; for (int i = 0; i < mask.IncCount; i++) { @@ -209,7 +207,7 @@ namespace DCFApixels.DragonECS filter.AddEntity(entity); } } - entities = (TEntityArhetype)_archetypes[uniqueID]; + entities = (TQuery)_queries[uniqueID]; return entities; } private bool IsMaskCompatible(int[] inc, int[] exc, int entity) @@ -397,7 +395,7 @@ namespace DCFApixels.DragonECS _nullPool = null; _filtersByIncludedComponents = null; _filtersByExcludedComponents = null; - _archetypes = null; + _queries = null; Realeze(); } public void DestryWithPipeline()