remove activation concept from components and entities
parent
2304cabe97
commit
d6c84b950a
|
@ -16,11 +16,6 @@ namespace Encompass
|
|||
|
||||
private readonly Dictionary<Type, HashSet<Guid>> typeToComponentIDs = new Dictionary<Type, HashSet<Guid>>();
|
||||
|
||||
private readonly List<Guid> activeComponents = new List<Guid>();
|
||||
private readonly List<Guid> inactiveComponents = new List<Guid>();
|
||||
|
||||
private readonly HashSet<Guid> componentsMarkedForActivation = new HashSet<Guid>();
|
||||
private readonly HashSet<Guid> componentsMarkedForDeactivation = new HashSet<Guid>();
|
||||
private readonly HashSet<Guid> componentsMarkedForRemoval = new HashSet<Guid>();
|
||||
|
||||
private readonly Dictionary<Guid, IComponent> pendingUpdates = new Dictionary<Guid, IComponent>();
|
||||
|
@ -65,8 +60,6 @@ namespace Encompass
|
|||
entityIDToComponentIDs[entity.ID].Add(componentID);
|
||||
componentIDToEntityID[componentID] = entity.ID;
|
||||
|
||||
activeComponents.Add(componentID);
|
||||
|
||||
entitiesWithAddedComponents.Add(entity.ID);
|
||||
|
||||
return componentID;
|
||||
|
@ -88,34 +81,34 @@ namespace Encompass
|
|||
|
||||
internal IEnumerable<ValueTuple<Guid, IComponent>> GetComponentsByEntity(Guid entityID)
|
||||
{
|
||||
return GetComponentIDsByEntityID(entityID).Intersect(activeComponents).Select((id) => new ValueTuple<Guid, IComponent>(id, IDToComponent[id]));
|
||||
return GetComponentIDsByEntityID(entityID).Select((id) => new ValueTuple<Guid, IComponent>(id, IDToComponent[id]));
|
||||
}
|
||||
|
||||
internal IEnumerable<ValueTuple<Guid, Guid, TComponent>> GetActiveComponentsByType<TComponent>() where TComponent : struct, IComponent
|
||||
internal IEnumerable<ValueTuple<Guid, Guid, TComponent>> GetComponentsByType<TComponent>() where TComponent : struct, IComponent
|
||||
{
|
||||
return typeToComponentIDs.ContainsKey(typeof(TComponent)) ?
|
||||
typeToComponentIDs[typeof(TComponent)].Intersect(activeComponents).Select((id) => new ValueTuple<Guid, Guid, TComponent>(GetEntityIDByComponentID(id), id, (TComponent)IDToComponent[id])) :
|
||||
typeToComponentIDs[typeof(TComponent)].Select((id) => new ValueTuple<Guid, Guid, TComponent>(GetEntityIDByComponentID(id), id, (TComponent)IDToComponent[id])) :
|
||||
Enumerable.Empty<ValueTuple<Guid, Guid, TComponent>>();
|
||||
}
|
||||
|
||||
internal IEnumerable<ValueTuple<Guid, IComponent>> GetActiveComponentsByType(Type type)
|
||||
internal IEnumerable<ValueTuple<Guid, IComponent>> GetComponentsByType(Type type)
|
||||
{
|
||||
return typeToComponentIDs.ContainsKey(type) ?
|
||||
typeToComponentIDs[type].Intersect(activeComponents).Select((id) => new ValueTuple<Guid, IComponent>(id, IDToComponent[id])) :
|
||||
typeToComponentIDs[type].Select((id) => new ValueTuple<Guid, IComponent>(id, IDToComponent[id])) :
|
||||
Enumerable.Empty<ValueTuple<Guid, IComponent>>();
|
||||
}
|
||||
|
||||
internal IEnumerable<ValueTuple<Guid, TComponent>> GetComponentsByEntityAndType<TComponent>(Guid entityID) where TComponent : struct, IComponent
|
||||
{
|
||||
var entityComponentsByType = GetComponentsByEntity(entityID).Where((pair) => componentIDToType[pair.Item1] == typeof(TComponent)).Select((pair) => new ValueTuple<Guid, TComponent>(pair.Item1, (TComponent)pair.Item2));
|
||||
var activeComponentsByType = GetActiveComponentsByType<TComponent>();
|
||||
var activeComponentsByType = GetComponentsByType<TComponent>();
|
||||
return activeComponentsByType.Select((triple) => (triple.Item2, triple.Item3)).Intersect(entityComponentsByType);
|
||||
}
|
||||
|
||||
internal IEnumerable<ValueTuple<Guid, IComponent>> GetComponentsByEntityAndType(Guid entityID, Type type)
|
||||
{
|
||||
var entityComponents = GetComponentsByEntity(entityID);
|
||||
var activeComponentsByType = GetActiveComponentsByType(type);
|
||||
var activeComponentsByType = GetComponentsByType(type);
|
||||
return entityComponents.Intersect(activeComponentsByType);
|
||||
}
|
||||
|
||||
|
@ -177,43 +170,6 @@ namespace Encompass
|
|||
}
|
||||
}
|
||||
|
||||
internal void Activate(Guid componentID)
|
||||
{
|
||||
if (inactiveComponents.Remove(componentID))
|
||||
{
|
||||
activeComponents.Add(componentID);
|
||||
}
|
||||
|
||||
var entityID = GetEntityIDByComponentID(componentID);
|
||||
entitiesWithAddedComponents.Add(entityID);
|
||||
}
|
||||
|
||||
internal void MarkForDeactivation(Guid componentID)
|
||||
{
|
||||
componentsMarkedForDeactivation.Add(componentID);
|
||||
}
|
||||
|
||||
internal void DeactivateMarkedComponents()
|
||||
{
|
||||
foreach (var componentID in componentsMarkedForDeactivation)
|
||||
{
|
||||
Deactivate(componentID);
|
||||
}
|
||||
|
||||
componentsMarkedForDeactivation.Clear();
|
||||
}
|
||||
|
||||
private void Deactivate(Guid componentID)
|
||||
{
|
||||
if (activeComponents.Remove(componentID))
|
||||
{
|
||||
inactiveComponents.Add(componentID);
|
||||
}
|
||||
|
||||
var entityID = GetEntityIDByComponentID(componentID);
|
||||
entitiesWithRemovedComponents.Add(entityID);
|
||||
}
|
||||
|
||||
internal void MarkForRemoval(Guid componentID)
|
||||
{
|
||||
componentsMarkedForRemoval.Add(componentID);
|
||||
|
@ -234,9 +190,6 @@ namespace Encompass
|
|||
var component = IDToComponent[componentID];
|
||||
var type = componentIDToType[componentID];
|
||||
|
||||
activeComponents.Remove(componentID);
|
||||
inactiveComponents.Remove(componentID);
|
||||
|
||||
var entityID = componentIDToEntityID[componentID];
|
||||
if (entityIDToComponentIDs.ContainsKey(entityID))
|
||||
{
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace Encompass
|
|||
|
||||
internal IEnumerable<ValueTuple<Entity, Guid, TComponent>> ReadComponentsFromWorld<TComponent>() where TComponent : struct, IComponent
|
||||
{
|
||||
return componentManager.GetActiveComponentsByType<TComponent>().Select((triple) => (GetEntity(triple.Item1), triple.Item2, triple.Item3));
|
||||
return componentManager.GetComponentsByType<TComponent>().Select((triple) => (GetEntity(triple.Item1), triple.Item2, triple.Item3));
|
||||
}
|
||||
|
||||
protected Guid AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
|
||||
|
@ -147,28 +147,6 @@ namespace Encompass
|
|||
return componentID;
|
||||
}
|
||||
|
||||
protected void ActivateComponent<TComponent>(Guid componentID) where TComponent : struct, IComponent
|
||||
{
|
||||
var entity = GetEntity(componentManager.GetEntityIDByComponentID(componentID));
|
||||
var component = GetComponentByID<TComponent>(componentID);
|
||||
|
||||
if (sendTypes.Contains(typeof(PendingComponentMessage<TComponent>)))
|
||||
{
|
||||
PendingComponentMessage<TComponent> newComponentMessage;
|
||||
newComponentMessage.entity = entity;
|
||||
newComponentMessage.componentID = componentID;
|
||||
newComponentMessage.component = component;
|
||||
SendMessage(newComponentMessage);
|
||||
|
||||
componentManager.Activate(componentID);
|
||||
}
|
||||
}
|
||||
|
||||
protected void DeactivateComponent(Guid componentID)
|
||||
{
|
||||
componentManager.MarkForDeactivation(componentID);
|
||||
}
|
||||
|
||||
private IEnumerable<ValueTuple<Entity, Guid, TComponent>> ExistingComponents<TComponent>() where TComponent : struct, IComponent
|
||||
{
|
||||
return ReadMessages<ComponentMessage<TComponent>>().Select((message) => (message.entity, message.componentID, message.component));
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace Encompass
|
|||
|
||||
protected IEnumerable<ValueTuple<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent
|
||||
{
|
||||
return componentManager.GetActiveComponentsByType<TComponent>().Select((triple) => (triple.Item2, triple.Item3));
|
||||
return componentManager.GetComponentsByType<TComponent>().Select((triple) => (triple.Item2, triple.Item3));
|
||||
}
|
||||
|
||||
protected ValueTuple<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent
|
||||
|
@ -66,7 +66,7 @@ namespace Encompass
|
|||
|
||||
protected bool SomeComponent<TComponent>() where TComponent : struct, IComponent
|
||||
{
|
||||
return componentManager.GetActiveComponentsByType<TComponent>().Any();
|
||||
return componentManager.GetComponentsByType<TComponent>().Any();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,18 +7,12 @@ namespace Encompass
|
|||
internal class EntityTracker
|
||||
{
|
||||
private readonly HashSet<Guid> trackedEntityIDs = new HashSet<Guid>();
|
||||
private readonly HashSet<Guid> deactivatedEntityIDs = new HashSet<Guid>();
|
||||
|
||||
public IEnumerable<Guid> TrackedEntityIDs
|
||||
{
|
||||
get { return trackedEntityIDs; }
|
||||
}
|
||||
|
||||
public IEnumerable<Guid> DeactivatedEntityIds
|
||||
{
|
||||
get { return deactivatedEntityIDs; }
|
||||
}
|
||||
|
||||
public void TrackEntity(Guid entityID)
|
||||
{
|
||||
trackedEntityIDs.Add(entityID);
|
||||
|
@ -26,26 +20,7 @@ namespace Encompass
|
|||
|
||||
public void UntrackEntity(Guid entityID)
|
||||
{
|
||||
if (trackedEntityIDs.Remove(entityID))
|
||||
{
|
||||
deactivatedEntityIDs.Remove(entityID);
|
||||
}
|
||||
}
|
||||
|
||||
public void ActivateEntity(Guid entityID)
|
||||
{
|
||||
if (deactivatedEntityIDs.Remove(entityID))
|
||||
{
|
||||
trackedEntityIDs.Add(entityID);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeactivateEntity(Guid entityID)
|
||||
{
|
||||
if (trackedEntityIDs.Remove(entityID))
|
||||
{
|
||||
deactivatedEntityIDs.Add(entityID);
|
||||
}
|
||||
trackedEntityIDs.Remove(entityID);
|
||||
}
|
||||
|
||||
public bool IsTracking(Guid entityID)
|
||||
|
|
|
@ -36,7 +36,6 @@ namespace Encompass
|
|||
entityManager.DestroyMarkedEntities();
|
||||
|
||||
componentManager.PerformComponentUpdates();
|
||||
componentManager.DeactivateMarkedComponents();
|
||||
componentManager.RemoveMarkedComponents();
|
||||
|
||||
entityManager.CheckEntitiesWithAddedComponents();
|
||||
|
|
|
@ -58,11 +58,6 @@ namespace Encompass
|
|||
return componentManager.AddDrawComponent(entity, componentID, component, layer);
|
||||
}
|
||||
|
||||
public void DeactivateComponent(Guid componentID)
|
||||
{
|
||||
componentManager.MarkForDeactivation(componentID);
|
||||
}
|
||||
|
||||
internal void RegisterComponent(Type componentType)
|
||||
{
|
||||
registeredComponentTypes.Add(componentType);
|
||||
|
@ -265,7 +260,6 @@ namespace Encompass
|
|||
);
|
||||
|
||||
componentManager.PerformComponentUpdates();
|
||||
componentManager.DeactivateMarkedComponents();
|
||||
componentManager.RemoveMarkedComponents();
|
||||
|
||||
entityManager.CheckEntitiesWithAddedComponents();
|
||||
|
|
|
@ -303,48 +303,6 @@ namespace Tests
|
|||
world.Update(0.01);
|
||||
}
|
||||
|
||||
struct HasComponentWhenInactiveTestMessage : IMessage
|
||||
{
|
||||
public Entity entity;
|
||||
}
|
||||
|
||||
[Receives(typeof(HasComponentWhenInactiveTestMessage))]
|
||||
[Reads(typeof(MockComponent))]
|
||||
class HasComponentWhenInactiveTestEngine : Engine
|
||||
{
|
||||
public override void Update(double dt)
|
||||
{
|
||||
foreach (var hasComponentTestEngine in ReadMessages<HasComponentWhenInactiveTestMessage>())
|
||||
{
|
||||
Assert.IsFalse(HasComponent<MockComponent>(hasComponentTestEngine.entity));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HasComponentWhenInactive()
|
||||
{
|
||||
var worldBuilder = new WorldBuilder();
|
||||
worldBuilder.AddEngine(new HasComponentWhenInactiveTestEngine());
|
||||
var entity = worldBuilder.CreateEntity();
|
||||
|
||||
MockComponent mockComponent;
|
||||
mockComponent.myInt = 3;
|
||||
mockComponent.myString = "hello";
|
||||
|
||||
var componentID = worldBuilder.AddComponent(entity, mockComponent);
|
||||
|
||||
HasComponentWhenInactiveTestMessage testMessage;
|
||||
testMessage.entity = entity;
|
||||
worldBuilder.SendMessage(testMessage);
|
||||
|
||||
worldBuilder.DeactivateComponent(componentID);
|
||||
|
||||
var world = worldBuilder.Build();
|
||||
|
||||
world.Update(0.01f);
|
||||
}
|
||||
|
||||
struct RemoveComponentTestMessage : IMessage
|
||||
{
|
||||
public Entity entity;
|
||||
|
@ -432,54 +390,12 @@ namespace Tests
|
|||
world.Update(0.01f);
|
||||
}
|
||||
|
||||
struct ActivateComponentMessage : IMessage
|
||||
{
|
||||
public Entity entity;
|
||||
public Guid componentID;
|
||||
}
|
||||
|
||||
[Activates(typeof(MockComponent))]
|
||||
[Receives(typeof(ActivateComponentMessage))]
|
||||
class ActivateComponentEngine : Engine
|
||||
{
|
||||
public override void Update(double dt)
|
||||
{
|
||||
foreach (var activateComponentMessage in ReadMessages<ActivateComponentMessage>())
|
||||
{
|
||||
ActivateComponent<MockComponent>(activateComponentMessage.componentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CheckHasMockComponentMessage : IMessage
|
||||
{
|
||||
public Entity entity;
|
||||
public bool shouldHaveComponent;
|
||||
}
|
||||
|
||||
[Receives(typeof(ActivateComponentMessage))]
|
||||
[Sends(typeof(CheckHasMockComponentMessage))]
|
||||
class DoActivateCheckEngine : Engine
|
||||
{
|
||||
private Entity entity;
|
||||
|
||||
public DoActivateCheckEngine(Entity entity)
|
||||
{
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public override void Update(double dt)
|
||||
{
|
||||
if (SomeMessage<ActivateComponentMessage>())
|
||||
{
|
||||
CheckHasMockComponentMessage checkHasMockComponentMessage;
|
||||
checkHasMockComponentMessage.entity = entity;
|
||||
checkHasMockComponentMessage.shouldHaveComponent = true;
|
||||
SendMessage(checkHasMockComponentMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Receives(typeof(CheckHasMockComponentMessage))]
|
||||
[ReadsPending(typeof(MockComponent))]
|
||||
class CheckHasPendingMockComponentEngine : Engine
|
||||
|
@ -492,107 +408,5 @@ namespace Tests
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ActivateComponent()
|
||||
{
|
||||
var worldBuilder = new WorldBuilder();
|
||||
var entity = worldBuilder.CreateEntity();
|
||||
|
||||
worldBuilder.AddEngine(new ActivateComponentEngine());
|
||||
worldBuilder.AddEngine(new CheckHasPendingMockComponentEngine());
|
||||
worldBuilder.AddEngine(new DoActivateCheckEngine(entity));
|
||||
|
||||
MockComponent mockComponent;
|
||||
mockComponent.myInt = 3;
|
||||
mockComponent.myString = "hello";
|
||||
|
||||
var componentID = worldBuilder.AddComponent(entity, mockComponent);
|
||||
|
||||
worldBuilder.DeactivateComponent(componentID);
|
||||
|
||||
ActivateComponentMessage activateMessage;
|
||||
activateMessage.entity = entity;
|
||||
activateMessage.componentID = componentID;
|
||||
worldBuilder.SendMessage(activateMessage);
|
||||
|
||||
var world = worldBuilder.Build();
|
||||
|
||||
world.Update(0.01);
|
||||
}
|
||||
|
||||
struct DeactivateComponentMessage : IMessage
|
||||
{
|
||||
public Entity entity;
|
||||
public Guid componentID;
|
||||
}
|
||||
|
||||
[Receives(typeof(DeactivateComponentMessage))]
|
||||
class DeactivateComponentEngine : Engine
|
||||
{
|
||||
public override void Update(double dt)
|
||||
{
|
||||
foreach (var deactivateComponentMessage in ReadMessages<DeactivateComponentMessage>())
|
||||
{
|
||||
DeactivateComponent(deactivateComponentMessage.componentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Receives(typeof(DeactivateComponentMessage))]
|
||||
[Sends(typeof(CheckHasMockComponentMessage))]
|
||||
class DoDeactivateCheckEngine : Engine
|
||||
{
|
||||
private Entity entity;
|
||||
|
||||
public DoDeactivateCheckEngine(Entity entity)
|
||||
{
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public override void Update(double dt)
|
||||
{
|
||||
if (SomeMessage<DeactivateComponentMessage>())
|
||||
{
|
||||
CheckHasMockComponentMessage checkHasMockComponentMessage;
|
||||
checkHasMockComponentMessage.entity = entity;
|
||||
checkHasMockComponentMessage.shouldHaveComponent = true;
|
||||
SendMessage(checkHasMockComponentMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckHasMockComponentMessage checkHasMockComponentMessage;
|
||||
checkHasMockComponentMessage.entity = entity;
|
||||
checkHasMockComponentMessage.shouldHaveComponent = false;
|
||||
SendMessage(checkHasMockComponentMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeactivateComponent()
|
||||
{
|
||||
var worldBuilder = new WorldBuilder();
|
||||
var entity = worldBuilder.CreateEntity();
|
||||
|
||||
worldBuilder.AddEngine(new DeactivateComponentEngine());
|
||||
worldBuilder.AddEngine(new CheckHasMockComponentEngine());
|
||||
worldBuilder.AddEngine(new DoDeactivateCheckEngine(entity));
|
||||
|
||||
MockComponent mockComponent;
|
||||
mockComponent.myInt = 3;
|
||||
mockComponent.myString = "hello";
|
||||
|
||||
var componentID = worldBuilder.AddComponent(entity, mockComponent);
|
||||
|
||||
DeactivateComponentMessage deactivateComponentMessage;
|
||||
deactivateComponentMessage.entity = entity;
|
||||
deactivateComponentMessage.componentID = componentID;
|
||||
worldBuilder.SendMessage(deactivateComponentMessage);
|
||||
|
||||
var world = worldBuilder.Build();
|
||||
|
||||
world.Update(0.01);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,9 +60,6 @@ namespace Tests
|
|||
|
||||
var componentAID = worldBuilder.AddComponent(entity, mockComponent);
|
||||
var componentBID = worldBuilder.AddComponent(entity, mockComponentB);
|
||||
var inactiveComponentAID = worldBuilder.AddComponent(entity, mockComponent);
|
||||
|
||||
worldBuilder.DeactivateComponent(inactiveComponentAID);
|
||||
|
||||
var world = worldBuilder.Build();
|
||||
|
||||
|
@ -71,7 +68,6 @@ namespace Tests
|
|||
var resultComponentValues = resultComponents.Select((kv) => kv.Item2);
|
||||
resultComponentValues.Should().Contain(mockComponent);
|
||||
resultComponentValues.Should().Contain(mockComponentB);
|
||||
resultComponents.Should().NotContain((inactiveComponentAID, mockComponent));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -62,34 +62,6 @@ namespace Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InactiveDrawComponent()
|
||||
{
|
||||
var worldBuilder = new WorldBuilder();
|
||||
var renderer = worldBuilder.AddEntityRenderer(new TestRenderer());
|
||||
|
||||
AComponent aComponent;
|
||||
BComponent bComponent;
|
||||
TestDrawComponent testDrawComponent = default(TestDrawComponent);
|
||||
|
||||
var entity = worldBuilder.CreateEntity();
|
||||
worldBuilder.AddComponent(entity, aComponent);
|
||||
worldBuilder.AddComponent(entity, bComponent);
|
||||
var testDrawComponentID = worldBuilder.AddDrawComponent(entity, testDrawComponent, 1);
|
||||
|
||||
worldBuilder.DeactivateComponent(testDrawComponentID);
|
||||
|
||||
var world = worldBuilder.Build();
|
||||
|
||||
world.Update(0.01f);
|
||||
|
||||
Assert.IsFalse(renderer.IsTracking(entity.ID));
|
||||
|
||||
world.Draw();
|
||||
|
||||
Assert.IsFalse(called);
|
||||
}
|
||||
|
||||
static bool calledOnDraw = false;
|
||||
static IEnumerable<ValueTuple<Guid, TestDrawComponent>> resultComponents;
|
||||
[Renders(typeof(TestDrawComponent), typeof(AComponent), typeof(CComponent))]
|
||||
|
|
Loading…
Reference in New Issue