refactoring / simplifying query initialization

This commit is contained in:
Mikhail 2023-04-07 16:03:42 +08:00
parent 9805f0c709
commit 7e4a33bd4d
4 changed files with 53 additions and 28 deletions

View File

@ -1,7 +1,9 @@
using DCFApixels.DragonECS; using DCFApixels.DragonECS;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -18,12 +20,14 @@ namespace DCFApixels.DragonECS
{ {
internal void AddEntity(int entityID); internal void AddEntity(int entityID);
internal void RemoveEntity(int entityID); internal void RemoveEntity(int entityID);
public EcsQueryMask Mask { get; }
} }
public abstract class EcsQueryBase : IEcsQuery public abstract class EcsQueryBase : IEcsQuery
{ {
internal EcsGroup group; internal EcsGroup group;
internal EcsQueryMask mask; internal EcsQueryMask mask;
public EcsQueryMask Mask => mask;
public void AddEntity(int entityID) => group.Add(entityID); public void AddEntity(int entityID) => group.Add(entityID);
public void RemoveEntity(int entityID) => group.Remove(entityID); public void RemoveEntity(int entityID) => group.Remove(entityID);
@ -34,6 +38,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
void IEcsQuery.RemoveEntity(int entityID) => group.Remove(entityID); void IEcsQuery.RemoveEntity(int entityID) => group.Remove(entityID);
} }
public abstract class EcsQuery<TWorldArchetype> : EcsQueryBase public abstract class EcsQuery<TWorldArchetype> : EcsQueryBase
where TWorldArchetype : EcsWorld<TWorldArchetype> where TWorldArchetype : EcsWorld<TWorldArchetype>
{ {
@ -46,13 +51,12 @@ namespace DCFApixels.DragonECS
get => group.Readonly; get => group.Readonly;
} }
public EcsQuery(Builder b)
{
}
public EcsGroup.Enumerator GetEnumerator() => group.GetEnumerator(); public EcsGroup.Enumerator GetEnumerator() => group.GetEnumerator();
protected virtual void Init(Builder b) { }
#region Builder #region Builder
public sealed class Builder : EcsQueryBuilder public sealed class Builder : EcsQueryBuilder
@ -61,8 +65,29 @@ namespace DCFApixels.DragonECS
private List<int> _inc; private List<int> _inc;
private List<int> _exc; private List<int> _exc;
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static TQuery Build<TQuery>(IEcsWorld world) where TQuery : IEcsQuery
internal Builder(IEcsWorld world) {
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<TWorldArchetype> newQuery;
if (constructorInfo != null)
{
newQuery = (EcsQuery<TWorldArchetype>)constructorInfo.Invoke(new object[] { builder });
}
else
{
newQuery = (EcsQuery<TWorldArchetype>)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; _world = world;
_inc = new List<int>(8); _inc = new List<int>(8);
@ -84,11 +109,13 @@ namespace DCFApixels.DragonECS
return new opt<TComponent>(_world.GetPool<TComponent>()); return new opt<TComponent>(_world.GetPool<TComponent>());
} }
internal void End(out EcsQueryMask mask) private void End(out EcsQueryMask mask)
{ {
_inc.Sort(); _inc.Sort();
_exc.Sort(); _exc.Sort();
mask = new EcsQueryMask(_world.ArchetypeType, _inc.ToArray(), _exc.ToArray()); mask = new EcsQueryMask(_world.ArchetypeType, _inc.ToArray(), _exc.ToArray());
_world = null; _world = null;
_inc.Clear(); _inc.Clear();
_inc = null; _inc = null;

View File

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
public interface IEcsFiled<TComponent> public interface IEcsQueryMember<TComponent>
where TComponent : struct where TComponent : struct
{ {
public ref TComponent Write(int entityID); public ref TComponent Write(int entityID);
@ -15,7 +15,7 @@ namespace DCFApixels.DragonECS
} }
[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)]
public readonly struct inc<TComponent> : IEcsFiled<TComponent> public readonly struct inc<TComponent> : IEcsQueryMember<TComponent>
where TComponent : struct where TComponent : struct
{ {
private readonly EcsPool<TComponent> _pool; private readonly EcsPool<TComponent> _pool;
@ -37,7 +37,7 @@ namespace DCFApixels.DragonECS
} }
[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)]
public readonly struct exc<TComponent> : IEcsFiled<TComponent> public readonly struct exc<TComponent> : IEcsQueryMember<TComponent>
where TComponent : struct where TComponent : struct
{ {
private readonly EcsPool<TComponent> _pool; private readonly EcsPool<TComponent> _pool;
@ -59,7 +59,7 @@ namespace DCFApixels.DragonECS
} }
[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)]
public readonly struct opt<TComponent> : IEcsFiled<TComponent> public readonly struct opt<TComponent> : IEcsQueryMember<TComponent>
where TComponent : struct where TComponent : struct
{ {
private readonly EcsPool<TComponent> _pool; private readonly EcsPool<TComponent> _pool;

View File

@ -80,7 +80,7 @@ namespace DCFApixels.DragonECS
throw new NotImplementedException(); throw new NotImplementedException();
} }
public EcsFilter Entities<TComponent>() where TComponent : struct public EcsFilter Query<TComponent>() where TComponent : struct
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Entities #region Entities
public TArhetype Entities<TArhetype>(out TArhetype entities) where TArhetype : IEcsQuery; public TQuery Query<TQuery>(out TQuery entities) where TQuery : IEcsQuery;
public ent NewEntity(); public ent NewEntity();
public void DelEntity(ent entity); public void DelEntity(ent entity);
@ -72,7 +72,7 @@ namespace DCFApixels.DragonECS
private List<EcsQueryBase>[] _filtersByIncludedComponents; private List<EcsQueryBase>[] _filtersByIncludedComponents;
private List<EcsQueryBase>[] _filtersByExcludedComponents; private List<EcsQueryBase>[] _filtersByExcludedComponents;
private IEcsQuery[] _archetypes; private IEcsQuery[] _queries;
private EcsPipeline _pipeline; private EcsPipeline _pipeline;
@ -116,7 +116,7 @@ namespace DCFApixels.DragonECS
FillArray(_pools, _nullPool); FillArray(_pools, _nullPool);
_gens = new short[512]; _gens = new short[512];
_archetypes = new EcsQuery<TWorldArchetype>[EntityArhetype.capacity]; _queries = new EcsQuery<TWorldArchetype>[EntityArhetype.capacity];
_groups = new List<EcsGroup>(128); _groups = new List<EcsGroup>(128);
_denseEntities = new int[512]; _denseEntities = new int[512];
@ -161,22 +161,20 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Entities #region Entities
public TEntityArhetype Entities<TEntityArhetype>(out TEntityArhetype entities) where TEntityArhetype : IEcsQuery public TQuery Query<TQuery>(out TQuery entities) where TQuery : IEcsQuery
{ {
int uniqueID = EntityArhetype<TEntityArhetype>.uniqueID; int uniqueID = EntityArhetype<TQuery>.uniqueID;
if (_archetypes.Length < EntityArhetype.capacity) if (_queries.Length < EntityArhetype.capacity)
Array.Resize(ref _archetypes, EntityArhetype.capacity); Array.Resize(ref _queries, EntityArhetype.capacity);
if (_archetypes[uniqueID] == null) if (_queries[uniqueID] == null)
{ {
EcsQuery<TWorldArchetype>.Builder builder = new EcsQuery<TWorldArchetype>.Builder(this); _queries[uniqueID] = EcsQuery<TWorldArchetype>.Builder.Build<TQuery>(this);
_archetypes[uniqueID] = (TEntityArhetype)Activator.CreateInstance(typeof(TEntityArhetype), builder); var mask = _queries[uniqueID].Mask;
builder.End(out EcsQueryMask mask); var filter = (EcsQueryBase)_queries[uniqueID];
var filter = (EcsQueryBase)_archetypes[uniqueID]; ((EcsQuery<TWorldArchetype>)_queries[uniqueID]).group = new EcsGroup(this);
((EcsQuery<TWorldArchetype>)_queries[uniqueID]).mask = mask;
((EcsQuery<TWorldArchetype>)_archetypes[uniqueID]).group = new EcsGroup(this);
((EcsQuery<TWorldArchetype>)_archetypes[uniqueID]).mask = mask;
for (int i = 0; i < mask.IncCount; i++) for (int i = 0; i < mask.IncCount; i++)
{ {
@ -209,7 +207,7 @@ namespace DCFApixels.DragonECS
filter.AddEntity(entity); filter.AddEntity(entity);
} }
} }
entities = (TEntityArhetype)_archetypes[uniqueID]; entities = (TQuery)_queries[uniqueID];
return entities; return entities;
} }
private bool IsMaskCompatible(int[] inc, int[] exc, int entity) private bool IsMaskCompatible(int[] inc, int[] exc, int entity)
@ -397,7 +395,7 @@ namespace DCFApixels.DragonECS
_nullPool = null; _nullPool = null;
_filtersByIncludedComponents = null; _filtersByIncludedComponents = null;
_filtersByExcludedComponents = null; _filtersByExcludedComponents = null;
_archetypes = null; _queries = null;
Realeze(); Realeze();
} }
public void DestryWithPipeline() public void DestryWithPipeline()