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>
public abstract class Engine : IEquatable<Engine>
{
public Guid ID;
internal Guid ID;
internal readonly HashSet<Type> sendTypes = new HashSet<Type>();
internal readonly HashSet<Type> receiveTypes = new HashSet<Type>();
@ -123,7 +123,7 @@ namespace Encompass
/// <summary>
/// Returns true if an Entity with the specified ID exists.
/// </summary>
protected bool EntityExists(Guid entityID)
internal bool EntityExists(Guid entityID)
{
return entityManager.EntityExists(entityID);
}
@ -134,7 +134,7 @@ namespace Encompass
/// <exception cref="Encompass.Exceptions.EntityNotFoundException">
/// Thrown when an Entity with the given ID does not exist.
/// </exception>
protected Entity GetEntity(Guid entityID)
internal Entity GetEntity(Guid entityID)
{
return entityManager.GetEntity(entityID);
}
@ -142,7 +142,7 @@ namespace Encompass
/// <summary>
/// Returns the Entity ID associated with the specified Component Type and ID.
/// </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 existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
@ -158,7 +158,7 @@ namespace Encompass
/// <summary>
/// Returns the Entity associated with the specified Component Type and ID.
/// </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));
}
@ -168,7 +168,7 @@ namespace Encompass
/// </summary>
protected Entity ReadEntity<TComponent>() where TComponent : struct, IComponent
{
var (id, component) = ReadComponent<TComponent>();
var (id, component) = ReadComponentHelper<TComponent>();
return GetEntityByComponentID<TComponent>(id);
}
@ -177,7 +177,7 @@ namespace Encompass
/// </summary>
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);
}
@ -186,7 +186,7 @@ namespace Encompass
/// <summary>
/// Returns the Component struct with the specified Component Type and ID.
/// </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 existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
@ -216,10 +216,7 @@ namespace Encompass
return GetEntity(componentManager.GetEntityIDByComponentID(componentID));
}
/// <summary>
/// Returns all of the Components with the specified Component Type.
/// </summary>
protected IEnumerable<(Guid, TComponent)> ReadComponents<TComponent>() where TComponent : struct, IComponent
private IEnumerable<(Guid, TComponent)> ReadComponentsHelper<TComponent>() where TComponent : struct, IComponent
{
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
@ -242,17 +239,22 @@ namespace Encompass
}
/// <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>
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>
/// 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>
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 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>
/// Returns a component of the specified type including its Entity reference. If multiples exist, an arbitrary Component is returned.
/// </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>();
return (id, component, GetEntityByComponentID<TComponent>(id));
var (id, component) = ReadComponentHelper<TComponent>();
return (component, GetEntityByComponentID<TComponent>(id));
}
/// <summary>
@ -308,16 +318,7 @@ 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 (Guid, TComponent) GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
private (Guid, TComponent) GetComponentHelper<TComponent>(Entity entity) where TComponent : struct, IComponent
{
var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage<TComponent>));
var existingRead = receiveTypes.Contains(typeof(ComponentMessage<TComponent>));
@ -359,7 +360,12 @@ namespace Encompass
/// <exception cref="Encompass.Exceptions.IllegalReadException">
/// Thrown when the Engine does not declare that it reads the given Component Type.
/// </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 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>
/// Returns true if the Entity has a Component of the given Type.
/// </summary>
@ -463,7 +483,7 @@ namespace Encompass
/// <exception cref="Encompass.Exceptions.IllegalWriteException">
/// Thrown when the Engine does not declare that it Writes the given Component Type.
/// </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;
@ -483,16 +503,14 @@ namespace Encompass
newComponentMessage.priority = priority;
SendPendingComponentMessage(newComponentMessage);
}
return componentID;
}
/// <summary>
/// Overwrites Component struct data associated with the specified Component ID.
/// </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>
@ -503,7 +521,7 @@ namespace Encompass
/// <exception cref="Encompass.Exceptions.IllegalWriteException">
/// Thrown when the Engine does not declare that it Writes the given Component Type.
/// </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;
@ -523,8 +541,6 @@ namespace Encompass
newComponentMessage.priority = priority;
SendPendingComponentMessage(newComponentMessage);
}
return componentID;
}
/// <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.
/// Entity destruction takes place after all the Engines have been processed by World Update.
/// </summary>
protected void Destroy(Guid entityID)
internal void Destroy(Guid entityID)
{
entityManager.MarkForDestroy(entityID);
}
@ -660,17 +676,22 @@ namespace Encompass
/// <summary>
/// Removes a Component with the specified type from the given Entity.
/// 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>
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);
return true;
}
/// <summary>
/// Removes the Component with the specified ID from its Entity.
/// </summary>
protected void RemoveComponent(Guid componentID)
private void RemoveComponent(Guid componentID)
{
componentManager.MarkForRemoval(componentID);
}

View File

@ -8,19 +8,22 @@ namespace Encompass
{
private readonly ComponentManager componentManager;
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(
ComponentManager componentManager,
DrawLayerManager drawLayerManager
DrawLayerManager drawLayerManager,
EntityManager entityManager
)
{
this.componentManager = componentManager;
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);
}
@ -41,11 +44,13 @@ namespace Encompass
{
var component = componentManager.GetComponentByID(componentID);
var componentType = componentManager.GetComponentTypeByID(componentID);
var entityID = componentManager.GetEntityIDByComponentID(componentID);
var entity = entityManager.GetEntity(entityID);
if (drawComponentTypeToOrderedRenderer.ContainsKey(componentType))
{
var internalRenderAction = drawComponentTypeToOrderedRenderer[componentType];
internalRenderAction(componentID, component);
internalRenderAction(entity, component);
}
}

View File

@ -19,39 +19,39 @@ namespace Encompass
this.componentManager = componentManager;
}
protected bool EntityExists(Guid entityID)
{
return entityManager.EntityExists(entityID);
}
protected Entity GetEntity(Guid entityID)
{
return entityManager.GetEntity(entityID);
}
protected Guid GetEntityIDByComponentID(Guid componentID)
internal Guid GetEntityIDByComponentID(Guid 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();
}
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

View File

@ -7,11 +7,11 @@ namespace Encompass
/// </summary>
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();
componentMessageManager = new ComponentMessageManager();
entityManager = new EntityManager(componentManager, componentMessageManager);
renderManager = new RenderManager(componentManager, drawLayerManager);
renderManager = new RenderManager(componentManager, drawLayerManager, entityManager);
}
/// <summary>
@ -72,18 +72,18 @@ namespace Encompass
/// <summary>
/// Sets Component data for the specified Component Type on the specified Entity.
/// </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>
/// 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.
/// </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)

View File

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

View File

@ -18,7 +18,7 @@ namespace Tests
public class EngineTest
{
static List<ValueTuple<Guid, MockComponent>> resultComponents;
static List<MockComponent> resultComponents;
static MockComponent resultComponent;
static List<MockMessage> resultMessages = new List<MockMessage>();
@ -32,8 +32,8 @@ namespace Tests
}
}
static List<(Guid, MockComponent, Entity)> resultComponentsIncludingEntity;
static (Guid, MockComponent, Entity) resultComponentIncludingEntity;
static List<(MockComponent, Entity)> resultComponentsIncludingEntity;
static (MockComponent, Entity) resultComponentIncludingEntity;
[Reads(typeof(MockComponent))]
public class ReadComponentsIncludingEntityEngine : Engine
@ -49,7 +49,7 @@ namespace Tests
{
public override void Update(double dt)
{
resultComponent = ReadComponent<MockComponent>().Item2;
resultComponent = ReadComponent<MockComponent>();
}
}
@ -79,16 +79,15 @@ namespace Tests
mockComponentB.myInt = 1;
mockComponentB.myString = "howdy";
var componentAID = worldBuilder.SetComponent(entity, mockComponent);
var componentBID = worldBuilder.SetComponent(entityB, mockComponentB);
worldBuilder.SetComponent(entity, mockComponent);
worldBuilder.SetComponent(entityB, mockComponentB);
var world = worldBuilder.Build();
world.Update(0.01f);
var resultComponentValues = resultComponents.Select((kv) => kv.Item2);
resultComponentValues.Should().Contain(mockComponent);
resultComponentValues.Should().Contain(mockComponentB);
resultComponents.Should().Contain(mockComponent);
resultComponents.Should().Contain(mockComponentB);
}
[Test]
@ -108,23 +107,23 @@ namespace Tests
mockComponentB.myInt = 1;
mockComponentB.myString = "howdy";
var componentAID = worldBuilder.SetComponent(entity, mockComponent);
var componentBID = worldBuilder.SetComponent(entityB, mockComponentB);
worldBuilder.SetComponent(entity, mockComponent);
worldBuilder.SetComponent(entityB, mockComponentB);
var world = worldBuilder.Build();
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(mockComponentB);
var resultEntities = resultComponentsIncludingEntity.Select((kv) => kv.Item3);
var resultEntities = resultComponentsIncludingEntity.Select((kv) => kv.Item2);
resultEntities.Should().Contain(entity);
resultEntities.Should().Contain(entityB);
resultComponentsIncludingEntity.Should().Contain((componentAID, mockComponent, entity));
resultComponentsIncludingEntity.Should().Contain((componentBID, mockComponentB, entityB));
resultComponentsIncludingEntity.Should().Contain((mockComponent, entity));
resultComponentsIncludingEntity.Should().Contain((mockComponentB, entityB));
}
[Test]
@ -187,13 +186,13 @@ namespace Tests
mockComponent.myInt = 0;
mockComponent.myString = "hello";
var componentID = worldBuilder.SetComponent(entity, mockComponent);
worldBuilder.SetComponent(entity, mockComponent);
var world = worldBuilder.Build();
world.Update(0.01f);
(componentID, mockComponent, entity).Should().BeEquivalentTo(resultComponentIncludingEntity);
(mockComponent, entity).Should().BeEquivalentTo(resultComponentIncludingEntity);
}
[Reads(typeof(MockComponent))]
@ -202,11 +201,11 @@ namespace Tests
{
public override void Update(double dt)
{
(var componentID, var component) = ReadComponent<MockComponent>();
var (component, entity) = ReadComponentIncludingEntity<MockComponent>();
component.myInt = 420;
component.myString = "blaze it";
SetComponent(GetEntityByComponentID<MockComponent>(componentID), component);
SetComponent(entity, component);
}
}
@ -242,13 +241,13 @@ namespace Tests
{
public override void Update(double dt)
{
(var componentID, var component) = ReadComponent<MockComponent>();
var (component, entity) = ReadComponentIncludingEntity<MockComponent>();
component.myInt = 420;
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);
}
static ValueTuple<Guid, MockComponent> pairA;
static ValueTuple<Guid, MockComponent> pairB;
static (MockComponent, Entity) pairA;
static (MockComponent, Entity) pairB;
[Reads(typeof(MockComponent))]
class SameValueComponentReadEngine : Engine
{
public override void Update(double dt)
{
var components = ReadComponents<MockComponent>();
var components = ReadComponentsIncludingEntity<MockComponent>();
pairA = components.First();
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]
public void SameValueComponents()
{
@ -476,18 +475,18 @@ namespace Tests
var world = worldBuilder.Build();
world.Update(0.01f);
Assert.That(pairA, Is.Not.EqualTo(pairB));
Assert.That(pairA.Item2, Is.EqualTo(pairB.Item2));
Assert.That(EngineTest.pairA, Is.Not.EqualTo(EngineTest.pairB));
Assert.That(EngineTest.pairA.Item1, Is.EqualTo(EngineTest.pairB.Item1));
}
static IEnumerable<ValueTuple<Guid, MockComponent>> emptyComponentReadResult;
static IEnumerable<(MockComponent, Entity)> emptyComponentReadResult;
[Reads(typeof(MockComponent))]
class ReadEmptyMockComponentsEngine : Engine
{
public override void Update(double dt)
{
emptyComponentReadResult = ReadComponents<MockComponent>();
emptyComponentReadResult = ReadComponentsIncludingEntity<MockComponent>();
}
}
@ -510,23 +509,21 @@ namespace Tests
{
public override void Update(double dt)
{
foreach (var componentPair in ReadComponents<DestroyerComponent>())
foreach (var (component, entity) in ReadComponentsIncludingEntity<DestroyerComponent>())
{
var componentID = componentPair.Item1;
var entityID = GetEntityIDByComponentID<DestroyerComponent>(componentID);
Destroy(entityID);
Destroy(entity);
}
}
}
static List<(Guid, MockComponent)> results;
static List<(MockComponent, Entity)> results;
[Reads(typeof(MockComponent))]
class ReaderEngine : Engine
{
public override void Update(double dt)
{
results = ReadComponents<MockComponent>().ToList();
results = ReadComponentsIncludingEntity<MockComponent>().ToList();
}
}
@ -547,21 +544,21 @@ namespace Tests
mockComponent.myString = "blah";
worldBuilder.SetComponent(entity, destroyerComponent);
var componentID = worldBuilder.SetComponent(entity, mockComponent);
worldBuilder.SetComponent(entity, mockComponent);
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();
world.Update(0.01);
world.Update(0.01);
Assert.That(results, Does.Not.Contain((componentID, mockComponent)));
Assert.That(results, Does.Not.Contain((componentBID, mockComponent)));
Assert.That(results, Does.Contain((componentCID, mockComponent)));
Assert.That(results, Does.Not.Contain((mockComponent, entity)));
Assert.That(results, Does.Not.Contain((mockComponent, entity)));
Assert.That(results, Does.Contain((mockComponent, entityC)));
}
[Receives(typeof(DestroyComponentMessage))]
@ -586,14 +583,14 @@ namespace Tests
var mockComponent = new MockComponent { };
var entity = worldBuilder.CreateEntity();
var componentID = worldBuilder.SetComponent(entity, mockComponent);
worldBuilder.SetComponent(entity, mockComponent);
worldBuilder.SendMessage(new DestroyComponentMessage { entity = entity });
var world = worldBuilder.Build();
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))]
@ -601,13 +598,10 @@ namespace Tests
{
public override void Update(double dt)
{
foreach (var componentPair in ReadComponents<DestroyerComponent>())
foreach (var (componentPair, entity) in ReadComponentsIncludingEntity<DestroyerComponent>())
{
var componentID = componentPair.Item1;
var entity = GetEntityByComponentID<MockComponent>(componentID);
var (id, _) = GetComponent<MockComponent>(entity);
RemoveComponent(id);
Destroy(entity.ID);
RemoveComponent<MockComponent>(entity);
Destroy(entity);
}
}
}
@ -629,37 +623,6 @@ namespace Tests
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))]
[WritesPending(typeof(MockComponent))]
[Writes(typeof(MockComponent))]
@ -667,24 +630,22 @@ namespace Tests
{
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(mockComponentID);
RemoveComponent<MockComponent>(entity);
SetComponent(entity, new MockComponent());
}
}
}
static Entity entityResult;
[ReadsPending(typeof(MockComponent))]
class GetEntityFromPendingComponentIDEngine : Engine
class GetEntityFromPendingReadComponents : Engine
{
public override void Update(double dt)
{
foreach (var (mockComponentID, mockComponent) in ReadComponents<MockComponent>())
{
entityFromComponentIDResult = GetEntityByComponentID<MockComponent>(mockComponentID);
}
var (_, entity) = ReadComponentIncludingEntity<MockComponent>();
}
}
@ -693,7 +654,7 @@ namespace Tests
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AddAndRemoveMockComponentEngine());
worldBuilder.AddEngine(new GetEntityFromPendingComponentIDEngine());
worldBuilder.AddEngine(new GetEntityFromPendingReadComponents());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent());
@ -703,186 +664,14 @@ namespace Tests
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))]
class DelayedMessageEngine : Engine
{
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);
}
}
@ -936,9 +725,9 @@ namespace Tests
{
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)
{
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;
[Reads(typeof(MockComponent))]
@ -1123,7 +883,7 @@ namespace Tests
{
public override void Update(double dt)
{
foreach (var (_, _, entity) in ReadComponentsIncludingEntity<MockComponent>())
foreach (var (_, entity) in ReadComponentsIncludingEntity<MockComponent>())
{
RemoveComponent<MockComponent>(entity);
}

View File

@ -1,8 +1,4 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using Encompass;
namespace Tests
@ -13,13 +9,13 @@ namespace Tests
public class SingletonRead
{
static ValueTuple<Guid, AComponent> result;
static (AComponent, Entity) result;
class TestRenderer : GeneralRenderer
{
public override void Render()
{
result = ReadComponent<AComponent>();
result = ReadComponentIncludingEntity<AComponent>();
}
}
@ -32,14 +28,14 @@ namespace Tests
AComponent aComponent;
var entity = worldBuilder.CreateEntity();
var componentID = worldBuilder.SetComponent(entity, aComponent);
worldBuilder.SetComponent(entity, aComponent);
var world = worldBuilder.Build();
world.Update(0.01f);
world.Draw();
Assert.That(result, Is.EqualTo(new ValueTuple<Guid, AComponent>(componentID, aComponent)));
Assert.That(result, Is.EqualTo((aComponent, entity)));
}
[Test]
@ -52,17 +48,17 @@ namespace Tests
AComponent aComponentTwo;
var entity = worldBuilder.CreateEntity();
var componentID = worldBuilder.SetComponent(entity, aComponent);
worldBuilder.SetComponent(entity, aComponent);
var entityB = worldBuilder.CreateEntity();
var componentTwoID = worldBuilder.SetComponent(entityB, aComponentTwo);
worldBuilder.SetComponent(entityB, aComponentTwo);
var world = worldBuilder.Build();
world.Update(0.01f);
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>
{
public override void Render(Guid drawComponentID, TestDrawComponent testDrawComponent) { }
public override void Render(Entity entity, TestDrawComponent testDrawComponent) { }
}
static bool called = false;
class DeactivatedRenderer : TestRenderer
{
public override void Render(Guid drawComponentID, TestDrawComponent testDrawComponent)
public override void Render(Entity entity, TestDrawComponent testDrawComponent)
{
called = true;
}
}
static bool calledOnDraw = false;
static ValueTuple<Guid, TestDrawComponent> resultComponent;
static (TestDrawComponent, Entity) resultComponent;
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;
}
}
@ -54,7 +54,7 @@ namespace Tests
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, aComponent);
worldBuilder.SetComponent(entity, cComponent);
var testDrawComponentID = worldBuilder.SetDrawComponent(entity, testDrawComponent, 2);
worldBuilder.SetDrawComponent(entity, testDrawComponent, 2);
var world = worldBuilder.Build();
@ -62,7 +62,7 @@ namespace Tests
world.Draw();
Assert.IsTrue(calledOnDraw);
resultComponent.Should().BeEquivalentTo((testDrawComponentID, testDrawComponent));
resultComponent.Should().BeEquivalentTo((testDrawComponent, entity));
}
[Reads(typeof(TestDrawComponent))]
@ -70,9 +70,9 @@ namespace Tests
{
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;
var entity = worldBuilder.CreateEntity();
var testDrawComponentID = worldBuilder.SetDrawComponent(entity, testDrawComponent, 1);
worldBuilder.SetDrawComponent(entity, testDrawComponent, 1);
var world = worldBuilder.Build();

View File

@ -186,7 +186,7 @@ namespace Tests
{
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)
{
resultComponent = ReadComponent<AComponent>().Item2;
resultComponent = ReadComponent<AComponent>();
}
}

View File

@ -18,9 +18,9 @@ namespace Tests
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();
worldBuilder.SetComponent(entity, testComponent);
var testDrawComponentOneID = worldBuilder.SetDrawComponent(entity, testDrawComponent, 3);
worldBuilder.SetDrawComponent(entity, testDrawComponent, 3);
TestDrawComponent testDrawComponentTwo = default(TestDrawComponent);
var entityTwo = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entityTwo, testComponent);
var testDrawComponentTwoID = worldBuilder.SetDrawComponent(entityTwo, testDrawComponentTwo, 1);
worldBuilder.SetDrawComponent(entityTwo, testDrawComponentTwo, 1);
TestDrawComponent testDrawComponentThree = default(TestDrawComponent);
var entityThree = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entityThree, testComponent);
var testDrawComponentThreeID = worldBuilder.SetDrawComponent(entityThree, testDrawComponentThree, 5);
worldBuilder.SetDrawComponent(entityThree, testDrawComponentThree, 5);
TestDrawComponent testDrawComponentFour = default(TestDrawComponent);
var entityFour = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entityFour, testComponent);
var testDrawComponentFourID = worldBuilder.SetDrawComponent(entityFour, testDrawComponentFour, -5);
worldBuilder.SetDrawComponent(entityFour, testDrawComponentFour, -5);
var world = worldBuilder.Build();
world.Update(0.01f);
world.Draw();
drawOrder.Should().BeEquivalentTo(testDrawComponentFourID, testDrawComponentTwoID, testDrawComponentOneID, testDrawComponentThreeID, testGeneralRenderer);
drawOrder.Should().BeEquivalentTo(entityFour, entityTwo, entity, entityThree, testGeneralRenderer);
}
}
}