DragonECS/src/EcsQuery.cs

177 lines
6.0 KiB
C#
Raw Normal View History

2023-04-07 18:16:13 +08:00
using System;
using System.Collections.Generic;
using System.Reflection;
2023-04-09 02:52:39 +08:00
using Unity.Profiling;
namespace DCFApixels.DragonECS
{
2023-04-17 22:58:52 +08:00
public abstract class EcsQueryBase
2023-04-07 15:11:48 +08:00
{
internal EcsWorld source;
2023-04-09 02:52:39 +08:00
internal EcsGroup groupFilter;
2023-04-07 15:11:48 +08:00
internal EcsQueryMask mask;
public EcsWorld World => source;
#region Builder
2023-04-17 22:58:52 +08:00
protected virtual void Init(Builder b) { }
2023-04-18 19:35:42 +08:00
protected abstract void OnBuildAfter();
2023-04-17 22:58:52 +08:00
public abstract void Execute();
public sealed class Builder : EcsQueryBuilderBase
{
private EcsWorld _world;
private List<int> _inc;
private List<int> _exc;
private Builder(EcsWorld world)
2023-04-17 22:58:52 +08:00
{
_world = world;
_inc = new List<int>(8);
_exc = new List<int>(4);
}
internal static TQuery Build<TQuery>(EcsWorld world) where TQuery : EcsQueryBase
{
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);
2023-04-17 22:58:52 +08:00
EcsQueryBase newQuery;
if (constructorInfo != null)
{
2023-04-17 22:58:52 +08:00
newQuery = (EcsQueryBase)constructorInfo.Invoke(new object[] { builder });
}
else
{
2023-04-17 22:58:52 +08:00
newQuery = (EcsQueryBase)Activator.CreateInstance(typeof(TQuery));
newQuery.Init(builder);
}
2023-04-15 00:23:46 +08:00
newQuery.groupFilter = EcsGroup.New(world);
2023-04-17 22:58:52 +08:00
newQuery.source = world;
builder.End(out newQuery.mask);
2023-04-18 19:35:42 +08:00
newQuery.OnBuildAfter();
return (TQuery)(object)newQuery;
}
2023-04-21 14:21:24 +08:00
public sealed override TPool Include<TComponent, TPool>()
{
_inc.Add(_world.GetComponentID<TComponent>());
2023-04-21 14:21:24 +08:00
return _world.GetPool<TComponent, TPool>();
}
2023-04-21 14:21:24 +08:00
public sealed override TPool Exclude<TComponent, TPool>()
{
_exc.Add(_world.GetComponentID<TComponent>());
2023-04-21 14:21:24 +08:00
return _world.GetPool<TComponent, TPool>();
}
2023-04-21 14:21:24 +08:00
public sealed override TPool Optional<TComponent, TPool>()
{
2023-04-21 14:21:24 +08:00
return _world.GetPool<TComponent, TPool>();
}
private void End(out EcsQueryMask mask)
{
_inc.Sort();
_exc.Sort();
2023-04-20 19:23:58 +08:00
mask = new EcsQueryMask(_world.Archetype, _inc.ToArray(), _exc.ToArray());
_world = null;
_inc = null;
_exc = null;
}
}
#endregion
}
2023-04-21 14:21:24 +08:00
public abstract class EcsJoinAttachQuery : EcsQueryBase
2023-04-20 18:23:23 +08:00
{
2023-04-21 14:21:24 +08:00
// private EcsPool<Edge> attachPool;
2023-04-21 14:21:24 +08:00
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsJoinAttachQuery.Execute");
protected sealed override void OnBuildAfter()
2023-04-20 18:23:23 +08:00
{
2023-04-21 14:21:24 +08:00
throw new NotImplementedException();
// attachPool = World.GetPool<Edge>();
2023-04-20 18:23:23 +08:00
}
2023-04-21 14:21:24 +08:00
public sealed override void Execute()
{
using (_getEnumerator.Auto())
{
throw new NotImplementedException();
}
}
public EcsGroup.Enumerator GetEnumerator()
{
return groupFilter.GetEnumerator();
}
2023-04-20 18:23:23 +08:00
}
2023-04-21 14:21:24 +08:00
public abstract class EcsJoinRelationQuery : EcsQueryBase
2023-04-17 22:58:52 +08:00
{
2023-04-21 14:21:24 +08:00
// private EcsPool<Edge> attachPool;
2023-04-17 22:58:52 +08:00
2023-04-21 14:21:24 +08:00
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsJoinAttachQuery.Execute");
2023-04-18 19:35:42 +08:00
protected sealed override void OnBuildAfter()
2023-04-17 22:58:52 +08:00
{
2023-04-21 03:16:05 +08:00
throw new NotImplementedException();
2023-04-21 14:21:24 +08:00
// attachPool = World.GetPool<Edge>();
2023-04-17 22:58:52 +08:00
}
public sealed override void Execute()
{
using (_getEnumerator.Auto())
{
throw new NotImplementedException();
}
}
public EcsGroup.Enumerator GetEnumerator()
{
return groupFilter.GetEnumerator();
2023-04-21 14:21:24 +08:00
}
2023-04-17 22:58:52 +08:00
}
public abstract class EcsQuery : EcsQueryBase
{
2023-04-20 18:23:23 +08:00
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsQuery.Execute");
2023-04-18 19:35:42 +08:00
protected sealed override void OnBuildAfter() { }
2023-04-17 22:58:52 +08:00
public sealed override void Execute()
{
using (_getEnumerator.Auto())
{
var pools = World.GetAllPools();
EcsReadonlyGroup all = World.Entities;
groupFilter.Clear();
foreach (var e in all)
{
int entityID = e.id;
for (int i = 0, iMax = mask.Inc.Length; i < iMax; i++)
{
if (!pools[mask.Inc[i]].Has(entityID))
continue;
}
for (int i = 0, iMax = mask.Exc.Length; i < iMax; i++)
{
if (pools[mask.Exc[i]].Has(entityID))
continue;
}
groupFilter.AggressiveAdd(entityID);
}
groupFilter.Sort();
}
}
public EcsGroup.Enumerator GetEnumerator()
{
return groupFilter.GetEnumerator();
}
}
2023-04-07 18:16:13 +08:00
public class EcsQueryMask : EcsComponentMask
{
2023-04-07 14:03:29 +08:00
public EcsQueryMask(Type worldArchetypeType, int[] inc, int[] exc)
{
2023-04-20 19:23:58 +08:00
WorldArchetype = worldArchetypeType;
Inc = inc;
Exc = exc;
}
}
2023-04-17 22:58:52 +08:00
public abstract class EcsQueryBuilderBase
2023-04-07 17:15:31 +08:00
{
2023-04-21 14:21:24 +08:00
public abstract TPool Include<TComponent, TPool>() where TComponent : struct where TPool : EcsPoolBase, new();
public abstract TPool Exclude<TComponent, TPool>() where TComponent : struct where TPool : EcsPoolBase, new();
public abstract TPool Optional<TComponent, TPool>() where TComponent : struct where TPool : EcsPoolBase, new();
2023-04-07 17:15:31 +08:00
}
}