addcomponent optionally sends pending component message

pull/5/head
Evan Hemsley 2019-07-22 22:52:51 -07:00
parent 70e640573d
commit 41c81a0aa0
9 changed files with 53 additions and 87 deletions

View File

@ -22,6 +22,7 @@ namespace Encompass
} }
this.readTypes.Add(typeof(ComponentMessage<>).MakeGenericType(readType)); this.readTypes.Add(typeof(ComponentMessage<>).MakeGenericType(readType));
this.readTypes.Add(typeof(PendingComponentMessage<>).MakeGenericType(readType));
} }
} }
} }

View File

@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Encompass.Exceptions;
namespace Encompass
{
[AttributeUsage(AttributeTargets.Class)]
public class ReadsPending : Attribute
{
public readonly HashSet<Type> readPendingTypes = new HashSet<Type>();
public ReadsPending(params Type[] readPendingTypes)
{
foreach (var readPendingType in readPendingTypes)
{
var isComponent = readPendingType.GetInterfaces().Contains(typeof(IComponent));
if (!isComponent)
{
throw new IllegalReadTypeException("{0} must be a Component", readPendingType.Name);
}
this.readPendingTypes.Add(typeof(PendingComponentMessage<>).MakeGenericType(readPendingType));
}
}
}
}

View File

@ -45,10 +45,13 @@ namespace Encompass
entityIDToComponentIDs.Add(entityID, new HashSet<Guid>()); entityIDToComponentIDs.Add(entityID, new HashSet<Guid>());
} }
internal Guid AddComponent<TComponent>(Guid entityID, TComponent component) where TComponent : struct, IComponent internal Guid NextID()
{ {
var componentID = Guid.NewGuid(); return Guid.NewGuid();
}
internal Guid AddComponent<TComponent>(Entity entity, Guid componentID, TComponent component) where TComponent : struct, IComponent
{
IDToComponent[componentID] = component; IDToComponent[componentID] = component;
componentIDToType[componentID] = typeof(TComponent); componentIDToType[componentID] = typeof(TComponent);
@ -59,19 +62,19 @@ namespace Encompass
typeToComponentIDs[typeof(TComponent)].Add(componentID); typeToComponentIDs[typeof(TComponent)].Add(componentID);
entityIDToComponentIDs[entityID].Add(componentID); entityIDToComponentIDs[entity.ID].Add(componentID);
componentIDToEntityID[componentID] = entityID; componentIDToEntityID[componentID] = entity.ID;
activeComponents.Add(componentID); activeComponents.Add(componentID);
entitiesWithAddedComponents.Add(entityID); entitiesWithAddedComponents.Add(entity.ID);
return componentID; return componentID;
} }
internal Guid AddDrawComponent<TComponent>(Guid entityID, TComponent component, int layer = 0) where TComponent : struct, IComponent internal Guid AddDrawComponent<TComponent>(Entity entity, Guid componentID, TComponent component, int layer = 0) where TComponent : struct, IComponent
{ {
var componentID = AddComponent(entityID, component); AddComponent(entity, componentID, component);
drawLayerManager.RegisterComponentWithLayer(componentID, layer); drawLayerManager.RegisterComponentWithLayer(componentID, layer);
return componentID; return componentID;
} }

View File

@ -46,12 +46,6 @@ namespace Encompass
{ {
receiveTypes.UnionWith(readsAttribute.readTypes); receiveTypes.UnionWith(readsAttribute.readTypes);
} }
var readsPendingAttribute = GetType().GetCustomAttribute<ReadsPending>(false);
if (readsPendingAttribute != null)
{
receiveTypes.UnionWith(readsPendingAttribute.readPendingTypes);
}
} }
internal void AssignEntityManager(EntityManager entityManager) internal void AssignEntityManager(EntityManager entityManager)
@ -113,57 +107,55 @@ namespace Encompass
protected Guid AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent protected Guid AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
{ {
if (!sendTypes.Contains(typeof(PendingComponentMessage<TComponent>))) var componentID = componentManager.NextID();
componentManager.AddComponent(entity, componentID, component);
if (sendTypes.Contains(typeof(PendingComponentMessage<TComponent>)))
{ {
throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name); PendingComponentMessage<TComponent> componentMessage;
componentMessage.entity = entity;
componentMessage.componentID = componentID;
componentMessage.component = component;
SendMessage(componentMessage);
} }
var componentID = componentManager.AddComponent(entity.ID, component);
PendingComponentMessage<TComponent> componentMessage;
componentMessage.entity = entity;
componentMessage.componentID = componentID;
componentMessage.component = component;
SendMessage(componentMessage);
return componentID; return componentID;
} }
protected Guid AddDrawComponent<TComponent>(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent protected Guid AddDrawComponent<TComponent>(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent
{ {
if (!sendTypes.Contains(typeof(PendingComponentMessage<TComponent>))) var componentID = componentManager.NextID();
componentManager.AddDrawComponent(entity, componentID, component);
if (sendTypes.Contains(typeof(PendingComponentMessage<TComponent>)))
{ {
throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name); PendingComponentMessage<TComponent> newComponentMessage;
newComponentMessage.entity = entity;
newComponentMessage.componentID = componentID;
newComponentMessage.component = component;
SendMessage(newComponentMessage);
} }
var componentID = componentManager.AddDrawComponent(entity.ID, component, layer);
PendingComponentMessage<TComponent> newComponentMessage;
newComponentMessage.entity = entity;
newComponentMessage.componentID = componentID;
newComponentMessage.component = component;
SendMessage(newComponentMessage);
return componentID; return componentID;
} }
protected void ActivateComponent<TComponent>(Guid componentID) where TComponent : struct, IComponent protected void ActivateComponent<TComponent>(Guid componentID) where TComponent : struct, IComponent
{ {
if (!sendTypes.Contains(typeof(PendingComponentMessage<TComponent>)))
{
throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
}
var entity = GetEntity(componentManager.GetEntityIDByComponentID(componentID)); var entity = GetEntity(componentManager.GetEntityIDByComponentID(componentID));
var component = GetComponentByID<TComponent>(componentID); var component = GetComponentByID<TComponent>(componentID);
PendingComponentMessage<TComponent> newComponentMessage; if (sendTypes.Contains(typeof(PendingComponentMessage<TComponent>)))
newComponentMessage.entity = entity; {
newComponentMessage.componentID = componentID; PendingComponentMessage<TComponent> newComponentMessage;
newComponentMessage.component = component; newComponentMessage.entity = entity;
SendMessage(newComponentMessage); newComponentMessage.componentID = componentID;
newComponentMessage.component = component;
SendMessage(newComponentMessage);
componentManager.Activate(componentID); // TODO: actually delay this to end of frame, make sure to update after activate componentManager.Activate(componentID);
}
} }
protected void DeactivateComponent(Guid componentID) protected void DeactivateComponent(Guid componentID)
@ -189,14 +181,6 @@ namespace Encompass
{ {
return ExistingComponents<TComponent>().Union(PendingComponents<TComponent>()); return ExistingComponents<TComponent>().Union(PendingComponents<TComponent>());
} }
else if (existingRead)
{
return ExistingComponents<TComponent>();
}
else if (pendingRead)
{
return PendingComponents<TComponent>();
}
else else
{ {
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name); throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
@ -248,6 +232,11 @@ namespace Encompass
return GetComponents<TComponent>(entity).Any(); return GetComponents<TComponent>(entity).Any();
} }
internal void ActivateComponentInWorld(Guid componentID)
{
componentManager.Activate(componentID);
}
internal void UpdateComponentInWorld<TComponent>(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent internal void UpdateComponentInWorld<TComponent>(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent
{ {
componentManager.AddUpdateComponentOperation(componentID, newComponent); componentManager.AddUpdateComponentOperation(componentID, newComponent);

View File

@ -2,7 +2,7 @@ using System;
namespace Encompass namespace Encompass
{ {
public struct ComponentMessage<TComponent> : IMessage where TComponent : struct, IComponent internal struct ComponentMessage<TComponent> : IMessage where TComponent : struct, IComponent
{ {
public Entity entity; public Entity entity;
public Guid componentID; public Guid componentID;

View File

@ -2,7 +2,7 @@ using System;
namespace Encompass namespace Encompass
{ {
public struct ComponentUpdateMessage<TComponent> : IMessage where TComponent : struct, IComponent internal struct ComponentUpdateMessage<TComponent> : IMessage where TComponent : struct, IComponent
{ {
public Guid componentID; public Guid componentID;
public TComponent component; public TComponent component;

View File

@ -2,7 +2,7 @@ using System;
namespace Encompass namespace Encompass
{ {
public struct PendingComponentMessage<TComponent> : IMessage where TComponent : struct, IComponent internal struct PendingComponentMessage<TComponent> : IMessage where TComponent : struct, IComponent
{ {
public Entity entity; public Entity entity;
public Guid componentID; public Guid componentID;

View File

@ -48,12 +48,14 @@ namespace Encompass
public Guid AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent public Guid AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
{ {
return componentManager.AddComponent(entity.ID, component); var componentID = componentManager.NextID();
return componentManager.AddComponent(entity, componentID, component);
} }
public Guid AddDrawComponent<TComponent>(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent public Guid AddDrawComponent<TComponent>(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent
{ {
return componentManager.AddDrawComponent(entity.ID, component, layer); var componentID = componentManager.NextID();
return componentManager.AddDrawComponent(entity, componentID, component, layer);
} }
public void DeactivateComponent(Guid componentID) public void DeactivateComponent(Guid componentID)

View File

@ -124,7 +124,6 @@ namespace Tests
} }
[Reads(typeof(MockComponent))] [Reads(typeof(MockComponent))]
[ReadsPending(typeof(MockComponent))]
class HasMockComponentEngine : Engine class HasMockComponentEngine : Engine
{ {
private Entity entity; private Entity entity;
@ -482,7 +481,7 @@ namespace Tests
} }
[Receives(typeof(CheckHasMockComponentMessage))] [Receives(typeof(CheckHasMockComponentMessage))]
[ReadsPending(typeof(MockComponent))] [Reads(typeof(MockComponent))]
class CheckHasPendingMockComponentEngine : Engine class CheckHasPendingMockComponentEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)