immediate tracking
parent
41e9dd4451
commit
9b0bf34c73
|
@ -432,6 +432,10 @@ namespace Encompass
|
||||||
if (writeImmediateTypes.Contains(typeof(TComponent)))
|
if (writeImmediateTypes.Contains(typeof(TComponent)))
|
||||||
{
|
{
|
||||||
written = componentUpdateManager.AddImmediateComponent(entity, component, priority);
|
written = componentUpdateManager.AddImmediateComponent(entity, component, priority);
|
||||||
|
if (written)
|
||||||
|
{
|
||||||
|
trackingManager.ImmediateUpdateTracking(entity, typeof(TComponent));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -577,7 +581,10 @@ namespace Encompass
|
||||||
|
|
||||||
if (writeImmediateTypes.Contains(typeof(TComponent)))
|
if (writeImmediateTypes.Contains(typeof(TComponent)))
|
||||||
{
|
{
|
||||||
componentManager.RemoveImmediate<TComponent>(entity, priority);
|
if (componentManager.RemoveImmediate<TComponent>(entity, priority))
|
||||||
|
{
|
||||||
|
trackingManager.ImmediateUpdateTracking(entity, typeof(TComponent));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -650,20 +657,28 @@ namespace Encompass
|
||||||
timeManager.ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, easeOutFunction);
|
timeManager.ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, easeOutFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void CheckTrackEntity(Entity entity)
|
internal void CheckAndUpdateTracking(Entity entity)
|
||||||
{
|
{
|
||||||
if (entityQuery.CheckEntity(entity, componentManager.ComponentBitSet))
|
if (_trackedEntities.Contains(entity) && !entityQuery.CheckEntity(entity, componentManager.ComponentBitSet))
|
||||||
|
{
|
||||||
|
_trackedEntities.Remove(entity);
|
||||||
|
}
|
||||||
|
else if (!_trackedEntities.Contains(entity) && entityQuery.CheckEntity(entity, componentManager.ComponentBitSet))
|
||||||
{
|
{
|
||||||
_trackedEntities.Add(entity);
|
_trackedEntities.Add(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void CheckUntrackEntity(Entity entity)
|
internal void ImmediateCheckAndUpdateTracking(Entity entity)
|
||||||
{
|
{
|
||||||
if (!entityQuery.CheckEntity(entity, componentManager.ComponentBitSet))
|
if (_trackedEntities.Contains(entity) && !entityQuery.ImmediateCheckEntity(entity, componentUpdateManager.ImmediateBits, componentUpdateManager.ExistingBits))
|
||||||
{
|
{
|
||||||
_trackedEntities.Remove(entity);
|
_trackedEntities.Remove(entity);
|
||||||
}
|
}
|
||||||
|
else if (!_trackedEntities.Contains(entity) && entityQuery.ImmediateCheckEntity(entity, componentUpdateManager.ImmediateBits, componentUpdateManager.ExistingBits))
|
||||||
|
{
|
||||||
|
_trackedEntities.Add(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace Encompass
|
||||||
return existing.And(existingForbidden).AllTrue();
|
return existing.And(existingForbidden).AllTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CheckEntityImmediate(Entity entity, ComponentBitSet immediateBitLookup, ComponentBitSet existingBitLookup)
|
public bool ImmediateCheckEntity(Entity entity, ComponentBitSet immediateBitLookup, ComponentBitSet existingBitLookup)
|
||||||
{
|
{
|
||||||
var immediateBits = immediateBitLookup.EntityBitArray(entity.ID);
|
var immediateBits = immediateBitLookup.EntityBitArray(entity.ID);
|
||||||
var existingBits = existingBitLookup.EntityBitArray(entity.ID);
|
var existingBits = existingBitLookup.EntityBitArray(entity.ID);
|
||||||
|
|
|
@ -5,18 +5,26 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
internal class TrackingManager
|
internal class TrackingManager
|
||||||
{
|
{
|
||||||
private Dictionary<Type, HashSet<Engine>> _pendingComponentTypesToEngines = new Dictionary<Type, HashSet<Engine>>();
|
private Dictionary<Type, HashSet<Engine>> _immediateComponentTypesToEngines = new Dictionary<Type, HashSet<Engine>>();
|
||||||
private Dictionary<Type, HashSet<Engine>> _componentTypesToEngines = new Dictionary<Type, HashSet<Engine>>();
|
private Dictionary<Type, HashSet<Engine>> _componentTypesToEngines = new Dictionary<Type, HashSet<Engine>>();
|
||||||
|
|
||||||
private HashSet<(Entity, Type)> _additions = new HashSet<(Entity, Type)>();
|
private HashSet<(Entity, Type)> _additions = new HashSet<(Entity, Type)>();
|
||||||
private HashSet<(Entity, Type)> _removals = new HashSet<(Entity, Type)>();
|
private HashSet<(Entity, Type)> _removals = new HashSet<(Entity, Type)>();
|
||||||
|
|
||||||
|
private HashSet<(Entity, Engine)> _pairsToCheck = new HashSet<(Entity, Engine)>();
|
||||||
|
|
||||||
public void RegisterComponentTypeToEngine(Type type, Engine engine)
|
public void RegisterComponentTypeToEngine(Type type, Engine engine)
|
||||||
{
|
{
|
||||||
if (!_componentTypesToEngines.ContainsKey(type)) { _componentTypesToEngines.Add(type, new HashSet<Engine>()); }
|
if (!_componentTypesToEngines.ContainsKey(type)) { _componentTypesToEngines.Add(type, new HashSet<Engine>()); }
|
||||||
_componentTypesToEngines[type].Add(engine);
|
_componentTypesToEngines[type].Add(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RegisterImmediateComponentTypeToEngine(Type type, Engine engine)
|
||||||
|
{
|
||||||
|
if (!_immediateComponentTypesToEngines.ContainsKey(type)) { _immediateComponentTypesToEngines.Add(type, new HashSet<Engine>()); }
|
||||||
|
_immediateComponentTypesToEngines[type].Add(engine);
|
||||||
|
}
|
||||||
|
|
||||||
public void RegisterAddition(Entity entity, Type type)
|
public void RegisterAddition(Entity entity, Type type)
|
||||||
{
|
{
|
||||||
_additions.Add((entity, type));
|
_additions.Add((entity, type));
|
||||||
|
@ -35,12 +43,23 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
foreach (var engine in engineSet)
|
foreach (var engine in engineSet)
|
||||||
{
|
{
|
||||||
engine.CheckTrackEntity(entity);
|
engine.CheckAndUpdateTracking(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ImmediateUpdateTracking(Entity entity, Type componentType)
|
||||||
|
{
|
||||||
|
if (_immediateComponentTypesToEngines.ContainsKey(componentType))
|
||||||
|
{
|
||||||
|
foreach (var engine in _componentTypesToEngines[componentType])
|
||||||
|
{
|
||||||
|
engine.ImmediateCheckAndUpdateTracking(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateTracking()
|
public void UpdateTracking()
|
||||||
{
|
{
|
||||||
// TODO: optimize so we only check each entity/engine pair once
|
// TODO: optimize so we only check each entity/engine pair once
|
||||||
|
@ -50,7 +69,8 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
foreach (var engine in _componentTypesToEngines[componentType])
|
foreach (var engine in _componentTypesToEngines[componentType])
|
||||||
{
|
{
|
||||||
engine.CheckTrackEntity(entity);
|
_pairsToCheck.Add((entity, engine));
|
||||||
|
// engine.CheckTrackEntity(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,11 +82,18 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
foreach (var engine in _componentTypesToEngines[componentType])
|
foreach (var engine in _componentTypesToEngines[componentType])
|
||||||
{
|
{
|
||||||
engine.CheckUntrackEntity(entity);
|
_pairsToCheck.Add((entity, engine));
|
||||||
|
//engine.CheckUntrackEntity(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_removals.Clear();
|
_removals.Clear();
|
||||||
|
|
||||||
|
foreach (var (entity, engine) in _pairsToCheck)
|
||||||
|
{
|
||||||
|
engine.CheckAndUpdateTracking(entity);
|
||||||
|
}
|
||||||
|
_pairsToCheck.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,6 +162,10 @@ namespace Encompass
|
||||||
foreach (var componentType in engine.queryWithTypes.Union(engine.queryWithoutTypes))
|
foreach (var componentType in engine.queryWithTypes.Union(engine.queryWithoutTypes))
|
||||||
{
|
{
|
||||||
trackingManager.RegisterComponentTypeToEngine(componentType, engine);
|
trackingManager.RegisterComponentTypeToEngine(componentType, engine);
|
||||||
|
if (engine.readImmediateTypes.Contains(componentType))
|
||||||
|
{
|
||||||
|
trackingManager.RegisterImmediateComponentTypeToEngine(componentType, engine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var componentType in engine.readTypes.Union(engine.writeTypes).Union(engine.readImmediateTypes))
|
foreach (var componentType in engine.readTypes.Union(engine.writeTypes).Union(engine.readImmediateTypes))
|
||||||
|
|
|
@ -1103,6 +1103,7 @@ namespace Tests
|
||||||
struct MockComponentD : IComponent { }
|
struct MockComponentD : IComponent { }
|
||||||
|
|
||||||
[Reads(typeof(MockComponent), typeof(MockComponentB))]
|
[Reads(typeof(MockComponent), typeof(MockComponentB))]
|
||||||
|
[Writes(typeof(MockComponentB))]
|
||||||
[QueryWith(typeof(MockComponent), typeof(MockComponentB))]
|
[QueryWith(typeof(MockComponent), typeof(MockComponentB))]
|
||||||
class EntityQueryWithComponentsEngine : Engine
|
class EntityQueryWithComponentsEngine : Engine
|
||||||
{
|
{
|
||||||
|
@ -1119,6 +1120,7 @@ namespace Tests
|
||||||
foreach (var entity in TrackedEntities)
|
foreach (var entity in TrackedEntities)
|
||||||
{
|
{
|
||||||
entities.Add(entity);
|
entities.Add(entity);
|
||||||
|
RemoveComponent<MockComponentB>(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1148,9 +1150,14 @@ namespace Tests
|
||||||
world.Update(0.01);
|
world.Update(0.01);
|
||||||
|
|
||||||
queriedEntities.Should().BeEquivalentTo(new Entity[] { entity, entityB });
|
queriedEntities.Should().BeEquivalentTo(new Entity[] { entity, entityB });
|
||||||
|
|
||||||
|
world.Update(0.01);
|
||||||
|
|
||||||
|
queriedEntities.Should().BeEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reads(typeof(MockComponent))]
|
[Reads(typeof(MockComponent))]
|
||||||
|
[Writes(typeof(MockComponent))]
|
||||||
[QueryWithout(typeof(MockComponent))]
|
[QueryWithout(typeof(MockComponent))]
|
||||||
class EntityQueryWithoutComponentsEngine : Engine
|
class EntityQueryWithoutComponentsEngine : Engine
|
||||||
{
|
{
|
||||||
|
@ -1164,7 +1171,11 @@ namespace Tests
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
{
|
{
|
||||||
entities.Clear();
|
entities.Clear();
|
||||||
entities.AddRange(TrackedEntities);
|
foreach (var entity in TrackedEntities)
|
||||||
|
{
|
||||||
|
entities.Add(entity);
|
||||||
|
SetComponent(entity, new MockComponent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1193,6 +1204,10 @@ namespace Tests
|
||||||
world.Update(0.01);
|
world.Update(0.01);
|
||||||
|
|
||||||
queriedEntities.ToArray().Should().BeEquivalentTo(new Entity[] { entityC });
|
queriedEntities.ToArray().Should().BeEquivalentTo(new Entity[] { entityC });
|
||||||
|
|
||||||
|
world.Update(0.01);
|
||||||
|
|
||||||
|
queriedEntities.Should().BeEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reads(typeof(MockComponent), typeof(MockComponentB), typeof(MockComponentD))]
|
[Reads(typeof(MockComponent), typeof(MockComponentB), typeof(MockComponentD))]
|
||||||
|
|
Loading…
Reference in New Issue