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(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>());
}
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;
componentIDToType[componentID] = typeof(TComponent);
@ -59,19 +62,19 @@ namespace Encompass
typeToComponentIDs[typeof(TComponent)].Add(componentID);
entityIDToComponentIDs[entityID].Add(componentID);
componentIDToEntityID[componentID] = entityID;
entityIDToComponentIDs[entity.ID].Add(componentID);
componentIDToEntityID[componentID] = entity.ID;
activeComponents.Add(componentID);
entitiesWithAddedComponents.Add(entityID);
entitiesWithAddedComponents.Add(entity.ID);
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);
return componentID;
}

View File

@ -46,12 +46,6 @@ namespace Encompass
{
receiveTypes.UnionWith(readsAttribute.readTypes);
}
var readsPendingAttribute = GetType().GetCustomAttribute<ReadsPending>(false);
if (readsPendingAttribute != null)
{
receiveTypes.UnionWith(readsPendingAttribute.readPendingTypes);
}
}
internal void AssignEntityManager(EntityManager entityManager)
@ -113,57 +107,55 @@ namespace Encompass
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;
}
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;
}
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 component = GetComponentByID<TComponent>(componentID);
PendingComponentMessage<TComponent> newComponentMessage;
newComponentMessage.entity = entity;
newComponentMessage.componentID = componentID;
newComponentMessage.component = component;
SendMessage(newComponentMessage);
if (sendTypes.Contains(typeof(PendingComponentMessage<TComponent>)))
{
PendingComponentMessage<TComponent> newComponentMessage;
newComponentMessage.entity = entity;
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)
@ -189,14 +181,6 @@ namespace Encompass
{
return ExistingComponents<TComponent>().Union(PendingComponents<TComponent>());
}
else if (existingRead)
{
return ExistingComponents<TComponent>();
}
else if (pendingRead)
{
return PendingComponents<TComponent>();
}
else
{
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();
}
internal void ActivateComponentInWorld(Guid componentID)
{
componentManager.Activate(componentID);
}
internal void UpdateComponentInWorld<TComponent>(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent
{
componentManager.AddUpdateComponentOperation(componentID, newComponent);

View File

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

View File

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

View File

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

View File

@ -48,12 +48,14 @@ namespace Encompass
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
{
return componentManager.AddDrawComponent(entity.ID, component, layer);
var componentID = componentManager.NextID();
return componentManager.AddDrawComponent(entity, componentID, component, layer);
}
public void DeactivateComponent(Guid componentID)

View File

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