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 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<TWorldArchetype> : EcsQueryBase
where TWorldArchetype : EcsWorld<TWorldArchetype>
{
@ -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<int> _inc;
private List<int> _exc;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Builder(IEcsWorld world)
internal static TQuery Build<TQuery>(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<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;
_inc = new List<int>(8);
@ -84,11 +109,13 @@ namespace DCFApixels.DragonECS
return new opt<TComponent>(_world.GetPool<TComponent>());
}
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;

View File

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

View File

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

View File

@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS
#endregion
#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 void DelEntity(ent entity);
@ -72,7 +72,7 @@ namespace DCFApixels.DragonECS
private List<EcsQueryBase>[] _filtersByIncludedComponents;
private List<EcsQueryBase>[] _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<TWorldArchetype>[EntityArhetype.capacity];
_queries = new EcsQuery<TWorldArchetype>[EntityArhetype.capacity];
_groups = new List<EcsGroup>(128);
_denseEntities = new int[512];
@ -161,22 +161,20 @@ namespace DCFApixels.DragonECS
#endregion
#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;
if (_archetypes.Length < EntityArhetype.capacity)
Array.Resize(ref _archetypes, EntityArhetype.capacity);
int uniqueID = EntityArhetype<TQuery>.uniqueID;
if (_queries.Length < 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);
_archetypes[uniqueID] = (TEntityArhetype)Activator.CreateInstance(typeof(TEntityArhetype), builder);
builder.End(out EcsQueryMask mask);
_queries[uniqueID] = EcsQuery<TWorldArchetype>.Builder.Build<TQuery>(this);
var mask = _queries[uniqueID].Mask;
var filter = (EcsQueryBase)_queries[uniqueID];
var filter = (EcsQueryBase)_archetypes[uniqueID];
((EcsQuery<TWorldArchetype>)_archetypes[uniqueID]).group = new EcsGroup(this);
((EcsQuery<TWorldArchetype>)_archetypes[uniqueID]).mask = mask;
((EcsQuery<TWorldArchetype>)_queries[uniqueID]).group = new EcsGroup(this);
((EcsQuery<TWorldArchetype>)_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()