implement runtime type GetComponent
parent
591cd980d9
commit
3b6d473aeb
|
@ -249,6 +249,18 @@ namespace Encompass
|
|||
}
|
||||
}
|
||||
|
||||
internal (Guid, IComponent) ReadExistingComponentByEntityAndType(Entity entity, Type type)
|
||||
{
|
||||
if (entityToTypeToExistingComponentID.ContainsKey(entity) && entityToTypeToExistingComponentID[entity].TryGetValue(type, out Guid id))
|
||||
{
|
||||
return (id, componentIDToComponent[id]);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", type.Name, entity.ID);
|
||||
}
|
||||
}
|
||||
|
||||
internal (Guid, TComponent) ReadPendingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||
{
|
||||
if (entityToTypeToPendingComponentID.ContainsKey(entity) && entityToTypeToPendingComponentID[entity].TryGetValue(typeof(TComponent), out Guid id))
|
||||
|
@ -261,6 +273,18 @@ namespace Encompass
|
|||
}
|
||||
}
|
||||
|
||||
internal (Guid, IComponent) ReadPendingComponentByEntityAndType(Entity entity, Type type)
|
||||
{
|
||||
if (entityToTypeToPendingComponentID.ContainsKey(entity) && entityToTypeToPendingComponentID[entity].TryGetValue(type, out Guid id))
|
||||
{
|
||||
return (id, componentIDToComponent[id]);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", type.Name, entity.ID);
|
||||
}
|
||||
}
|
||||
|
||||
// check if entity has component of type
|
||||
|
||||
internal bool HasExistingOrPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||
|
|
|
@ -333,6 +333,52 @@ 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, IComponent) GetComponent(Entity entity, Type type)
|
||||
{
|
||||
var pending = typeof(PendingComponentMessage<>).MakeGenericType(type);
|
||||
var existing = typeof(ComponentMessage<>).MakeGenericType(type);
|
||||
|
||||
var pendingRead = receiveTypes.Contains(pending);
|
||||
var existingRead = receiveTypes.Contains(existing);
|
||||
|
||||
if (existingRead && pendingRead)
|
||||
{
|
||||
if (componentMessageManager.HasPendingComponent(entity, pending))
|
||||
{
|
||||
return componentMessageManager.ReadPendingComponentByEntityAndType(entity, pending);
|
||||
}
|
||||
else if (componentMessageManager.HasExistingComponent(entity, existing))
|
||||
{
|
||||
return componentMessageManager.ReadExistingComponentByEntityAndType(entity, existing);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", type.Name, entity.ID);
|
||||
}
|
||||
}
|
||||
else if (existingRead)
|
||||
{
|
||||
return componentMessageManager.ReadExistingComponentByEntityAndType(entity, existing);
|
||||
}
|
||||
else if (pendingRead)
|
||||
{
|
||||
return componentMessageManager.ReadPendingComponentByEntityAndType(entity, pending);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, type.Name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the Entity has a Component of the given Type.
|
||||
/// </summary>
|
||||
|
|
|
@ -271,6 +271,44 @@ namespace Tests
|
|||
Assert.AreEqual((componentID, mockComponent), gottenMockComponentIDPair);
|
||||
}
|
||||
|
||||
[Receives(typeof(EntityMessage))]
|
||||
[Reads(typeof(MockComponent))]
|
||||
class GetMockComponentByRuntimeType : Engine
|
||||
{
|
||||
public override void Update(double dt)
|
||||
{
|
||||
foreach (var entityMessage in ReadMessages<EntityMessage>())
|
||||
{
|
||||
gottenMockComponentIDPair = ((Guid, MockComponent))GetComponent(entityMessage.entity, typeof(MockComponent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetComponentByRuntimeType()
|
||||
{
|
||||
var worldBuilder = new WorldBuilder();
|
||||
worldBuilder.AddEngine(new GetMockComponentEngine());
|
||||
|
||||
var entity = worldBuilder.CreateEntity();
|
||||
|
||||
MockComponent mockComponent;
|
||||
mockComponent.myInt = 3;
|
||||
mockComponent.myString = "hello";
|
||||
|
||||
var componentID = worldBuilder.SetComponent<MockComponent>(entity, mockComponent);
|
||||
|
||||
EntityMessage entityMessage;
|
||||
entityMessage.entity = entity;
|
||||
worldBuilder.SendMessage(entityMessage);
|
||||
|
||||
var world = worldBuilder.Build();
|
||||
|
||||
world.Update(0.01);
|
||||
|
||||
Assert.AreEqual((componentID, mockComponent), gottenMockComponentIDPair);
|
||||
}
|
||||
|
||||
struct HasComponentTestMessage : IMessage
|
||||
{
|
||||
public Entity entity;
|
||||
|
|
Loading…
Reference in New Issue