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
|
internal (Guid, TComponent) ReadPendingComponentByEntityAndType<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (entityToTypeToPendingComponentID.ContainsKey(entity) && entityToTypeToPendingComponentID[entity].TryGetValue(typeof(TComponent), out Guid id))
|
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
|
// check if entity has component of type
|
||||||
|
|
||||||
internal bool HasExistingOrPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
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>
|
/// <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>
|
||||||
|
|
|
@ -271,6 +271,44 @@ namespace Tests
|
||||||
Assert.AreEqual((componentID, mockComponent), gottenMockComponentIDPair);
|
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
|
struct HasComponentTestMessage : IMessage
|
||||||
{
|
{
|
||||||
public Entity entity;
|
public Entity entity;
|
||||||
|
|
Loading…
Reference in New Issue