runtime type HasComponent

pull/5/head
thatcosmonaut 2019-11-13 13:15:43 -08:00
parent 0920b9a8f7
commit 591cd980d9
3 changed files with 84 additions and 1 deletions

View File

@ -268,16 +268,31 @@ namespace Encompass
return entityToTypeToComponentID.ContainsKey(entity) && entityToTypeToComponentID[entity].ContainsKey(typeof(TComponent));
}
internal bool HasExistingOrPendingComponent(Entity entity, Type type)
{
return entityToTypeToComponentID.ContainsKey(entity) && entityToTypeToComponentID[entity].ContainsKey(type);
}
internal bool HasExistingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return entityToTypeToExistingComponentID.ContainsKey(entity) && entityToTypeToExistingComponentID[entity].ContainsKey(typeof(TComponent));
}
internal bool HasExistingComponent(Entity entity, Type type)
{
return entityToTypeToExistingComponentID.ContainsKey(entity) && entityToTypeToExistingComponentID[entity].ContainsKey(type);
}
internal bool HasPendingComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return entityToTypeToPendingComponentID.ContainsKey(entity) && entityToTypeToPendingComponentID[entity].ContainsKey(typeof(TComponent));
}
internal bool HasPendingComponent(Entity entity, Type type)
{
return entityToTypeToPendingComponentID.ContainsKey(entity) && entityToTypeToPendingComponentID[entity].ContainsKey(type);
}
internal IComponent GetComponentByID(Guid componentID)
{
if (componentIDToComponent.ContainsKey(componentID))

View File

@ -362,6 +362,38 @@ namespace Encompass
}
}
/// <summary>
/// Returns true if the Entity has a Component of the given Type.
/// </summary>
/// <exception cref="Encompass.Exceptions.IllegalReadException">
/// Thrown when the Engine does not declare that is Reads the given Component Type.
/// </exception>
protected bool HasComponent(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 (pendingRead && existingRead)
{
return componentMessageManager.HasExistingOrPendingComponent(entity, type);
}
else if (existingRead)
{
return componentMessageManager.HasExistingComponent(entity, type);
}
else if (pendingRead)
{
return componentMessageManager.HasPendingComponent(entity, type);
}
else
{
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, type.Name);
}
}
/// <summary>
/// Sets Component data for the specified Component Type on the specified Entity. If Component data for this Type already existed on the Entity, the component data is overwritten.
/// </summary>

View File

@ -135,7 +135,7 @@ namespace Tests
worldBuilder.AddEngine(new ReadMockComponentEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SetComponent(entity, new MockComponent {});
worldBuilder.SetComponent(entity, new MockComponent { });
var world = worldBuilder.Build();
world.Update(0.01);
@ -312,6 +312,42 @@ namespace Tests
world.Update(0.01);
}
[Receives(typeof(HasComponentTestMessage))]
[Reads(typeof(MockComponent))]
class HasComponentWithRuntimeTypeEngine : Engine
{
public override void Update(double dt)
{
foreach (var hasComponentTestEngine in ReadMessages<HasComponentTestMessage>())
{
Assert.IsTrue(HasComponent(hasComponentTestEngine.entity, typeof(MockComponent)));
}
}
}
[Test]
public void HasComponentWithRuntimeType()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new HasComponentWithRuntimeTypeEngine());
var entity = worldBuilder.CreateEntity();
MockComponent mockComponent;
mockComponent.myInt = 3;
mockComponent.myString = "hello";
worldBuilder.SetComponent(entity, mockComponent);
HasComponentTestMessage hasComponentTestMessage;
hasComponentTestMessage.entity = entity;
worldBuilder.SendMessage(hasComponentTestMessage);
var world = worldBuilder.Build();
world.Update(0.01);
}
struct RemoveComponentTestMessage : IMessage
{
public Entity entity;