restructure entity queries to enable caching
parent
4e3aaa7d47
commit
1e73351b07
|
@ -0,0 +1,28 @@
|
|||
using Encompass.Exceptions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Encompass
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class QueryWith : Attribute
|
||||
{
|
||||
public readonly HashSet<Type> queryWithTypes = new HashSet<Type>();
|
||||
|
||||
public QueryWith(params Type[] queryWithTypes)
|
||||
{
|
||||
foreach (var queryWithType in queryWithTypes)
|
||||
{
|
||||
var isComponent = queryWithType.GetInterfaces().Contains(typeof(IComponent));
|
||||
|
||||
if (!isComponent)
|
||||
{
|
||||
throw new IllegalReadTypeException("{0} must be a Component", queryWithType.Name);
|
||||
}
|
||||
|
||||
this.queryWithTypes.Add(queryWithType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using Encompass.Exceptions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Encompass
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class QueryWithout : Attribute
|
||||
{
|
||||
public readonly HashSet<Type> queryWithoutTypes = new HashSet<Type>();
|
||||
|
||||
public QueryWithout(params Type[] queryWithoutTypes)
|
||||
{
|
||||
foreach (var type in queryWithoutTypes)
|
||||
{
|
||||
var isComponent = type.GetInterfaces().Contains(typeof(IComponent));
|
||||
|
||||
if (!isComponent)
|
||||
{
|
||||
throw new IllegalReadTypeException("{0} must be a Component", type.Name);
|
||||
}
|
||||
|
||||
this.queryWithoutTypes.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,11 +7,11 @@ namespace Encompass
|
|||
internal class ComponentStore
|
||||
{
|
||||
private Dictionary<Type, TypedComponentStore> Stores = new Dictionary<Type, TypedComponentStore>(512);
|
||||
private ComponentBitSet componentBitSet;
|
||||
public ComponentBitSet ComponentBitSet { get; private set; }
|
||||
|
||||
public ComponentStore(Dictionary<Type, int> typeToIndex)
|
||||
{
|
||||
componentBitSet = new ComponentBitSet(typeToIndex);
|
||||
ComponentBitSet = new ComponentBitSet(typeToIndex);
|
||||
}
|
||||
|
||||
public IEnumerable<(Type, TypedComponentStore)> StoresEnumerable()
|
||||
|
@ -33,7 +33,7 @@ namespace Encompass
|
|||
|
||||
public void FinishRegistering()
|
||||
{
|
||||
componentBitSet.FinishRegistering();
|
||||
ComponentBitSet.FinishRegistering();
|
||||
}
|
||||
|
||||
private TypedComponentStore<TComponent> Lookup<TComponent>() where TComponent : struct, IComponent
|
||||
|
@ -54,7 +54,7 @@ namespace Encompass
|
|||
|
||||
public BitSet1024 EntityBitArray(Entity entity)
|
||||
{
|
||||
return componentBitSet.EntityBitArray(entity);
|
||||
return ComponentBitSet.EntityBitArray(entity);
|
||||
}
|
||||
|
||||
public TComponent Get<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||
|
@ -65,18 +65,18 @@ namespace Encompass
|
|||
public void Set<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
|
||||
{
|
||||
Lookup<TComponent>().Set(entity, component);
|
||||
componentBitSet.Set<TComponent>(entity);
|
||||
ComponentBitSet.Set<TComponent>(entity);
|
||||
}
|
||||
|
||||
public bool Set<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent
|
||||
{
|
||||
componentBitSet.Set<TComponent>(entity);
|
||||
ComponentBitSet.Set<TComponent>(entity);
|
||||
return Lookup<TComponent>().Set(entity, component, priority);
|
||||
}
|
||||
|
||||
public void Remove<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||
{
|
||||
componentBitSet.RemoveComponent<TComponent>(entity);
|
||||
ComponentBitSet.RemoveComponent<TComponent>(entity);
|
||||
Lookup<TComponent>().Remove(entity);
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ namespace Encompass
|
|||
{
|
||||
entry.Remove(entity);
|
||||
}
|
||||
componentBitSet.RemoveEntity(entity);
|
||||
ComponentBitSet.RemoveEntity(entity);
|
||||
}
|
||||
|
||||
public bool Any<TComponent>() where TComponent : struct, IComponent
|
||||
|
@ -117,7 +117,7 @@ namespace Encompass
|
|||
|
||||
public void ClearAll()
|
||||
{
|
||||
componentBitSet.Clear();
|
||||
ComponentBitSet.Clear();
|
||||
foreach (var store in Stores.Values)
|
||||
{
|
||||
store.Clear();
|
||||
|
@ -127,7 +127,7 @@ namespace Encompass
|
|||
public void SwapWith(ComponentStore other)
|
||||
{
|
||||
(Stores, other.Stores) = (other.Stores, Stores);
|
||||
(componentBitSet, other.componentBitSet) = (other.componentBitSet, componentBitSet);
|
||||
(ComponentBitSet, other.ComponentBitSet) = (other.ComponentBitSet, ComponentBitSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,14 +197,7 @@ namespace Encompass
|
|||
UpToDateComponentStore.Remove<TComponent>(entity);
|
||||
}
|
||||
|
||||
internal BitSet1024 PendingBits(Entity entity)
|
||||
{
|
||||
return pendingComponentStore.EntityBitArray(entity);
|
||||
}
|
||||
|
||||
internal BitSet1024 ExistingBits(Entity entity)
|
||||
{
|
||||
return existingComponentStore.EntityBitArray(entity);
|
||||
}
|
||||
internal ComponentBitSet PendingBits { get { return pendingComponentStore.ComponentBitSet; } }
|
||||
internal ComponentBitSet ExistingBits { get { return existingComponentStore.ComponentBitSet; } }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Reflection;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Encompass.Exceptions;
|
||||
using Encompass.Collections;
|
||||
|
||||
namespace Encompass
|
||||
{
|
||||
|
@ -21,6 +22,8 @@ namespace Encompass
|
|||
internal readonly HashSet<Type> receiveTypes = new HashSet<Type>();
|
||||
internal readonly HashSet<Type> writeTypes = new HashSet<Type>();
|
||||
internal readonly HashSet<Type> writePendingTypes = new HashSet<Type>();
|
||||
internal readonly HashSet<Type> queryWithTypes = new HashSet<Type>();
|
||||
internal readonly HashSet<Type> queryWithoutTypes = new HashSet<Type>();
|
||||
internal readonly Dictionary<Type, int> writePriorities = new Dictionary<Type, int>();
|
||||
internal readonly int defaultWritePriority = 0;
|
||||
|
||||
|
@ -36,6 +39,8 @@ namespace Encompass
|
|||
private ComponentUpdateManager componentUpdateManager;
|
||||
private TimeManager timeManager;
|
||||
|
||||
private EntitySetQuery entityQuery;
|
||||
|
||||
protected Engine()
|
||||
{
|
||||
ID = Guid.NewGuid();
|
||||
|
@ -82,6 +87,18 @@ namespace Encompass
|
|||
{
|
||||
readPendingTypes = readsPendingAttribute.readPendingTypes;
|
||||
}
|
||||
|
||||
var queryWithAttribute = GetType().GetCustomAttribute<QueryWith>(false);
|
||||
if (queryWithAttribute != null)
|
||||
{
|
||||
queryWithTypes = queryWithAttribute.queryWithTypes;
|
||||
}
|
||||
|
||||
var queryWithoutAttribute = GetType().GetCustomAttribute<QueryWithout>(false);
|
||||
if (queryWithoutAttribute != null)
|
||||
{
|
||||
queryWithoutTypes = queryWithoutAttribute.queryWithoutTypes;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
|
@ -612,16 +629,49 @@ namespace Encompass
|
|||
timeManager.ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, easeOutFunction);
|
||||
}
|
||||
|
||||
protected IEnumerable<Entity> QueryEntities()
|
||||
{
|
||||
foreach (var entity in entityQuery.FilterEntities(entityManager.Entities, componentUpdateManager.PendingBits, componentUpdateManager.ExistingBits))
|
||||
{
|
||||
yield return entity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an empty EntitySetQuery. Can be modified and iterated over to obtain Entities that fit the given criteria.
|
||||
/// </summary>
|
||||
protected EntitySetQueryBuilder EntityQueryBuilder()
|
||||
internal void BuildEntityQuery()
|
||||
{
|
||||
return new EntitySetQueryBuilder(
|
||||
entityManager,
|
||||
componentUpdateManager,
|
||||
readPendingTypes,
|
||||
readTypes
|
||||
var withMask = BitSet1024Builder.Zeroes();
|
||||
foreach (var type in queryWithTypes)
|
||||
{
|
||||
withMask = withMask.Set(componentUpdateManager.TypeToIndex[type]);
|
||||
}
|
||||
|
||||
var withoutMask = BitSet1024Builder.Zeroes();
|
||||
foreach (var type in queryWithoutTypes)
|
||||
{
|
||||
withoutMask = withoutMask.Set(componentUpdateManager.TypeToIndex[type]);
|
||||
}
|
||||
|
||||
var pendingMask = BitSet1024Builder.Zeroes();
|
||||
foreach (var type in readPendingTypes)
|
||||
{
|
||||
pendingMask = pendingMask.Set(componentUpdateManager.TypeToIndex[type]);
|
||||
}
|
||||
|
||||
var existingMask = BitSet1024Builder.Zeroes();
|
||||
foreach (var type in readTypes)
|
||||
{
|
||||
existingMask = existingMask.Set(componentUpdateManager.TypeToIndex[type]);
|
||||
}
|
||||
|
||||
entityQuery = new EntitySetQuery(
|
||||
withMask.And(pendingMask),
|
||||
withMask.And(existingMask),
|
||||
withoutMask.And(pendingMask),
|
||||
withoutMask.And(existingMask),
|
||||
withMask.Not()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,20 +4,16 @@ using Encompass.Collections;
|
|||
|
||||
namespace Encompass
|
||||
{
|
||||
public struct EntitySetQuery : IEnumerable<Entity>
|
||||
internal struct EntitySetQuery
|
||||
{
|
||||
private EntityManager EntityManager { get; }
|
||||
private ComponentUpdateManager ComponentUpdateManager { get; }
|
||||
private BitSet1024 WithPendingMask { get; }
|
||||
private BitSet1024 WithExistingMask { get; }
|
||||
private BitSet1024 WithoutPendingMask { get; }
|
||||
private BitSet1024 WithoutExistingMask { get; }
|
||||
private BitSet1024 NotWithMask { get; }
|
||||
|
||||
internal EntitySetQuery(EntityManager entityManager, ComponentUpdateManager componentUpdateManager, BitSet1024 withPendingMask, BitSet1024 withExistingMask, BitSet1024 withoutPendingMask, BitSet1024 withoutExistingMask, BitSet1024 notWithMask)
|
||||
internal EntitySetQuery(BitSet1024 withPendingMask, BitSet1024 withExistingMask, BitSet1024 withoutPendingMask, BitSet1024 withoutExistingMask, BitSet1024 notWithMask)
|
||||
{
|
||||
EntityManager = entityManager;
|
||||
ComponentUpdateManager = componentUpdateManager;
|
||||
WithPendingMask = withPendingMask;
|
||||
WithExistingMask = withExistingMask;
|
||||
WithoutPendingMask = withoutPendingMask;
|
||||
|
@ -25,28 +21,23 @@ namespace Encompass
|
|||
NotWithMask = notWithMask;
|
||||
}
|
||||
|
||||
public IEnumerator<Entity> GetEnumerator()
|
||||
public IEnumerable<Entity> FilterEntities(IEnumerable<Entity> entities, ComponentBitSet pendingBitLookup, ComponentBitSet existingBitLookup)
|
||||
{
|
||||
foreach (var entity in EntityManager.Entities)
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
var pendingBits = ComponentUpdateManager.PendingBits(entity);
|
||||
var existingBits = ComponentUpdateManager.ExistingBits(entity);
|
||||
var pendingBits = pendingBitLookup.EntityBitArray(entity);
|
||||
var existingBits = existingBitLookup.EntityBitArray(entity);
|
||||
|
||||
var pending = WithPendingMask.And(pendingBits);
|
||||
var existing = WithExistingMask.And(existingBits);
|
||||
var withCheck = pending.Or(existing).Or(NotWithMask);
|
||||
|
||||
var pendingForbidden = WithoutPendingMask.And(pendingBits);
|
||||
var existingForbidden = WithoutExistingMask.And(existingBits);
|
||||
var pendingForbidden = WithoutPendingMask.And(pendingBits).Not();
|
||||
var existingForbidden = WithoutExistingMask.And(existingBits).Not();
|
||||
var withoutCheck = pendingForbidden.And(existingForbidden);
|
||||
|
||||
if (withCheck.And(withoutCheck).AllTrue()) { yield return entity; }
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Encompass.Collections;
|
||||
|
||||
namespace Encompass
|
||||
{
|
||||
/// <summary>
|
||||
/// EntitySetQuery is used to efficiently obtain a set of Entities that have all required Components and do not have any forbidden Components.
|
||||
/// </summary>
|
||||
public class EntitySetQueryBuilder
|
||||
{
|
||||
internal EntitySetQueryBuilder(EntityManager entityManager, ComponentUpdateManager componentUpdateManager, IEnumerable<Type> pendingTypes, IEnumerable<Type> existingTypes)
|
||||
{
|
||||
EntityManager = entityManager;
|
||||
ComponentUpdateManager = componentUpdateManager;
|
||||
WithMask = BitSet1024Builder.Zeroes();
|
||||
WithoutMask = BitSet1024Builder.Zeroes();
|
||||
|
||||
PendingMask = BitSet1024Builder.Zeroes();
|
||||
foreach (var type in pendingTypes)
|
||||
{
|
||||
PendingMask = PendingMask.Set(componentUpdateManager.TypeToIndex[type]);
|
||||
}
|
||||
|
||||
ExistingMask = BitSet1024Builder.Zeroes();
|
||||
foreach (var type in existingTypes)
|
||||
{
|
||||
ExistingMask = ExistingMask.Set(componentUpdateManager.TypeToIndex[type]);
|
||||
}
|
||||
}
|
||||
|
||||
private EntityManager EntityManager { get; }
|
||||
private ComponentUpdateManager ComponentUpdateManager { get; }
|
||||
private BitSet1024 WithMask { get; set; }
|
||||
private BitSet1024 WithoutMask { get; set; }
|
||||
private BitSet1024 PendingMask { get; set; }
|
||||
private BitSet1024 ExistingMask { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Designates that the given component type is required.
|
||||
/// </summary>
|
||||
public EntitySetQueryBuilder With<TComponent>() where TComponent : struct, IComponent
|
||||
{
|
||||
WithMask = WithMask.Set(ComponentUpdateManager.TypeToIndex[typeof(TComponent)]);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Designates that the given component type is forbidden.
|
||||
/// </summary>
|
||||
public EntitySetQueryBuilder Without<TComponent>() where TComponent : struct, IComponent
|
||||
{
|
||||
WithoutMask = WithoutMask.Set(ComponentUpdateManager.TypeToIndex[typeof(TComponent)]);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntitySetQuery Build()
|
||||
{
|
||||
return new EntitySetQuery(
|
||||
EntityManager,
|
||||
ComponentUpdateManager,
|
||||
WithMask.And(PendingMask),
|
||||
WithMask.And(ExistingMask),
|
||||
WithoutMask.And(PendingMask),
|
||||
WithoutMask.And(ExistingMask),
|
||||
WithMask.Not()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -173,9 +173,6 @@ namespace Encompass
|
|||
typeToReaders[receiveType].Add(engine);
|
||||
}
|
||||
|
||||
// System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(typeof(TEngine).GetRuntimeMethod("Update", new Type[] { typeof(double) }).MethodHandle);
|
||||
// typeof(TEngine).GetMethod("Update", new Type[] { typeof(double) }).MethodHandle.GetFunctionPointer();
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
|
@ -385,6 +382,7 @@ namespace Encompass
|
|||
foreach (var engine in engineGraph.TopologicalSort())
|
||||
{
|
||||
engineOrder.Add(engine);
|
||||
engine.BuildEntityQuery();
|
||||
}
|
||||
|
||||
var world = new World(
|
||||
|
|
|
@ -1095,6 +1095,7 @@ namespace Tests
|
|||
struct MockComponentD : IComponent { }
|
||||
|
||||
[Reads(typeof(MockComponent), typeof(MockComponentB))]
|
||||
[QueryWith(typeof(MockComponent), typeof(MockComponentB))]
|
||||
class EntityQueryWithComponentsEngine : Engine
|
||||
{
|
||||
private List<Entity> entities;
|
||||
|
@ -1107,8 +1108,10 @@ namespace Tests
|
|||
public override void Update(double dt)
|
||||
{
|
||||
entities.Clear();
|
||||
|
||||
entities.AddRange(QueryEntities().With<MockComponent>().With<MockComponentB>());
|
||||
foreach (var entity in QueryEntities())
|
||||
{
|
||||
entities.Add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1140,6 +1143,7 @@ namespace Tests
|
|||
}
|
||||
|
||||
[Reads(typeof(MockComponent))]
|
||||
[QueryWithout(typeof(MockComponent))]
|
||||
class EntityQueryWithoutComponentsEngine : Engine
|
||||
{
|
||||
private List<Entity> entities;
|
||||
|
@ -1152,8 +1156,7 @@ namespace Tests
|
|||
public override void Update(double dt)
|
||||
{
|
||||
entities.Clear();
|
||||
|
||||
entities.AddRange(QueryEntities().Without<MockComponent>());
|
||||
entities.AddRange(QueryEntities());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1185,6 +1188,8 @@ namespace Tests
|
|||
}
|
||||
|
||||
[Reads(typeof(MockComponent), typeof(MockComponentB), typeof(MockComponentD))]
|
||||
[QueryWith(typeof(MockComponent), typeof(MockComponentB))]
|
||||
[QueryWithout(typeof(MockComponentD))]
|
||||
class EntityQueryWithandWithoutComponentsEngine : Engine
|
||||
{
|
||||
private List<Entity> entities;
|
||||
|
@ -1198,9 +1203,7 @@ namespace Tests
|
|||
{
|
||||
entities.Clear();
|
||||
|
||||
entities.AddRange(QueryEntities().With<MockComponent>()
|
||||
.With<MockComponentB>()
|
||||
.Without<MockComponentD>());
|
||||
entities.AddRange(QueryEntities());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1246,7 +1249,7 @@ namespace Tests
|
|||
{
|
||||
public override void Update(double dt)
|
||||
{
|
||||
foreach (var entity in QueryEntities().With<MockComponent>())
|
||||
foreach (var entity in ReadEntities<MockComponent>())
|
||||
{
|
||||
SetComponent(entity, new MockComponentB());
|
||||
}
|
||||
|
@ -1254,6 +1257,7 @@ namespace Tests
|
|||
}
|
||||
|
||||
[ReadsPending(typeof(MockComponentB))]
|
||||
[QueryWith(typeof(MockComponentB))]
|
||||
class EntityQueryWithPendingComponentsEngine : Engine
|
||||
{
|
||||
private List<Entity> entities;
|
||||
|
@ -1266,8 +1270,7 @@ namespace Tests
|
|||
public override void Update(double dt)
|
||||
{
|
||||
entities.Clear();
|
||||
|
||||
entities.AddRange(QueryEntities().With<MockComponentB>());
|
||||
entities.AddRange(QueryEntities());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1293,6 +1296,7 @@ namespace Tests
|
|||
}
|
||||
|
||||
[ReadsPending(typeof(MockComponentB))]
|
||||
[QueryWithout(typeof(MockComponentB))]
|
||||
class EntityQueryWithoutPendingComponentsEngine : Engine
|
||||
{
|
||||
private List<Entity> entities;
|
||||
|
@ -1305,8 +1309,7 @@ namespace Tests
|
|||
public override void Update(double dt)
|
||||
{
|
||||
entities.Clear();
|
||||
|
||||
entities.AddRange(QueryEntities().Without<MockComponentB>());
|
||||
entities.AddRange(QueryEntities());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1339,12 +1342,12 @@ namespace Tests
|
|||
{
|
||||
public override void Update(double dt)
|
||||
{
|
||||
foreach (var entity in QueryEntities().With<MockComponentC>())
|
||||
foreach (var entity in ReadEntities<MockComponentC>())
|
||||
{
|
||||
SetComponent(entity, new MockComponent());
|
||||
}
|
||||
|
||||
foreach (var entity in QueryEntities().With<MockComponentD>())
|
||||
foreach (var entity in ReadEntities<MockComponentD>())
|
||||
{
|
||||
SetComponent(entity, new MockComponent());
|
||||
SetComponent(entity, new MockComponentB());
|
||||
|
@ -1353,6 +1356,8 @@ namespace Tests
|
|||
}
|
||||
|
||||
[ReadsPending(typeof(MockComponent), typeof(MockComponentB))]
|
||||
[QueryWith(typeof(MockComponent))]
|
||||
[QueryWithout(typeof(MockComponentB))]
|
||||
class EntityQueryWithAndWithoutPendingComponentsEngine : Engine
|
||||
{
|
||||
private List<Entity> entities;
|
||||
|
@ -1366,7 +1371,7 @@ namespace Tests
|
|||
{
|
||||
entities.Clear();
|
||||
|
||||
entities.AddRange(QueryEntities().With<MockComponent>().Without<MockComponentB>());
|
||||
entities.AddRange(QueryEntities());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1400,7 +1405,7 @@ namespace Tests
|
|||
{
|
||||
public override void Update(double dt)
|
||||
{
|
||||
foreach (var entity in QueryEntities().With<MockComponentC>())
|
||||
foreach (var entity in ReadEntities<MockComponentC>())
|
||||
{
|
||||
SetComponent(entity, new MockComponentB());
|
||||
}
|
||||
|
@ -1409,6 +1414,7 @@ namespace Tests
|
|||
|
||||
[ReadsPending(typeof(MockComponentB))]
|
||||
[Reads(typeof(MockComponent))]
|
||||
[QueryWith(typeof(MockComponent), typeof(MockComponentB))]
|
||||
class EntityQueryWithPendingAndNonPendingComponents : Engine
|
||||
{
|
||||
private List<Entity> entities;
|
||||
|
@ -1421,8 +1427,7 @@ namespace Tests
|
|||
public override void Update(double dt)
|
||||
{
|
||||
entities.Clear();
|
||||
|
||||
entities.AddRange(QueryEntities().With<MockComponent>().With<MockComponentB>());
|
||||
entities.AddRange(QueryEntities());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue