optimize component message system

pull/5/head
Evan Hemsley 2019-08-01 16:24:57 -07:00
parent ec3b0df585
commit d86c002305
7 changed files with 425 additions and 47 deletions

View File

@ -1,13 +1,300 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Linq;
namespace Encompass namespace Encompass
{ {
class ComponentMessageManager class ComponentMessageManager
{ {
private readonly Dictionary<Type, HashSet<IMessage>> componentMessageTypeToComponentMessages = new Dictionary<Type, HashSet<IMessage>>(); private readonly Dictionary<Guid, IComponent> componentIDToComponent = new Dictionary<Guid, IComponent>();
private readonly Dictionary<Type, HashSet<Guid>> componentMessageTypeToExistingComponentIDs = new Dictionary<Type, HashSet<Guid>>();
private readonly Dictionary<Type, HashSet<Guid>> componentMessageTypeToPendingComponentIDs = new Dictionary<Type, HashSet<Guid>>();
private readonly Dictionary<Type, HashSet<Guid>> componentMessageTypeToComponentIDs = new Dictionary<Type, HashSet<Guid>>();
private readonly Dictionary<Entity, Dictionary<Type, HashSet<Guid>>> entityToTypeToExistingComponentIDs = new Dictionary<Entity, Dictionary<Type, HashSet<Guid>>>();
private readonly Dictionary<Entity, Dictionary<Type, HashSet<Guid>>> entityToTypeToPendingComponentIDs = new Dictionary<Entity, Dictionary<Type, HashSet<Guid>>>();
private readonly Dictionary<Entity, Dictionary<Type, HashSet<Guid>>> entityToTypeToComponentIDs = new Dictionary<Entity, Dictionary<Type, HashSet<Guid>>>();
internal void ClearMessages()
{
componentIDToComponent.Clear();
foreach (var set in componentMessageTypeToExistingComponentIDs.Values)
{
set.Clear();
}
foreach (var set in componentMessageTypeToPendingComponentIDs.Values)
{
set.Clear();
}
foreach (var set in componentMessageTypeToComponentIDs.Values)
{
set.Clear();
}
foreach (var dictionary in entityToTypeToExistingComponentIDs.Values)
{
foreach (var set in dictionary.Values)
{
set.Clear();
}
}
foreach (var dictionary in entityToTypeToPendingComponentIDs.Values)
{
foreach (var set in dictionary.Values)
{
set.Clear();
}
}
foreach (var dictionary in entityToTypeToComponentIDs.Values)
{
foreach (var set in dictionary.Values)
{
set.Clear();
}
}
}
internal void RegisterDestroyedEntity(Entity entity)
{
entityToTypeToComponentIDs.Remove(entity);
entityToTypeToPendingComponentIDs.Remove(entity);
entityToTypeToExistingComponentIDs.Remove(entity);
}
internal void AddExistingComponentMessage<TComponent>(ComponentMessage<TComponent> componentMessage) where TComponent : struct, IComponent
{
RegisterExistingOrPendingComponentMessage(componentMessage.componentID, componentMessage.component);
if (!componentMessageTypeToExistingComponentIDs.ContainsKey(typeof(TComponent)))
{
componentMessageTypeToExistingComponentIDs.Add(typeof(TComponent), new HashSet<Guid>());
}
componentMessageTypeToExistingComponentIDs[typeof(TComponent)].Add(componentMessage.componentID);
if (!entityToTypeToExistingComponentIDs.ContainsKey(componentMessage.entity))
{
entityToTypeToExistingComponentIDs.Add(componentMessage.entity, new Dictionary<Type, HashSet<Guid>>());
}
if (!entityToTypeToExistingComponentIDs[componentMessage.entity].ContainsKey(typeof(TComponent)))
{
entityToTypeToExistingComponentIDs[componentMessage.entity].Add(typeof(TComponent), new HashSet<Guid>());
}
entityToTypeToExistingComponentIDs[componentMessage.entity][typeof(TComponent)].Add(componentMessage.componentID);
}
internal void AddPendingComponentMessage<TComponent>(PendingComponentMessage<TComponent> pendingComponentMessage) where TComponent : struct, IComponent
{
RegisterExistingOrPendingComponentMessage(pendingComponentMessage.componentID, pendingComponentMessage.component);
if (!componentMessageTypeToPendingComponentIDs.ContainsKey(typeof(TComponent)))
{
componentMessageTypeToPendingComponentIDs.Add(typeof(TComponent), new HashSet<Guid>());
}
componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Add(pendingComponentMessage.componentID);
if (!entityToTypeToPendingComponentIDs.ContainsKey(pendingComponentMessage.entity))
{
entityToTypeToPendingComponentIDs.Add(pendingComponentMessage.entity, new Dictionary<Type, HashSet<Guid>>());
}
if (!entityToTypeToPendingComponentIDs[pendingComponentMessage.entity].ContainsKey(typeof(TComponent)))
{
entityToTypeToPendingComponentIDs[pendingComponentMessage.entity].Add(typeof(TComponent), new HashSet<Guid>());
}
entityToTypeToPendingComponentIDs[pendingComponentMessage.entity][typeof(TComponent)].Add(pendingComponentMessage.componentID);
}
private void RegisterExistingOrPendingComponentMessage<TComponent>(Guid componentID, TComponent component) where TComponent: struct, IComponent
{
componentIDToComponent[componentID] = component;
if (!componentMessageTypeToComponentIDs.ContainsKey(typeof(TComponent)))
{
componentMessageTypeToComponentIDs.Add(typeof(TComponent), new HashSet<Guid>());
}
componentMessageTypeToComponentIDs[typeof(TComponent)].Add(componentID);
}
// general component reads by type
internal IEnumerable<(Guid, TComponent)> ReadExistingAndPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (componentMessageTypeToComponentIDs.TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Select(id => (id, (TComponent)componentIDToComponent[id]));
}
return Enumerable.Empty<(Guid, TComponent)>();
}
internal IEnumerable<(Guid, TComponent)> ReadExistingComponentsByType<TComponent>() where TComponent: struct, IComponent
{
HashSet<Guid> idSet;
if (componentMessageTypeToExistingComponentIDs.TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Select(id => (id, (TComponent)componentIDToComponent[id]));
}
return Enumerable.Empty<(Guid, TComponent)>();
}
internal IEnumerable<(Guid, TComponent)> ReadPendingComponentsByType<TComponent>() where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (componentMessageTypeToPendingComponentIDs.TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Select(id => (id, (TComponent)componentIDToComponent[id]));
}
return Enumerable.Empty<(Guid, TComponent)>();
}
// singular component reads by type
internal (Guid, TComponent) ReadFirstExistingOrPendingComponentByType<TComponent>() where TComponent : struct, IComponent
{
return ReadExistingAndPendingComponentsByType<TComponent>().First();
}
internal (Guid, TComponent) ReadFirstExistingComponentByType<TComponent>() where TComponent : struct, IComponent
{
return ReadExistingComponentsByType<TComponent>().First();
}
internal (Guid, TComponent) ReadFirstPendingComponentByType<TComponent>() where TComponent : struct, IComponent
{
return ReadPendingComponentsByType<TComponent>().First();
}
// check if some component of type exists in the world
internal bool SomeExistingOrPendingComponent<TComponent>() where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (componentMessageTypeToComponentIDs.TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Count > 0;
}
return false;
}
internal bool SomeExistingComponent<TComponent>() where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (componentMessageTypeToExistingComponentIDs.TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Count > 0;
}
return false;
}
internal bool SomePendingComponent<TComponent>() where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (componentMessageTypeToPendingComponentIDs.TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Count > 0;
}
return false;
}
// read components by entity and type
internal IEnumerable<(Guid, TComponent)> ReadExistingAndPendingComponentsByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (entityToTypeToComponentIDs.TryGetValue(entity, out _) && entityToTypeToComponentIDs[entity].TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Select(id => (id, (TComponent)componentIDToComponent[id]));
}
return Enumerable.Empty<(Guid, TComponent)>();
}
internal IEnumerable<(Guid, TComponent)> ReadExistingComponentsByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (entityToTypeToExistingComponentIDs.TryGetValue(entity, out _) && entityToTypeToExistingComponentIDs[entity].TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Select(id => (id, (TComponent)componentIDToComponent[id]));
}
return Enumerable.Empty<(Guid, TComponent)>();
}
internal IEnumerable<(Guid, TComponent)> ReadPendingComponentsByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (entityToTypeToPendingComponentIDs.TryGetValue(entity, out _) && entityToTypeToPendingComponentIDs[entity].TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Select(id => (id, (TComponent)componentIDToComponent[id]));
}
return Enumerable.Empty<(Guid, TComponent)>();
}
// singular read components by entity and type
internal (Guid, TComponent) ReadFirstExistingOrPendingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return ReadExistingAndPendingComponentsByEntityAndType<TComponent>(entity).First();
}
internal (Guid, TComponent) ReadFirstExistingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return ReadExistingComponentsByEntityAndType<TComponent>(entity).First();
}
internal (Guid, TComponent) ReadFirstPendingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return ReadPendingComponentsByEntityAndType<TComponent>(entity).First();
}
// check if entity has component of type
internal bool HasExistingOrPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (entityToTypeToComponentIDs.TryGetValue(entity, out _) && entityToTypeToComponentIDs[entity].TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Count > 0;
}
return false;
}
internal bool HasExistingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (entityToTypeToExistingComponentIDs.TryGetValue(entity, out _) && entityToTypeToExistingComponentIDs[entity].TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Count > 0;
}
return false;
}
internal bool HasPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{
HashSet<Guid> idSet;
if (entityToTypeToPendingComponentIDs.TryGetValue(entity, out _) && entityToTypeToPendingComponentIDs[entity].TryGetValue(typeof(TComponent), out idSet))
{
return idSet.Count > 0;
}
return false;
}
} }
} }

View File

@ -14,6 +14,7 @@ namespace Encompass
private EntityManager entityManager; private EntityManager entityManager;
private ComponentManager componentManager; private ComponentManager componentManager;
private MessageManager messageManager; private MessageManager messageManager;
private ComponentMessageManager componentMessageManager;
protected Engine() protected Engine()
{ {
@ -69,6 +70,11 @@ namespace Encompass
this.messageManager = messageManager; this.messageManager = messageManager;
} }
internal void AssignComponentMessageManager(ComponentMessageManager componentMessageManager)
{
this.componentMessageManager = componentMessageManager;
}
public abstract void Update(double dt); public abstract void Update(double dt);
protected Entity CreateEntity() protected Entity CreateEntity()
@ -119,11 +125,12 @@ namespace Encompass
if (sendTypes.Contains(typeof(PendingComponentMessage<TComponent>))) if (sendTypes.Contains(typeof(PendingComponentMessage<TComponent>)))
{ {
PendingComponentMessage<TComponent> componentMessage; PendingComponentMessage<TComponent> newComponentMessage;
componentMessage.entity = entity; newComponentMessage.entity = entity;
componentMessage.componentID = componentID; newComponentMessage.componentID = componentID;
componentMessage.component = component; newComponentMessage.component = component;
SendMessage(componentMessage); SendMessage(newComponentMessage);
SendPendingComponentMessage(newComponentMessage);
} }
return componentID; return componentID;
@ -142,36 +149,28 @@ namespace Encompass
newComponentMessage.componentID = componentID; newComponentMessage.componentID = componentID;
newComponentMessage.component = component; newComponentMessage.component = component;
SendMessage(newComponentMessage); SendMessage(newComponentMessage);
SendPendingComponentMessage(newComponentMessage);
} }
return componentID; return componentID;
} }
private IEnumerable<ValueTuple<Entity, Guid, TComponent>> ExistingComponents<TComponent>() where TComponent : struct, IComponent protected IEnumerable<ValueTuple<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent
{
return ReadMessages<ComponentMessage<TComponent>>().Select((message) => (message.entity, message.componentID, message.component));
}
private IEnumerable<ValueTuple<Entity, Guid, TComponent>> PendingComponents<TComponent>() where TComponent : struct, IComponent
{
return ReadMessages<PendingComponentMessage<TComponent>>().Select((message) => (message.entity, message.componentID, message.component));
}
private IEnumerable<ValueTuple<Entity, Guid, TComponent>> ReadComponentMessages<TComponent>() where TComponent : struct, IComponent
{ {
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>)); var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>)); var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
if (existingRead && pendingRead) if (existingRead && pendingRead)
{ {
return ExistingComponents<TComponent>().Union(PendingComponents<TComponent>()); return componentMessageManager.ReadExistingAndPendingComponentsByType<TComponent>();
} }
else if (existingRead) else if (existingRead)
{ {
return ExistingComponents<TComponent>(); return componentMessageManager.ReadExistingComponentsByType<TComponent>();
} }
else if (pendingRead) else if (pendingRead)
{ {
return PendingComponents<TComponent>(); return componentMessageManager.ReadPendingComponentsByType<TComponent>();
} }
else else
{ {
@ -179,44 +178,115 @@ namespace Encompass
} }
} }
private IEnumerable<ValueTuple<Guid, TComponent>> ExistingComponentsOnEntity<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return ReadComponentMessages<TComponent>().Where((triple) => triple.Item1 == entity).Select((triple) => (triple.Item2, triple.Item3));
}
private IEnumerable<ValueTuple<Guid, TComponent>> PendingComponentsOnEntity<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return ReadComponentMessages<TComponent>().Where((triple) => triple.Item1 == entity).Select((triple) => (triple.Item2, triple.Item3));
}
protected IEnumerable<ValueTuple<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent
{
return ReadComponentMessages<TComponent>().Select((triple) => (triple.Item2, triple.Item3));
}
protected ValueTuple<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent protected ValueTuple<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent
{ {
return ReadComponents<TComponent>().Single(); var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
if (existingRead && pendingRead)
{
return componentMessageManager.ReadFirstExistingOrPendingComponentByType<TComponent>();
}
else if (existingRead)
{
return componentMessageManager.ReadFirstExistingComponentByType<TComponent>();
}
else if (pendingRead)
{
return componentMessageManager.ReadFirstPendingComponentByType<TComponent>();
}
else
{
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
}
} }
protected bool SomeComponent<TComponent>() where TComponent : struct, IComponent protected bool SomeComponent<TComponent>() where TComponent : struct, IComponent
{ {
return ReadComponentMessages<TComponent>().Any(); var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
if (existingRead && pendingRead)
{
return componentMessageManager.SomeExistingOrPendingComponent<TComponent>();
}
else if (existingRead)
{
return componentMessageManager.SomeExistingComponent<TComponent>();
}
else if (pendingRead)
{
return componentMessageManager.SomePendingComponent<TComponent>();
}
else
{
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
}
} }
protected IEnumerable<ValueTuple<Guid, TComponent>> GetComponents<TComponent>(Entity entity) where TComponent : struct, IComponent protected IEnumerable<ValueTuple<Guid, TComponent>> GetComponents<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return ExistingComponentsOnEntity<TComponent>(entity); var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
if (existingRead && pendingRead)
{
return componentMessageManager.ReadExistingAndPendingComponentsByEntityAndType<TComponent>(entity);
}
else if (existingRead)
{
return componentMessageManager.ReadExistingComponentsByEntityAndType<TComponent>(entity);
}
else if (pendingRead)
{
return componentMessageManager.ReadPendingComponentsByEntityAndType<TComponent>(entity);
}
else
{
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
}
} }
protected ValueTuple<Guid, TComponent> GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent protected ValueTuple<Guid, TComponent> GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return GetComponents<TComponent>(entity).First(); var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
if (existingRead && pendingRead)
{
return componentMessageManager.ReadFirstExistingOrPendingComponentByEntityAndType<TComponent>(entity);
}
else if (existingRead)
{
return componentMessageManager.ReadFirstExistingComponentByEntityAndType<TComponent>(entity);
}
else if (pendingRead)
{
return componentMessageManager.ReadFirstPendingComponentByEntityAndType<TComponent>(entity);
}
else
{
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
}
} }
protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return GetComponents<TComponent>(entity).Any(); var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
if (pendingRead && existingRead)
{
return componentMessageManager.HasExistingOrPendingComponent<TComponent>(entity);
}
else if (existingRead)
{
return componentMessageManager.HasExistingComponent<TComponent>(entity);
}
else if (pendingRead)
{
return componentMessageManager.HasPendingComponent<TComponent>(entity);
}
else
{
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
}
} }
internal void UpdateComponentInWorld<TComponent>(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent internal void UpdateComponentInWorld<TComponent>(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent
@ -260,6 +330,16 @@ namespace Encompass
messageManager.AddMessage(message); messageManager.AddMessage(message);
} }
internal void SendExistingComponentMessage<TComponent>(ComponentMessage<TComponent> message) where TComponent : struct, IComponent
{
componentMessageManager.AddExistingComponentMessage(message);
}
internal void SendPendingComponentMessage<TComponent>(PendingComponentMessage<TComponent> message) where TComponent : struct, IComponent
{
componentMessageManager.AddPendingComponentMessage(message);
}
protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage
{ {
if (!receiveTypes.Contains(typeof(TMessage))) if (!receiveTypes.Contains(typeof(TMessage)))

View File

@ -18,6 +18,7 @@ namespace Encompass.Engines
componentMessage.componentID = componentID; componentMessage.componentID = componentID;
componentMessage.component = component; componentMessage.component = component;
SendMessage(componentMessage); SendMessage(componentMessage);
SendExistingComponentMessage(componentMessage);
} }
} }
} }

View File

@ -10,10 +10,12 @@ namespace Encompass
private readonly HashSet<Guid> entitiesMarkedForDestroy = new HashSet<Guid>(); private readonly HashSet<Guid> entitiesMarkedForDestroy = new HashSet<Guid>();
private readonly ComponentManager componentManager; private readonly ComponentManager componentManager;
private readonly ComponentMessageManager componentMessageManager;
public EntityManager(ComponentManager componentManager) public EntityManager(ComponentManager componentManager, ComponentMessageManager componentMessageManager)
{ {
this.componentManager = componentManager; this.componentManager = componentManager;
this.componentMessageManager = componentMessageManager;
} }
public Entity CreateEntity() public Entity CreateEntity()
@ -44,6 +46,7 @@ namespace Encompass
{ {
foreach (var entityID in entitiesMarkedForDestroy) foreach (var entityID in entitiesMarkedForDestroy)
{ {
componentMessageManager.RegisterDestroyedEntity(GetEntity(entityID));
componentManager.MarkAllComponentsOnEntityForRemoval(entityID); componentManager.MarkAllComponentsOnEntityForRemoval(entityID);
IDToEntity.Remove(entityID); IDToEntity.Remove(entityID);
componentManager.RegisterDestroyedEntity(entityID); componentManager.RegisterDestroyedEntity(entityID);

View File

@ -8,6 +8,7 @@ namespace Encompass
private readonly EntityManager entityManager; private readonly EntityManager entityManager;
private readonly ComponentManager componentManager; private readonly ComponentManager componentManager;
private readonly MessageManager messageManager; private readonly MessageManager messageManager;
private readonly ComponentMessageManager componentMessageManager;
private readonly RenderManager renderManager; private readonly RenderManager renderManager;
internal World( internal World(
@ -15,6 +16,7 @@ namespace Encompass
EntityManager entityManager, EntityManager entityManager,
ComponentManager componentManager, ComponentManager componentManager,
MessageManager messageManager, MessageManager messageManager,
ComponentMessageManager componentMessageManager,
RenderManager renderManager RenderManager renderManager
) )
{ {
@ -22,6 +24,7 @@ namespace Encompass
this.entityManager = entityManager; this.entityManager = entityManager;
this.componentManager = componentManager; this.componentManager = componentManager;
this.messageManager = messageManager; this.messageManager = messageManager;
this.componentMessageManager = componentMessageManager;
this.renderManager = renderManager; this.renderManager = renderManager;
} }
@ -33,6 +36,7 @@ namespace Encompass
} }
messageManager.ClearMessages(); messageManager.ClearMessages();
componentMessageManager.ClearMessages();
entityManager.DestroyMarkedEntities(); entityManager.DestroyMarkedEntities();
componentManager.PerformComponentUpdates(); componentManager.PerformComponentUpdates();

View File

@ -15,6 +15,7 @@ namespace Encompass
private readonly ComponentManager componentManager; private readonly ComponentManager componentManager;
private readonly EntityManager entityManager; private readonly EntityManager entityManager;
private readonly MessageManager messageManager; private readonly MessageManager messageManager;
private readonly ComponentMessageManager componentMessageManager;
private readonly DrawLayerManager drawLayerManager; private readonly DrawLayerManager drawLayerManager;
private readonly RenderManager renderManager; private readonly RenderManager renderManager;
@ -23,16 +24,14 @@ namespace Encompass
private readonly HashSet<Engine> senders = new HashSet<Engine>(); private readonly HashSet<Engine> senders = new HashSet<Engine>();
private readonly HashSet<Type> registeredComponentTypes = new HashSet<Type>(); private readonly HashSet<Type> registeredComponentTypes = new HashSet<Type>();
private readonly HashSet<Type> registeredNewComponentTypes = new HashSet<Type>();
public WorldBuilder() public WorldBuilder()
{ {
var entitiesWithAddedComponents = new HashSet<Guid>();
var entitiesWithRemovedComponents = new HashSet<Guid>();
drawLayerManager = new DrawLayerManager(); drawLayerManager = new DrawLayerManager();
componentManager = new ComponentManager(drawLayerManager); componentManager = new ComponentManager(drawLayerManager);
entityManager = new EntityManager(componentManager);
messageManager = new MessageManager(); messageManager = new MessageManager();
componentMessageManager = new ComponentMessageManager();
entityManager = new EntityManager(componentManager, componentMessageManager);
renderManager = new RenderManager(entityManager, componentManager, drawLayerManager); renderManager = new RenderManager(entityManager, componentManager, drawLayerManager);
} }
@ -74,6 +73,7 @@ namespace Encompass
engine.AssignEntityManager(entityManager); engine.AssignEntityManager(entityManager);
engine.AssignComponentManager(componentManager); engine.AssignComponentManager(componentManager);
engine.AssignMessageManager(messageManager); engine.AssignMessageManager(messageManager);
engine.AssignComponentMessageManager(componentMessageManager);
engines.Add(engine); engines.Add(engine);
engineGraph.AddVertex(engine); engineGraph.AddVertex(engine);
@ -250,6 +250,7 @@ namespace Encompass
entityManager, entityManager,
componentManager, componentManager,
messageManager, messageManager,
componentMessageManager,
renderManager renderManager
); );

View File

@ -112,7 +112,9 @@ namespace Tests
var world = worldBuilder.Build(); var world = worldBuilder.Build();
Assert.Throws<InvalidOperationException>(() => world.Update(0.01f)); world.Update(0.01);
Assert.That(resultComponent, Is.EqualTo(mockComponent).Or.EqualTo(mockComponentB));
} }
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]