remove exposed GUIDs from the API

pull/5/head
Evan Hemsley 2019-11-20 19:01:29 -08:00
parent 6579c706c5
commit 62dfdb758a
11 changed files with 201 additions and 423 deletions

View File

@ -13,7 +13,7 @@ namespace Encompass
/// </summary> /// </summary>
public abstract class Engine : IEquatable<Engine> public abstract class Engine : IEquatable<Engine>
{ {
public Guid ID; internal Guid ID;
internal readonly HashSet<Type> sendTypes = new HashSet<Type>(); internal readonly HashSet<Type> sendTypes = new HashSet<Type>();
internal readonly HashSet<Type> receiveTypes = new HashSet<Type>(); internal readonly HashSet<Type> receiveTypes = new HashSet<Type>();
@ -123,7 +123,7 @@ namespace Encompass
/// <summary> /// <summary>
/// Returns true if an Entity with the specified ID exists. /// Returns true if an Entity with the specified ID exists.
/// </summary> /// </summary>
protected bool EntityExists(Guid entityID) internal bool EntityExists(Guid entityID)
{ {
return entityManager.EntityExists(entityID); return entityManager.EntityExists(entityID);
} }
@ -134,7 +134,7 @@ namespace Encompass
/// <exception cref="Encompass.Exceptions.EntityNotFoundException"> /// <exception cref="Encompass.Exceptions.EntityNotFoundException">
/// Thrown when an Entity with the given ID does not exist. /// Thrown when an Entity with the given ID does not exist.
/// </exception> /// </exception>
protected Entity GetEntity(Guid entityID) internal Entity GetEntity(Guid entityID)
{ {
return entityManager.GetEntity(entityID); return entityManager.GetEntity(entityID);
} }
@ -142,7 +142,7 @@ namespace Encompass
/// <summary> /// <summary>
/// Returns the Entity ID associated with the specified Component Type and ID. /// Returns the Entity ID associated with the specified Component Type and ID.
/// </summary> /// </summary>
protected Guid GetEntityIDByComponentID<TComponent>(Guid componentID) where TComponent : struct, IComponent private Guid GetEntityIDByComponentID<TComponent>(Guid componentID) 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>));
@ -158,7 +158,7 @@ namespace Encompass
/// <summary> /// <summary>
/// Returns the Entity associated with the specified Component Type and ID. /// Returns the Entity associated with the specified Component Type and ID.
/// </summary> /// </summary>
protected Entity GetEntityByComponentID<TComponent>(Guid componentID) where TComponent : struct, IComponent private Entity GetEntityByComponentID<TComponent>(Guid componentID) where TComponent : struct, IComponent
{ {
return GetEntity(GetEntityIDByComponentID<TComponent>(componentID)); return GetEntity(GetEntityIDByComponentID<TComponent>(componentID));
} }
@ -168,7 +168,7 @@ namespace Encompass
/// </summary> /// </summary>
protected Entity ReadEntity<TComponent>() where TComponent : struct, IComponent protected Entity ReadEntity<TComponent>() where TComponent : struct, IComponent
{ {
var (id, component) = ReadComponent<TComponent>(); var (id, component) = ReadComponentHelper<TComponent>();
return GetEntityByComponentID<TComponent>(id); return GetEntityByComponentID<TComponent>(id);
} }
@ -177,7 +177,7 @@ namespace Encompass
/// </summary> /// </summary>
protected IEnumerable<Entity> ReadEntities<TComponent>() where TComponent : struct, IComponent protected IEnumerable<Entity> ReadEntities<TComponent>() where TComponent : struct, IComponent
{ {
foreach (var (id, component) in ReadComponents<TComponent>()) foreach (var (id, _) in ReadComponentsHelper<TComponent>())
{ {
yield return GetEntityByComponentID<TComponent>(id); yield return GetEntityByComponentID<TComponent>(id);
} }
@ -186,7 +186,7 @@ namespace Encompass
/// <summary> /// <summary>
/// Returns the Component struct with the specified Component Type and ID. /// Returns the Component struct with the specified Component Type and ID.
/// </summary> /// </summary>
protected TComponent GetComponentByID<TComponent>(Guid componentID) where TComponent : struct, IComponent internal TComponent GetComponentByID<TComponent>(Guid componentID) 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>));
@ -216,10 +216,7 @@ namespace Encompass
return GetEntity(componentManager.GetEntityIDByComponentID(componentID)); return GetEntity(componentManager.GetEntityIDByComponentID(componentID));
} }
/// <summary> private IEnumerable<(Guid, TComponent)> ReadComponentsHelper<TComponent>() where TComponent : struct, IComponent
/// Returns all of the Components with the specified Component Type.
/// </summary>
protected IEnumerable<(Guid, TComponent)> ReadComponents<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>));
@ -242,17 +239,22 @@ namespace Encompass
} }
/// <summary> /// <summary>
/// Returns all of the components of the specified type including an Entity reference for each Component. /// Returns all of the Components with the specified Component Type.
/// </summary> /// </summary>
protected IEnumerable<(Guid, TComponent, Entity)> ReadComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent protected IEnumerable<TComponent> ReadComponents<TComponent>() where TComponent : struct, IComponent
{ {
return ReadComponents<TComponent>().Select((tuple) => (tuple.Item1, tuple.Item2, GetEntityByComponentID<TComponent>(tuple.Item1))); return ReadComponentsHelper<TComponent>().Select(tuple => tuple.Item2);
} }
/// <summary> /// <summary>
/// Returns a Component with the specified Component Type. If multiples exist, an arbitrary Component is returned. /// Returns all of the components of the specified type including an Entity reference for each Component.
/// </summary> /// </summary>
protected (Guid, TComponent) ReadComponent<TComponent>() where TComponent : struct, IComponent protected IEnumerable<(TComponent, Entity)> ReadComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent
{
return ReadComponentsHelper<TComponent>().Select((tuple) => (tuple.Item2, GetEntityByComponentID<TComponent>(tuple.Item1)));
}
private (Guid, TComponent) ReadComponentHelper<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>));
@ -274,13 +276,21 @@ namespace Encompass
} }
} }
/// <summary>
/// Returns a Component with the specified Component Type. If multiples exist, an arbitrary Component is returned.
/// </summary>
protected TComponent ReadComponent<TComponent>() where TComponent : struct, IComponent
{
return ReadComponentHelper<TComponent>().Item2;
}
/// <summary> /// <summary>
/// Returns a component of the specified type including its Entity reference. If multiples exist, an arbitrary Component is returned. /// Returns a component of the specified type including its Entity reference. If multiples exist, an arbitrary Component is returned.
/// </summary> /// </summary>
protected (Guid, TComponent, Entity) ReadComponentIncludingEntity<TComponent>() where TComponent : struct, IComponent protected (TComponent, Entity) ReadComponentIncludingEntity<TComponent>() where TComponent : struct, IComponent
{ {
var (id, component) = ReadComponent<TComponent>(); var (id, component) = ReadComponentHelper<TComponent>();
return (id, component, GetEntityByComponentID<TComponent>(id)); return (component, GetEntityByComponentID<TComponent>(id));
} }
/// <summary> /// <summary>
@ -308,16 +318,7 @@ namespace Encompass
} }
} }
/// <summary> private (Guid, TComponent) GetComponentHelper<TComponent>(Entity entity) where TComponent : struct, IComponent
/// Returns a Component with the specified Type that exists on the Entity.
/// </summary>
/// <exception cref="Encompass.Exceptions.NoComponentOfTypeOnEntityException">
/// Thrown when the Entity does not have a Component of the specified Type
/// </exception>
/// <exception cref="Encompass.Exceptions.IllegalReadException">
/// Thrown when the Engine does not declare that it reads the given Component Type.
/// </exception>
protected (Guid, TComponent) GetComponent<TComponent>(Entity entity) 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>));
@ -359,7 +360,12 @@ namespace Encompass
/// <exception cref="Encompass.Exceptions.IllegalReadException"> /// <exception cref="Encompass.Exceptions.IllegalReadException">
/// Thrown when the Engine does not declare that it reads the given Component Type. /// Thrown when the Engine does not declare that it reads the given Component Type.
/// </exception> /// </exception>
protected (Guid, IComponent) GetComponent(Entity entity, Type type) protected TComponent GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return GetComponentHelper<TComponent>(entity).Item2;
}
private (Guid, IComponent) GetComponentHelper(Entity entity, Type type)
{ {
var pending = typeof(PendingComponentMessage<>).MakeGenericType(type); var pending = typeof(PendingComponentMessage<>).MakeGenericType(type);
var existing = typeof(ComponentMessage<>).MakeGenericType(type); var existing = typeof(ComponentMessage<>).MakeGenericType(type);
@ -396,6 +402,20 @@ namespace Encompass
} }
} }
/// <summary>
/// Returns a Component with the specified Type that exists on the Entity.
/// </summary>
/// <exception cref="Encompass.Exceptions.NoComponentOfTypeOnEntityException">
/// Thrown when the Entity does not have a Component of the specified Type
/// </exception>
/// <exception cref="Encompass.Exceptions.IllegalReadException">
/// Thrown when the Engine does not declare that it reads the given Component Type.
/// </exception>
protected IComponent GetComponent(Entity entity, Type type)
{
return GetComponentHelper(entity, type).Item2;
}
/// <summary> /// <summary>
/// Returns true if the Entity has a Component of the given Type. /// Returns true if the Entity has a Component of the given Type.
/// </summary> /// </summary>
@ -463,7 +483,7 @@ namespace Encompass
/// <exception cref="Encompass.Exceptions.IllegalWriteException"> /// <exception cref="Encompass.Exceptions.IllegalWriteException">
/// Thrown when the Engine does not declare that it Writes the given Component Type. /// Thrown when the Engine does not declare that it Writes the given Component Type.
/// </exception> /// </exception>
protected Guid SetComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent protected void SetComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
{ {
var priority = writePriorities.ContainsKey(typeof(TComponent)) ? writePriorities[typeof(TComponent)] : 0; var priority = writePriorities.ContainsKey(typeof(TComponent)) ? writePriorities[typeof(TComponent)] : 0;
@ -483,16 +503,14 @@ namespace Encompass
newComponentMessage.priority = priority; newComponentMessage.priority = priority;
SendPendingComponentMessage(newComponentMessage); SendPendingComponentMessage(newComponentMessage);
} }
return componentID;
} }
/// <summary> /// <summary>
/// Overwrites Component struct data associated with the specified Component ID. /// Overwrites Component struct data associated with the specified Component ID.
/// </summary> /// </summary>
protected Guid SetComponent<TComponent>(Guid componentID, TComponent component) where TComponent : struct, IComponent internal void SetComponent<TComponent>(Guid componentID, TComponent component) where TComponent : struct, IComponent
{ {
return SetComponent(GetEntityByComponentID<TComponent>(componentID), component); SetComponent(GetEntityByComponentID<TComponent>(componentID), component);
} }
/// <summary> /// <summary>
@ -503,7 +521,7 @@ namespace Encompass
/// <exception cref="Encompass.Exceptions.IllegalWriteException"> /// <exception cref="Encompass.Exceptions.IllegalWriteException">
/// Thrown when the Engine does not declare that it Writes the given Component Type. /// Thrown when the Engine does not declare that it Writes the given Component Type.
/// </exception> /// </exception>
protected Guid SetDrawComponent<TComponent>(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent, IDrawComponent protected void SetDrawComponent<TComponent>(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent, IDrawComponent
{ {
var priority = writePriorities.ContainsKey(typeof(TComponent)) ? writePriorities[typeof(TComponent)] : 0; var priority = writePriorities.ContainsKey(typeof(TComponent)) ? writePriorities[typeof(TComponent)] : 0;
@ -523,8 +541,6 @@ namespace Encompass
newComponentMessage.priority = priority; newComponentMessage.priority = priority;
SendPendingComponentMessage(newComponentMessage); SendPendingComponentMessage(newComponentMessage);
} }
return componentID;
} }
/// <summary> /// <summary>
@ -622,7 +638,7 @@ namespace Encompass
/// Destroys the Entity with the specified ID. This also removes all of the Components associated with the Entity. /// Destroys the Entity with the specified ID. This also removes all of the Components associated with the Entity.
/// Entity destruction takes place after all the Engines have been processed by World Update. /// Entity destruction takes place after all the Engines have been processed by World Update.
/// </summary> /// </summary>
protected void Destroy(Guid entityID) internal void Destroy(Guid entityID)
{ {
entityManager.MarkForDestroy(entityID); entityManager.MarkForDestroy(entityID);
} }
@ -660,17 +676,22 @@ namespace Encompass
/// <summary> /// <summary>
/// Removes a Component with the specified type from the given Entity. /// Removes a Component with the specified type from the given Entity.
/// Note that the Engine must Read the Component type that is being removed. /// Note that the Engine must Read the Component type that is being removed.
/// If a Component with the specified type does not exist on the Entity, returns false and does not mutate the Entity.
/// </summary> /// </summary>
protected void RemoveComponent<TComponent>(Entity entity) where TComponent : struct, IComponent protected bool RemoveComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
var (componentID, _) = GetComponent<TComponent>(entity); if (!HasComponent<TComponent>(entity)) { return false; }
var (componentID, _) = GetComponentHelper<TComponent>(entity);
RemoveComponent(componentID); RemoveComponent(componentID);
return true;
} }
/// <summary> /// <summary>
/// Removes the Component with the specified ID from its Entity. /// Removes the Component with the specified ID from its Entity.
/// </summary> /// </summary>
protected void RemoveComponent(Guid componentID) private void RemoveComponent(Guid componentID)
{ {
componentManager.MarkForRemoval(componentID); componentManager.MarkForRemoval(componentID);
} }

View File

@ -8,19 +8,22 @@ namespace Encompass
{ {
private readonly ComponentManager componentManager; private readonly ComponentManager componentManager;
private readonly DrawLayerManager drawLayerManager; private readonly DrawLayerManager drawLayerManager;
private readonly EntityManager entityManager;
private readonly Dictionary<Type, Action<Guid, IComponent>> drawComponentTypeToOrderedRenderer = new Dictionary<Type, Action<Guid, IComponent>>(); private readonly Dictionary<Type, Action<Entity, IComponent>> drawComponentTypeToOrderedRenderer = new Dictionary<Type, Action<Entity, IComponent>>();
public RenderManager( public RenderManager(
ComponentManager componentManager, ComponentManager componentManager,
DrawLayerManager drawLayerManager DrawLayerManager drawLayerManager,
EntityManager entityManager
) )
{ {
this.componentManager = componentManager; this.componentManager = componentManager;
this.drawLayerManager = drawLayerManager; this.drawLayerManager = drawLayerManager;
this.entityManager = entityManager;
} }
public void RegisterOrderedRenderer<TComponent>(Action<Guid, IComponent> renderAction) where TComponent : struct, IComponent public void RegisterOrderedRenderer<TComponent>(Action<Entity, IComponent> renderAction) where TComponent : struct, IComponent
{ {
drawComponentTypeToOrderedRenderer.Add(typeof(TComponent), renderAction); drawComponentTypeToOrderedRenderer.Add(typeof(TComponent), renderAction);
} }
@ -41,11 +44,13 @@ namespace Encompass
{ {
var component = componentManager.GetComponentByID(componentID); var component = componentManager.GetComponentByID(componentID);
var componentType = componentManager.GetComponentTypeByID(componentID); var componentType = componentManager.GetComponentTypeByID(componentID);
var entityID = componentManager.GetEntityIDByComponentID(componentID);
var entity = entityManager.GetEntity(entityID);
if (drawComponentTypeToOrderedRenderer.ContainsKey(componentType)) if (drawComponentTypeToOrderedRenderer.ContainsKey(componentType))
{ {
var internalRenderAction = drawComponentTypeToOrderedRenderer[componentType]; var internalRenderAction = drawComponentTypeToOrderedRenderer[componentType];
internalRenderAction(componentID, component); internalRenderAction(entity, component);
} }
} }

View File

@ -19,39 +19,39 @@ namespace Encompass
this.componentManager = componentManager; this.componentManager = componentManager;
} }
protected bool EntityExists(Guid entityID) internal Guid GetEntityIDByComponentID(Guid componentID)
{
return entityManager.EntityExists(entityID);
}
protected Entity GetEntity(Guid entityID)
{
return entityManager.GetEntity(entityID);
}
protected Guid GetEntityIDByComponentID(Guid componentID)
{ {
return componentManager.GetEntityIDByComponentID(componentID); return componentManager.GetEntityIDByComponentID(componentID);
} }
protected Entity GetEntityByComponentID(Guid componentID) internal Entity GetEntity(Guid entityID)
{ {
return GetEntity(GetEntityIDByComponentID(componentID)); return entityManager.GetEntity(entityID);
} }
protected IEnumerable<ValueTuple<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent protected IEnumerable<TComponent> ReadComponents<TComponent>() where TComponent : struct, IComponent
{ {
return componentManager.GetComponentsByType<TComponent>(); return componentManager.GetComponentsByType<TComponent>().Select(tuple => tuple.Item2);
} }
protected ValueTuple<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent protected IEnumerable<(TComponent, Entity)> ReadComponentsIncludingEntity<TComponent>() where TComponent : struct, IComponent
{
return componentManager.GetComponentsByType<TComponent>().Select(tuple => (tuple.Item2, GetEntity(GetEntityIDByComponentID(tuple.Item1))));
}
protected TComponent ReadComponent<TComponent>() where TComponent : struct, IComponent
{ {
return ReadComponents<TComponent>().First(); return ReadComponents<TComponent>().First();
} }
protected ValueTuple<Guid, TComponent> GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent protected (TComponent, Entity) ReadComponentIncludingEntity<TComponent>() where TComponent : struct, IComponent
{ {
return componentManager.GetComponentByEntityAndType<TComponent>(entity); return ReadComponentsIncludingEntity<TComponent>().First();
}
protected TComponent GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return componentManager.GetComponentByEntityAndType<TComponent>(entity).Item2;
} }
protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent

View File

@ -7,11 +7,11 @@ namespace Encompass
/// </summary> /// </summary>
public abstract class OrderedRenderer<TComponent> : Renderer where TComponent : struct, IComponent, IDrawComponent public abstract class OrderedRenderer<TComponent> : Renderer where TComponent : struct, IComponent, IDrawComponent
{ {
public abstract void Render(Guid drawComponentID, TComponent drawComponent); public abstract void Render(Entity entity, TComponent drawComponent);
internal void InternalRender(Guid drawComponentId, IComponent component) internal void InternalRender(Entity entity, IComponent component)
{ {
Render(drawComponentId, (TComponent)component); Render(entity, (TComponent)component);
} }
} }
} }

View File

@ -42,7 +42,7 @@ namespace Encompass
messageManager = new MessageManager(); messageManager = new MessageManager();
componentMessageManager = new ComponentMessageManager(); componentMessageManager = new ComponentMessageManager();
entityManager = new EntityManager(componentManager, componentMessageManager); entityManager = new EntityManager(componentManager, componentMessageManager);
renderManager = new RenderManager(componentManager, drawLayerManager); renderManager = new RenderManager(componentManager, drawLayerManager, entityManager);
} }
/// <summary> /// <summary>
@ -72,18 +72,18 @@ namespace Encompass
/// <summary> /// <summary>
/// Sets Component data for the specified Component Type on the specified Entity. /// Sets Component data for the specified Component Type on the specified Entity.
/// </summary> /// </summary>
public Guid SetComponent<TComponent>(Entity entity, TComponent component, int priority = 0) where TComponent : struct, IComponent public void SetComponent<TComponent>(Entity entity, TComponent component, int priority = 0) where TComponent : struct, IComponent
{ {
return componentManager.MarkComponentForWrite(entity, component, priority); componentManager.MarkComponentForWrite(entity, component, priority);
} }
/// <summary> /// <summary>
/// Sets Draw Component data for the specified Component Type on the specified Entity. /// Sets Draw Component data for the specified Component Type on the specified Entity.
/// This method must be used for the Draw Component to be readable by an OrderedRenderer. /// This method must be used for the Draw Component to be readable by an OrderedRenderer.
/// </summary> /// </summary>
public Guid SetDrawComponent<TComponent>(Entity entity, TComponent component, int priority = 0, int layer = 0) where TComponent : struct, IComponent, IDrawComponent public void SetDrawComponent<TComponent>(Entity entity, TComponent component, int priority = 0, int layer = 0) where TComponent : struct, IComponent, IDrawComponent
{ {
return componentManager.MarkDrawComponentForWrite(entity, component, priority, layer); componentManager.MarkDrawComponentForWrite(entity, component, priority, layer);
} }
internal void RegisterComponent(Type componentType) internal void RegisterComponent(Type componentType)

View File

@ -23,7 +23,7 @@ namespace Tests
public Entity entity; public Entity entity;
} }
static (Guid, MockComponent) gottenMockComponentIDPair; static MockComponent gottenMockComponent;
[Receives(typeof(EntityMessage))] [Receives(typeof(EntityMessage))]
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
@ -33,7 +33,7 @@ namespace Tests
{ {
foreach (var entityMessage in ReadMessages<EntityMessage>()) foreach (var entityMessage in ReadMessages<EntityMessage>())
{ {
gottenMockComponentIDPair = GetComponent<MockComponent>(entityMessage.entity); gottenMockComponent = GetComponent<MockComponent>(entityMessage.entity);
} }
} }
} }
@ -53,7 +53,7 @@ namespace Tests
foreach (var addComponentTestMessage in ReadMessages<AddComponentTestMessage>()) foreach (var addComponentTestMessage in ReadMessages<AddComponentTestMessage>())
{ {
Assert.IsTrue(HasComponent<MockComponent>(addComponentTestMessage.entity)); Assert.IsTrue(HasComponent<MockComponent>(addComponentTestMessage.entity));
Assert.That(GetComponent<MockComponent>(addComponentTestMessage.entity).Item2, Is.EqualTo(addComponentTestMessage.mockComponent)); Assert.That(GetComponent<MockComponent>(addComponentTestMessage.entity), Is.EqualTo(addComponentTestMessage.mockComponent));
} }
} }
} }
@ -97,8 +97,8 @@ namespace Tests
world.Update(0.01); world.Update(0.01);
Assert.That(gottenMockComponentIDPair.Item2.myInt, Is.EqualTo(50)); Assert.That(gottenMockComponent.myInt, Is.EqualTo(50));
Assert.That(gottenMockComponentIDPair.Item2.myString, Is.EqualTo("hi")); Assert.That(gottenMockComponent.myString, Is.EqualTo("hi"));
} }
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
@ -108,10 +108,8 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var (mockComponentID, mockComponent) in ReadComponents<MockComponent>()) foreach (var (mockComponent, entity) in ReadComponentsIncludingEntity<MockComponent>())
{ {
var entity = GetEntityByComponentID<MockComponent>(mockComponentID);
SetComponent(entity, new MockComponent { myInt = 420 }); SetComponent(entity, new MockComponent { myInt = 420 });
} }
} }
@ -123,7 +121,7 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
gottenMockComponentIDPair = ReadComponent<MockComponent>(); gottenMockComponent = ReadComponent<MockComponent>();
} }
} }
@ -140,7 +138,7 @@ namespace Tests
var world = worldBuilder.Build(); var world = worldBuilder.Build();
world.Update(0.01); world.Update(0.01);
Assert.That(gottenMockComponentIDPair.Item2.myInt, Is.EqualTo(420)); Assert.That(gottenMockComponent.myInt, Is.EqualTo(420));
} }
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
@ -149,11 +147,10 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var (mockComponentID, mockComponent) in ReadComponents<MockComponent>()) foreach (var (mockComponent, entity) in ReadComponentsIncludingEntity<MockComponent>())
{ {
var entity = GetEntityByComponentID<MockComponent>(mockComponentID);
SetComponent(entity, mockComponent); SetComponent(entity, mockComponent);
RemoveComponent(mockComponentID); RemoveComponent<MockComponent>(entity);
} }
} }
} }
@ -258,7 +255,7 @@ namespace Tests
mockComponent.myInt = 3; mockComponent.myInt = 3;
mockComponent.myString = "hello"; mockComponent.myString = "hello";
var componentID = worldBuilder.SetComponent<MockComponent>(entity, mockComponent); worldBuilder.SetComponent<MockComponent>(entity, mockComponent);
EntityMessage entityMessage; EntityMessage entityMessage;
entityMessage.entity = entity; entityMessage.entity = entity;
@ -268,7 +265,7 @@ namespace Tests
world.Update(0.01); world.Update(0.01);
Assert.AreEqual((componentID, mockComponent), gottenMockComponentIDPair); Assert.AreEqual(mockComponent, gottenMockComponent);
} }
[Receives(typeof(EntityMessage))] [Receives(typeof(EntityMessage))]
@ -279,7 +276,7 @@ namespace Tests
{ {
foreach (var entityMessage in ReadMessages<EntityMessage>()) foreach (var entityMessage in ReadMessages<EntityMessage>())
{ {
gottenMockComponentIDPair = ((Guid, MockComponent))GetComponent(entityMessage.entity, typeof(MockComponent)); gottenMockComponent = (MockComponent)GetComponent(entityMessage.entity, typeof(MockComponent));
} }
} }
} }
@ -296,7 +293,7 @@ namespace Tests
mockComponent.myInt = 3; mockComponent.myInt = 3;
mockComponent.myString = "hello"; mockComponent.myString = "hello";
var componentID = worldBuilder.SetComponent<MockComponent>(entity, mockComponent); worldBuilder.SetComponent<MockComponent>(entity, mockComponent);
EntityMessage entityMessage; EntityMessage entityMessage;
entityMessage.entity = entity; entityMessage.entity = entity;
@ -306,7 +303,7 @@ namespace Tests
world.Update(0.01); world.Update(0.01);
Assert.AreEqual((componentID, mockComponent), gottenMockComponentIDPair); Assert.AreEqual(mockComponent, gottenMockComponent);
} }
struct HasComponentTestMessage : IMessage struct HasComponentTestMessage : IMessage
@ -389,9 +386,9 @@ namespace Tests
struct RemoveComponentTestMessage : IMessage struct RemoveComponentTestMessage : IMessage
{ {
public Entity entity; public Entity entity;
public Guid componentID;
} }
[Reads(typeof(MockComponent))]
[Receives(typeof(RemoveComponentTestMessage))] [Receives(typeof(RemoveComponentTestMessage))]
class RemoveComponentTestEngine : Engine class RemoveComponentTestEngine : Engine
{ {
@ -399,7 +396,7 @@ namespace Tests
{ {
foreach (var removeComponentMessage in ReadMessages<RemoveComponentTestMessage>()) foreach (var removeComponentMessage in ReadMessages<RemoveComponentTestMessage>())
{ {
RemoveComponent(removeComponentMessage.componentID); RemoveComponent<MockComponent>(removeComponentMessage.entity);
} }
} }
} }
@ -461,11 +458,10 @@ namespace Tests
mockComponent.myInt = 3; mockComponent.myInt = 3;
mockComponent.myString = "hello"; mockComponent.myString = "hello";
var componentID = worldBuilder.SetComponent(entity, mockComponent); worldBuilder.SetComponent(entity, mockComponent);
RemoveComponentTestMessage removeComponentMessage; RemoveComponentTestMessage removeComponentMessage;
removeComponentMessage.entity = entity; removeComponentMessage.entity = entity;
removeComponentMessage.componentID = componentID;
worldBuilder.SendMessage(removeComponentMessage); worldBuilder.SendMessage(removeComponentMessage);
var world = worldBuilder.Build(); var world = worldBuilder.Build();

View File

@ -18,7 +18,7 @@ namespace Tests
public class EngineTest public class EngineTest
{ {
static List<ValueTuple<Guid, MockComponent>> resultComponents; static List<MockComponent> resultComponents;
static MockComponent resultComponent; static MockComponent resultComponent;
static List<MockMessage> resultMessages = new List<MockMessage>(); static List<MockMessage> resultMessages = new List<MockMessage>();
@ -32,8 +32,8 @@ namespace Tests
} }
} }
static List<(Guid, MockComponent, Entity)> resultComponentsIncludingEntity; static List<(MockComponent, Entity)> resultComponentsIncludingEntity;
static (Guid, MockComponent, Entity) resultComponentIncludingEntity; static (MockComponent, Entity) resultComponentIncludingEntity;
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
public class ReadComponentsIncludingEntityEngine : Engine public class ReadComponentsIncludingEntityEngine : Engine
@ -49,7 +49,7 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
resultComponent = ReadComponent<MockComponent>().Item2; resultComponent = ReadComponent<MockComponent>();
} }
} }
@ -79,16 +79,15 @@ namespace Tests
mockComponentB.myInt = 1; mockComponentB.myInt = 1;
mockComponentB.myString = "howdy"; mockComponentB.myString = "howdy";
var componentAID = worldBuilder.SetComponent(entity, mockComponent); worldBuilder.SetComponent(entity, mockComponent);
var componentBID = worldBuilder.SetComponent(entityB, mockComponentB); worldBuilder.SetComponent(entityB, mockComponentB);
var world = worldBuilder.Build(); var world = worldBuilder.Build();
world.Update(0.01f); world.Update(0.01f);
var resultComponentValues = resultComponents.Select((kv) => kv.Item2); resultComponents.Should().Contain(mockComponent);
resultComponentValues.Should().Contain(mockComponent); resultComponents.Should().Contain(mockComponentB);
resultComponentValues.Should().Contain(mockComponentB);
} }
[Test] [Test]
@ -108,23 +107,23 @@ namespace Tests
mockComponentB.myInt = 1; mockComponentB.myInt = 1;
mockComponentB.myString = "howdy"; mockComponentB.myString = "howdy";
var componentAID = worldBuilder.SetComponent(entity, mockComponent); worldBuilder.SetComponent(entity, mockComponent);
var componentBID = worldBuilder.SetComponent(entityB, mockComponentB); worldBuilder.SetComponent(entityB, mockComponentB);
var world = worldBuilder.Build(); var world = worldBuilder.Build();
world.Update(0.01f); world.Update(0.01f);
var resultComponentValues = resultComponentsIncludingEntity.Select((kv) => kv.Item2); var resultComponentValues = resultComponentsIncludingEntity.Select((kv) => kv.Item1);
resultComponentValues.Should().Contain(mockComponent); resultComponentValues.Should().Contain(mockComponent);
resultComponentValues.Should().Contain(mockComponentB); resultComponentValues.Should().Contain(mockComponentB);
var resultEntities = resultComponentsIncludingEntity.Select((kv) => kv.Item3); var resultEntities = resultComponentsIncludingEntity.Select((kv) => kv.Item2);
resultEntities.Should().Contain(entity); resultEntities.Should().Contain(entity);
resultEntities.Should().Contain(entityB); resultEntities.Should().Contain(entityB);
resultComponentsIncludingEntity.Should().Contain((componentAID, mockComponent, entity)); resultComponentsIncludingEntity.Should().Contain((mockComponent, entity));
resultComponentsIncludingEntity.Should().Contain((componentBID, mockComponentB, entityB)); resultComponentsIncludingEntity.Should().Contain((mockComponentB, entityB));
} }
[Test] [Test]
@ -187,13 +186,13 @@ namespace Tests
mockComponent.myInt = 0; mockComponent.myInt = 0;
mockComponent.myString = "hello"; mockComponent.myString = "hello";
var componentID = worldBuilder.SetComponent(entity, mockComponent); worldBuilder.SetComponent(entity, mockComponent);
var world = worldBuilder.Build(); var world = worldBuilder.Build();
world.Update(0.01f); world.Update(0.01f);
(componentID, mockComponent, entity).Should().BeEquivalentTo(resultComponentIncludingEntity); (mockComponent, entity).Should().BeEquivalentTo(resultComponentIncludingEntity);
} }
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
@ -202,11 +201,11 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
(var componentID, var component) = ReadComponent<MockComponent>(); var (component, entity) = ReadComponentIncludingEntity<MockComponent>();
component.myInt = 420; component.myInt = 420;
component.myString = "blaze it"; component.myString = "blaze it";
SetComponent(GetEntityByComponentID<MockComponent>(componentID), component); SetComponent(entity, component);
} }
} }
@ -242,13 +241,13 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
(var componentID, var component) = ReadComponent<MockComponent>(); var (component, entity) = ReadComponentIncludingEntity<MockComponent>();
component.myInt = 420; component.myInt = 420;
component.myString = "blaze it"; component.myString = "blaze it";
SetComponent(componentID, component); SetComponent(entity, component);
component = ReadComponent<MockComponent>().Item2; component = ReadComponent<MockComponent>();
} }
} }
@ -437,22 +436,22 @@ namespace Tests
world.Update(0.01); world.Update(0.01);
} }
static ValueTuple<Guid, MockComponent> pairA; static (MockComponent, Entity) pairA;
static ValueTuple<Guid, MockComponent> pairB; static (MockComponent, Entity) pairB;
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
class SameValueComponentReadEngine : Engine class SameValueComponentReadEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
var components = ReadComponents<MockComponent>(); var components = ReadComponentsIncludingEntity<MockComponent>();
pairA = components.First(); pairA = components.First();
pairB = components.Last(); pairB = components.Last();
} }
} }
// Tests that components with identical values should be distinguishable by ID // Tests that components with identical values should be distinguishable by their entities
[Test] [Test]
public void SameValueComponents() public void SameValueComponents()
{ {
@ -476,18 +475,18 @@ namespace Tests
var world = worldBuilder.Build(); var world = worldBuilder.Build();
world.Update(0.01f); world.Update(0.01f);
Assert.That(pairA, Is.Not.EqualTo(pairB)); Assert.That(EngineTest.pairA, Is.Not.EqualTo(EngineTest.pairB));
Assert.That(pairA.Item2, Is.EqualTo(pairB.Item2)); Assert.That(EngineTest.pairA.Item1, Is.EqualTo(EngineTest.pairB.Item1));
} }
static IEnumerable<ValueTuple<Guid, MockComponent>> emptyComponentReadResult; static IEnumerable<(MockComponent, Entity)> emptyComponentReadResult;
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
class ReadEmptyMockComponentsEngine : Engine class ReadEmptyMockComponentsEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
emptyComponentReadResult = ReadComponents<MockComponent>(); emptyComponentReadResult = ReadComponentsIncludingEntity<MockComponent>();
} }
} }
@ -510,23 +509,21 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var componentPair in ReadComponents<DestroyerComponent>()) foreach (var (component, entity) in ReadComponentsIncludingEntity<DestroyerComponent>())
{ {
var componentID = componentPair.Item1; Destroy(entity);
var entityID = GetEntityIDByComponentID<DestroyerComponent>(componentID);
Destroy(entityID);
} }
} }
} }
static List<(Guid, MockComponent)> results; static List<(MockComponent, Entity)> results;
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
class ReaderEngine : Engine class ReaderEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
results = ReadComponents<MockComponent>().ToList(); results = ReadComponentsIncludingEntity<MockComponent>().ToList();
} }
} }
@ -547,21 +544,21 @@ namespace Tests
mockComponent.myString = "blah"; mockComponent.myString = "blah";
worldBuilder.SetComponent(entity, destroyerComponent); worldBuilder.SetComponent(entity, destroyerComponent);
var componentID = worldBuilder.SetComponent(entity, mockComponent); worldBuilder.SetComponent(entity, mockComponent);
worldBuilder.SetComponent(entityB, destroyerComponent); worldBuilder.SetComponent(entityB, destroyerComponent);
var componentBID = worldBuilder.SetComponent(entityB, mockComponent); worldBuilder.SetComponent(entityB, mockComponent);
var componentCID = worldBuilder.SetComponent(entityC, mockComponent); worldBuilder.SetComponent(entityC, mockComponent);
var world = worldBuilder.Build(); var world = worldBuilder.Build();
world.Update(0.01); world.Update(0.01);
world.Update(0.01); world.Update(0.01);
Assert.That(results, Does.Not.Contain((componentID, mockComponent))); Assert.That(results, Does.Not.Contain((mockComponent, entity)));
Assert.That(results, Does.Not.Contain((componentBID, mockComponent))); Assert.That(results, Does.Not.Contain((mockComponent, entity)));
Assert.That(results, Does.Contain((componentCID, mockComponent))); Assert.That(results, Does.Contain((mockComponent, entityC)));
} }
[Receives(typeof(DestroyComponentMessage))] [Receives(typeof(DestroyComponentMessage))]
@ -586,14 +583,14 @@ namespace Tests
var mockComponent = new MockComponent { }; var mockComponent = new MockComponent { };
var entity = worldBuilder.CreateEntity(); var entity = worldBuilder.CreateEntity();
var componentID = worldBuilder.SetComponent(entity, mockComponent); worldBuilder.SetComponent(entity, mockComponent);
worldBuilder.SendMessage(new DestroyComponentMessage { entity = entity }); worldBuilder.SendMessage(new DestroyComponentMessage { entity = entity });
var world = worldBuilder.Build(); var world = worldBuilder.Build();
world.Update(0.01); world.Update(0.01);
Assert.DoesNotThrow(() => world.Update(0.01)); Assert.DoesNotThrow(() => world.Update(0.01));
Assert.That(results, Does.Not.Contain((componentID, mockComponent))); Assert.That(results, Does.Not.Contain((mockComponent, entity)));
} }
[Reads(typeof(DestroyerComponent), typeof(MockComponent))] [Reads(typeof(DestroyerComponent), typeof(MockComponent))]
@ -601,13 +598,10 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var componentPair in ReadComponents<DestroyerComponent>()) foreach (var (componentPair, entity) in ReadComponentsIncludingEntity<DestroyerComponent>())
{ {
var componentID = componentPair.Item1; RemoveComponent<MockComponent>(entity);
var entity = GetEntityByComponentID<MockComponent>(componentID); Destroy(entity);
var (id, _) = GetComponent<MockComponent>(entity);
RemoveComponent(id);
Destroy(entity.ID);
} }
} }
} }
@ -629,37 +623,6 @@ namespace Tests
Assert.DoesNotThrow(() => world.Update(0.01)); Assert.DoesNotThrow(() => world.Update(0.01));
} }
static Entity entityFromComponentIDResult;
[Reads(typeof(MockComponent))]
class GetEntityFromComponentIDEngine : Engine
{
public override void Update(double dt)
{
var componentID = ReadComponent<MockComponent>().Item1;
entityFromComponentIDResult = GetEntityByComponentID<MockComponent>(componentID);
}
}
[Test]
public void GetEntityFromComponentID()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new GetEntityFromComponentIDEngine());
MockComponent component;
component.myInt = 2;
component.myString = "howdy";
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, component);
var world = worldBuilder.Build();
world.Update(0.01);
Assert.That(entity, Is.EqualTo(entityFromComponentIDResult));
}
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
[WritesPending(typeof(MockComponent))] [WritesPending(typeof(MockComponent))]
[Writes(typeof(MockComponent))] [Writes(typeof(MockComponent))]
@ -667,24 +630,22 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var (mockComponentID, mockComponent) in ReadComponents<MockComponent>()) foreach (var (mockComponent, entity) in ReadComponentsIncludingEntity<MockComponent>())
{ {
var entity = GetEntityByComponentID<MockComponent>(mockComponentID); RemoveComponent<MockComponent>(entity);
RemoveComponent(mockComponentID);
SetComponent(entity, new MockComponent()); SetComponent(entity, new MockComponent());
} }
} }
} }
static Entity entityResult;
[ReadsPending(typeof(MockComponent))] [ReadsPending(typeof(MockComponent))]
class GetEntityFromPendingComponentIDEngine : Engine class GetEntityFromPendingReadComponents : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var (mockComponentID, mockComponent) in ReadComponents<MockComponent>()) var (_, entity) = ReadComponentIncludingEntity<MockComponent>();
{
entityFromComponentIDResult = GetEntityByComponentID<MockComponent>(mockComponentID);
}
} }
} }
@ -693,7 +654,7 @@ namespace Tests
{ {
var worldBuilder = new WorldBuilder(); var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddAndRemoveMockComponentEngine()); worldBuilder.AddEngine(new AddAndRemoveMockComponentEngine());
worldBuilder.AddEngine(new GetEntityFromPendingComponentIDEngine()); worldBuilder.AddEngine(new GetEntityFromPendingReadComponents());
var entity = worldBuilder.CreateEntity(); var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent()); worldBuilder.SetComponent(entity, new MockComponent());
@ -703,186 +664,14 @@ namespace Tests
Assert.DoesNotThrow(() => world.Update(0.01)); Assert.DoesNotThrow(() => world.Update(0.01));
} }
[ReadsPending(typeof(MockComponent))]
class GetPendingComponentFromIDEngine : Engine
{
public override void Update(double dt)
{
foreach (var (mockComponentID, mockComponent) in ReadComponents<MockComponent>())
{
GetComponentByID<MockComponent>(mockComponentID);
}
}
}
[Test]
public void GetComponentFromID()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddAndRemoveMockComponentEngine());
worldBuilder.AddEngine(new GetPendingComponentFromIDEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent());
var world = worldBuilder.Build();
Assert.DoesNotThrow(() => world.Update(0.01));
}
static MockComponent mockComponentByIDResult;
[Reads(typeof(MockComponent))]
class GetComponentByIDEngine : Engine
{
public override void Update(double dt)
{
var componentID = ReadComponent<MockComponent>().Item1;
mockComponentByIDResult = GetComponentByID<MockComponent>(componentID);
}
}
[Test]
public void GetComponentByID()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new GetComponentByIDEngine());
MockComponent component;
component.myInt = 2;
component.myString = "howdy";
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, component);
var world = worldBuilder.Build();
world.Update(0.01f);
Assert.That(component, Is.EqualTo(mockComponentByIDResult));
}
struct OtherComponent : IComponent { }
[Reads(typeof(MockComponent), typeof(OtherComponent))]
class GetComponentByIDWithTypeMismatchEngine : Engine
{
public override void Update(double dt)
{
var componentID = ReadComponent<MockComponent>().Item1;
GetComponentByID<OtherComponent>(componentID);
}
}
[Test]
public void GetComponentByIDWithTypeMismatch()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new GetComponentByIDWithTypeMismatchEngine());
MockComponent component;
component.myInt = 2;
component.myString = "howdy";
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, component);
var world = worldBuilder.Build();
Assert.Throws<ComponentTypeMismatchException>(() => world.Update(0.01f));
}
struct EntityIDComponent : IComponent { public Guid entityID; }
static bool hasEntity;
[Reads(typeof(EntityIDComponent))]
class HasEntityTestEngine : Engine
{
public override void Update(double dt)
{
foreach (var (mockComponentID, mockComponent) in ReadComponents<EntityIDComponent>())
{
hasEntity = EntityExists(mockComponent.entityID);
if (hasEntity) { Destroy(mockComponent.entityID); }
}
}
}
[Test]
public void EntityExists()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new HasEntityTestEngine());
var entity = worldBuilder.CreateEntity();
var entityTwo = worldBuilder.CreateEntity();
EntityIDComponent entityIDComponent;
entityIDComponent.entityID = entityTwo.ID;
worldBuilder.SetComponent(entity, entityIDComponent);
var world = worldBuilder.Build();
world.Update(0.01);
Assert.IsTrue(hasEntity);
world.Update(0.01);
Assert.IsFalse(hasEntity);
}
struct MockComponentUpdateMessage : IMessage
{
public Guid componentID;
public MockComponent mockComponent;
}
[Reads(typeof(MockComponent))]
[Receives(typeof(MockComponentUpdateMessage))]
[Writes(typeof(MockComponent))]
class UpdateByComponentIDEngine : Engine
{
public override void Update(double dt)
{
foreach (var mockComponentUpdateMessage in ReadMessages<MockComponentUpdateMessage>())
{
SetComponent(mockComponentUpdateMessage.componentID, mockComponentUpdateMessage.mockComponent);
SetComponent(mockComponentUpdateMessage.componentID, mockComponentUpdateMessage.mockComponent);
}
}
}
[Test]
public void EngineUpdateByComponentID()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new UpdateByComponentIDEngine());
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 1;
mockComponent.myString = "5";
var mockComponentID = worldBuilder.SetComponent(entity, mockComponent);
MockComponentUpdateMessage mockComponentUpdateMessage;
mockComponentUpdateMessage.componentID = mockComponentID;
mockComponentUpdateMessage.mockComponent = mockComponent;
worldBuilder.SendMessage(mockComponentUpdateMessage);
var world = worldBuilder.Build();
Assert.DoesNotThrow(() => world.Update(0.01));
}
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
class DelayedMessageEngine : Engine class DelayedMessageEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var (componentID, component) in ReadComponents<MockComponent>()) foreach (var (component, entity) in ReadComponentsIncludingEntity<MockComponent>())
{ {
RemoveComponent(componentID); RemoveComponent<MockComponent>(entity);
SendMessageDelayed(new MockMessage { }, 1); SendMessageDelayed(new MockMessage { }, 1);
} }
} }
@ -936,9 +725,9 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var (componentID, component) in ReadComponents<MockComponent>()) foreach (var entity in ReadEntities<MockComponent>())
{ {
RemoveComponent(componentID); RemoveComponent<MockComponent>(entity);
} }
} }
} }
@ -965,42 +754,13 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var (componentID, component) in ReadComponents<MockComponent>()) foreach (var entity in ReadEntities<MockComponent>())
{ {
SetComponent(componentID, new MockComponent { }); SetComponent(entity, new MockComponent { });
} }
} }
} }
[Receives(typeof(DestroyComponentMessage))]
class DestroyEntityByIDEngine : Engine
{
public override void Update(double dt)
{
foreach (var message in ReadMessages<DestroyComponentMessage>())
{
Destroy(message.entity.ID);
}
}
}
[Test]
public void EngineSetComponentAndDestroyEntitySameFrame()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddComponentEngine());
worldBuilder.AddEngine(new DestroyEntityByIDEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent { });
worldBuilder.SendMessage(new DestroyComponentMessage { entity = entity });
var world = worldBuilder.Build();
world.Update(0.01);
Assert.DoesNotThrow(() => world.Update(0.01));
}
static Entity readEntity; static Entity readEntity;
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
@ -1123,7 +883,7 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var (_, _, entity) in ReadComponentsIncludingEntity<MockComponent>()) foreach (var (_, entity) in ReadComponentsIncludingEntity<MockComponent>())
{ {
RemoveComponent<MockComponent>(entity); RemoveComponent<MockComponent>(entity);
} }

View File

@ -1,8 +1,4 @@
using NUnit.Framework; using NUnit.Framework;
using System;
using System.Collections.Generic;
using Encompass; using Encompass;
namespace Tests namespace Tests
@ -13,13 +9,13 @@ namespace Tests
public class SingletonRead public class SingletonRead
{ {
static ValueTuple<Guid, AComponent> result; static (AComponent, Entity) result;
class TestRenderer : GeneralRenderer class TestRenderer : GeneralRenderer
{ {
public override void Render() public override void Render()
{ {
result = ReadComponent<AComponent>(); result = ReadComponentIncludingEntity<AComponent>();
} }
} }
@ -32,14 +28,14 @@ namespace Tests
AComponent aComponent; AComponent aComponent;
var entity = worldBuilder.CreateEntity(); var entity = worldBuilder.CreateEntity();
var componentID = worldBuilder.SetComponent(entity, aComponent); worldBuilder.SetComponent(entity, aComponent);
var world = worldBuilder.Build(); var world = worldBuilder.Build();
world.Update(0.01f); world.Update(0.01f);
world.Draw(); world.Draw();
Assert.That(result, Is.EqualTo(new ValueTuple<Guid, AComponent>(componentID, aComponent))); Assert.That(result, Is.EqualTo((aComponent, entity)));
} }
[Test] [Test]
@ -52,17 +48,17 @@ namespace Tests
AComponent aComponentTwo; AComponent aComponentTwo;
var entity = worldBuilder.CreateEntity(); var entity = worldBuilder.CreateEntity();
var componentID = worldBuilder.SetComponent(entity, aComponent); worldBuilder.SetComponent(entity, aComponent);
var entityB = worldBuilder.CreateEntity(); var entityB = worldBuilder.CreateEntity();
var componentTwoID = worldBuilder.SetComponent(entityB, aComponentTwo); worldBuilder.SetComponent(entityB, aComponentTwo);
var world = worldBuilder.Build(); var world = worldBuilder.Build();
world.Update(0.01f); world.Update(0.01f);
world.Draw(); world.Draw();
Assert.That(result, Is.EqualTo((componentID, aComponent)).Or.EqualTo((componentTwoID, aComponentTwo))); Assert.That(result, Is.EqualTo((aComponent, entity)).Or.EqualTo((aComponentTwo, entityB)));
} }
} }
} }

View File

@ -17,26 +17,26 @@ namespace Tests
class TestRenderer : OrderedRenderer<TestDrawComponent> class TestRenderer : OrderedRenderer<TestDrawComponent>
{ {
public override void Render(Guid drawComponentID, TestDrawComponent testDrawComponent) { } public override void Render(Entity entity, TestDrawComponent testDrawComponent) { }
} }
static bool called = false; static bool called = false;
class DeactivatedRenderer : TestRenderer class DeactivatedRenderer : TestRenderer
{ {
public override void Render(Guid drawComponentID, TestDrawComponent testDrawComponent) public override void Render(Entity entity, TestDrawComponent testDrawComponent)
{ {
called = true; called = true;
} }
} }
static bool calledOnDraw = false; static bool calledOnDraw = false;
static ValueTuple<Guid, TestDrawComponent> resultComponent; static (TestDrawComponent, Entity) resultComponent;
class CalledRenderer : OrderedRenderer<TestDrawComponent> class CalledRenderer : OrderedRenderer<TestDrawComponent>
{ {
public override void Render(Guid drawComponentID, TestDrawComponent testDrawComponent) public override void Render(Entity entity, TestDrawComponent testDrawComponent)
{ {
resultComponent = (drawComponentID, testDrawComponent); resultComponent = (testDrawComponent, entity);
calledOnDraw = true; calledOnDraw = true;
} }
} }
@ -54,7 +54,7 @@ namespace Tests
var entity = worldBuilder.CreateEntity(); var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, aComponent); worldBuilder.SetComponent(entity, aComponent);
worldBuilder.SetComponent(entity, cComponent); worldBuilder.SetComponent(entity, cComponent);
var testDrawComponentID = worldBuilder.SetDrawComponent(entity, testDrawComponent, 2); worldBuilder.SetDrawComponent(entity, testDrawComponent, 2);
var world = worldBuilder.Build(); var world = worldBuilder.Build();
@ -62,7 +62,7 @@ namespace Tests
world.Draw(); world.Draw();
Assert.IsTrue(calledOnDraw); Assert.IsTrue(calledOnDraw);
resultComponent.Should().BeEquivalentTo((testDrawComponentID, testDrawComponent)); resultComponent.Should().BeEquivalentTo((testDrawComponent, entity));
} }
[Reads(typeof(TestDrawComponent))] [Reads(typeof(TestDrawComponent))]
@ -70,9 +70,9 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
foreach (var (componentID, component) in ReadComponents<TestDrawComponent>()) foreach (var entity in ReadEntities<TestDrawComponent>())
{ {
Destroy(GetEntityIDByComponentID<TestDrawComponent>(componentID)); Destroy(entity);
} }
} }
} }
@ -88,7 +88,7 @@ namespace Tests
TestDrawComponent testDrawComponent; TestDrawComponent testDrawComponent;
var entity = worldBuilder.CreateEntity(); var entity = worldBuilder.CreateEntity();
var testDrawComponentID = worldBuilder.SetDrawComponent(entity, testDrawComponent, 1); worldBuilder.SetDrawComponent(entity, testDrawComponent, 1);
var world = worldBuilder.Build(); var world = worldBuilder.Build();

View File

@ -186,7 +186,7 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
resultComponent = ReadComponent<AComponent>().Item2; resultComponent = ReadComponent<AComponent>();
} }
} }
@ -257,7 +257,7 @@ namespace Tests
{ {
public override void Update(double dt) public override void Update(double dt)
{ {
resultComponent = ReadComponent<AComponent>().Item2; resultComponent = ReadComponent<AComponent>();
} }
} }

View File

@ -18,9 +18,9 @@ namespace Tests
class TestEntityRenderer : OrderedRenderer<TestDrawComponent> class TestEntityRenderer : OrderedRenderer<TestDrawComponent>
{ {
public override void Render(Guid drawComponentID, TestDrawComponent testDrawComponent) public override void Render(Entity entity, TestDrawComponent testDrawComponent)
{ {
drawOrder.Add(drawComponentID); drawOrder.Add(entity);
} }
} }
@ -44,32 +44,32 @@ namespace Tests
var entity = worldBuilder.CreateEntity(); var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, testComponent); worldBuilder.SetComponent(entity, testComponent);
var testDrawComponentOneID = worldBuilder.SetDrawComponent(entity, testDrawComponent, 3); worldBuilder.SetDrawComponent(entity, testDrawComponent, 3);
TestDrawComponent testDrawComponentTwo = default(TestDrawComponent); TestDrawComponent testDrawComponentTwo = default(TestDrawComponent);
var entityTwo = worldBuilder.CreateEntity(); var entityTwo = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entityTwo, testComponent); worldBuilder.SetComponent(entityTwo, testComponent);
var testDrawComponentTwoID = worldBuilder.SetDrawComponent(entityTwo, testDrawComponentTwo, 1); worldBuilder.SetDrawComponent(entityTwo, testDrawComponentTwo, 1);
TestDrawComponent testDrawComponentThree = default(TestDrawComponent); TestDrawComponent testDrawComponentThree = default(TestDrawComponent);
var entityThree = worldBuilder.CreateEntity(); var entityThree = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entityThree, testComponent); worldBuilder.SetComponent(entityThree, testComponent);
var testDrawComponentThreeID = worldBuilder.SetDrawComponent(entityThree, testDrawComponentThree, 5); worldBuilder.SetDrawComponent(entityThree, testDrawComponentThree, 5);
TestDrawComponent testDrawComponentFour = default(TestDrawComponent); TestDrawComponent testDrawComponentFour = default(TestDrawComponent);
var entityFour = worldBuilder.CreateEntity(); var entityFour = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entityFour, testComponent); worldBuilder.SetComponent(entityFour, testComponent);
var testDrawComponentFourID = worldBuilder.SetDrawComponent(entityFour, testDrawComponentFour, -5); worldBuilder.SetDrawComponent(entityFour, testDrawComponentFour, -5);
var world = worldBuilder.Build(); var world = worldBuilder.Build();
world.Update(0.01f); world.Update(0.01f);
world.Draw(); world.Draw();
drawOrder.Should().BeEquivalentTo(testDrawComponentFourID, testDrawComponentTwoID, testDrawComponentOneID, testDrawComponentThreeID, testGeneralRenderer); drawOrder.Should().BeEquivalentTo(entityFour, entityTwo, entity, entityThree, testGeneralRenderer);
} }
} }
} }