read new and existing component system

pull/5/head
Evan Hemsley 2019-07-19 12:47:17 -07:00
parent 80effc06dc
commit 1845d5f766
16 changed files with 241 additions and 111 deletions

View File

@ -19,7 +19,7 @@ namespace Encompass
throw new IllegalActivateTypeException("{0} must be a Component", activateType.Name); throw new IllegalActivateTypeException("{0} must be a Component", activateType.Name);
} }
this.activateTypes.Add(typeof(ComponentMessage<>).MakeGenericType(activateType)); this.activateTypes.Add(typeof(NewComponentMessage<>).MakeGenericType(activateType));
} }
} }
} }

View File

@ -14,22 +14,14 @@ namespace Encompass
{ {
foreach (var readType in readTypes) foreach (var readType in readTypes)
{ {
var isMessage = readType.GetInterfaces().Contains(typeof(IMessage));
var isComponent = readType.GetInterfaces().Contains(typeof(IComponent)); var isComponent = readType.GetInterfaces().Contains(typeof(IComponent));
if (!isMessage && !isComponent) if (!isComponent)
{ {
throw new IllegalReadTypeException("{0} must be a Message or Component", readType.Name); throw new IllegalReadTypeException("{0} must be a Component", readType.Name);
} }
if (isComponent) this.readTypes.Add(typeof(ComponentMessage<>).MakeGenericType(readType));
{
this.readTypes.Add(typeof(ComponentMessage<>).MakeGenericType(readType));
}
else
{
this.readTypes.Add(readType);
}
} }
} }
} }

View File

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

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Encompass.Exceptions;
namespace Encompass
{
[AttributeUsage(AttributeTargets.Class)]
public class Receives : Attribute
{
public readonly HashSet<Type> receiveTypes;
public Receives(params Type[] receiveTypes)
{
foreach (var receiveType in receiveTypes)
{
var isMessage = receiveType.GetInterfaces().Contains(typeof(IMessage));
if (!isMessage)
{
throw new IllegalSendTypeException("{0} must be a Message", receiveType.Name);
}
}
this.receiveTypes = new HashSet<Type>(receiveTypes);
}
}
}

View File

@ -17,7 +17,7 @@ namespace Encompass
var isMessage = sendType.GetInterfaces().Contains(typeof(IMessage)); var isMessage = sendType.GetInterfaces().Contains(typeof(IMessage));
if (!isMessage) if (!isMessage)
{ {
throw new IllegalWriteTypeException("{0} must be a Message", sendType.Name); throw new IllegalSendTypeException("{0} must be a Message", sendType.Name);
} }
} }

View File

@ -9,8 +9,7 @@ namespace Encompass
public abstract class Engine public abstract class Engine
{ {
internal readonly HashSet<Type> sendTypes = new HashSet<Type>(); internal readonly HashSet<Type> sendTypes = new HashSet<Type>();
internal readonly HashSet<Type> readTypes = new HashSet<Type>(); internal readonly HashSet<Type> receiveTypes = new HashSet<Type>();
internal readonly HashSet<Type> activateTypes = new HashSet<Type>();
internal readonly HashSet<Type> updateTypes = new HashSet<Type>(); internal readonly HashSet<Type> updateTypes = new HashSet<Type>();
private EntityManager entityManager; private EntityManager entityManager;
@ -19,22 +18,34 @@ namespace Encompass
protected Engine() protected Engine()
{ {
var writesAttribute = GetType().GetCustomAttribute<Sends>(false); var sendsAttribute = GetType().GetCustomAttribute<Sends>(false);
if (writesAttribute != null) if (sendsAttribute != null)
{ {
sendTypes = writesAttribute.sendTypes; sendTypes = sendsAttribute.sendTypes;
}
var readsAttribute = GetType().GetCustomAttribute<Reads>(false);
if (readsAttribute != null)
{
readTypes = readsAttribute.readTypes;
} }
var activatesAttribute = GetType().GetCustomAttribute<Activates>(false); var activatesAttribute = GetType().GetCustomAttribute<Activates>(false);
if (activatesAttribute != null) if (activatesAttribute != null)
{ {
activateTypes = activatesAttribute.activateTypes; sendTypes.UnionWith(activatesAttribute.activateTypes);
}
var receivesAttribute = GetType().GetCustomAttribute<Receives>(false);
if (receivesAttribute != null)
{
receiveTypes = receivesAttribute.receiveTypes;
}
var readsAttribute = GetType().GetCustomAttribute<Reads>(false);
if (readsAttribute != null)
{
receiveTypes.UnionWith(readsAttribute.readTypes);
}
var readsNewAttribute = GetType().GetCustomAttribute<ReadsNew>(false);
if (readsNewAttribute != null)
{
receiveTypes.UnionWith(readsNewAttribute.newComponentReadTypes);
} }
var updatesAttribute = GetType().GetCustomAttribute<Updates>(false); var updatesAttribute = GetType().GetCustomAttribute<Updates>(false);
@ -107,14 +118,14 @@ 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 (!activateTypes.Contains(typeof(ComponentMessage<TComponent>))) if (!sendTypes.Contains(typeof(NewComponentMessage<TComponent>)))
{ {
throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name); throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
} }
var componentID = componentManager.AddComponent(entity.ID, component); var componentID = componentManager.AddComponent(entity.ID, component);
ComponentMessage<TComponent> componentMessage; NewComponentMessage<TComponent> componentMessage;
componentMessage.entity = entity; componentMessage.entity = entity;
componentMessage.componentID = componentID; componentMessage.componentID = componentID;
componentMessage.component = component; componentMessage.component = component;
@ -125,25 +136,25 @@ namespace Encompass
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 (!activateTypes.Contains(typeof(ComponentMessage<TComponent>))) if (!sendTypes.Contains(typeof(NewComponentMessage<TComponent>)))
{ {
throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name); throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
} }
var componentID = componentManager.AddDrawComponent(entity.ID, component, layer); var componentID = componentManager.AddDrawComponent(entity.ID, component, layer);
ComponentMessage<TComponent> componentMessage; NewComponentMessage<TComponent> newComponentMessage;
componentMessage.entity = entity; newComponentMessage.entity = entity;
componentMessage.componentID = componentID; newComponentMessage.componentID = componentID;
componentMessage.component = component; newComponentMessage.component = component;
SendMessage(componentMessage); 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 (!activateTypes.Contains(typeof(ComponentMessage<TComponent>))) if (!sendTypes.Contains(typeof(NewComponentMessage<TComponent>)))
{ {
throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name); throw new IllegalActivateException("Engine {0} tried to activate undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
} }
@ -151,13 +162,13 @@ namespace Encompass
var entity = GetEntity(componentManager.GetEntityIDByComponentID(componentID)); var entity = GetEntity(componentManager.GetEntityIDByComponentID(componentID));
var component = GetComponentByID<TComponent>(componentID); var component = GetComponentByID<TComponent>(componentID);
ComponentMessage<TComponent> componentMessage; NewComponentMessage<TComponent> newComponentMessage;
componentMessage.entity = entity; newComponentMessage.entity = entity;
componentMessage.componentID = componentID; newComponentMessage.componentID = componentID;
componentMessage.component = component; newComponentMessage.component = component;
SendMessage(componentMessage); SendMessage(newComponentMessage);
componentManager.Activate(componentID); componentManager.Activate(componentID); // TODO: actually delay this to end of frame, make sure to update after activate
} }
protected void DeactivateComponent(Guid componentID) protected void DeactivateComponent(Guid componentID)
@ -165,9 +176,9 @@ namespace Encompass
componentManager.MarkForDeactivation(componentID); componentManager.MarkForDeactivation(componentID);
} }
protected IEnumerable<ValueTuple<Guid, TComponent>> GetComponents<TComponent>(Entity entity) where TComponent : struct, IComponent private IEnumerable<ValueTuple<Guid, TComponent>> ExistingComponentsOnEntity<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
if (!readTypes.Contains(typeof(ComponentMessage<TComponent>))) if (!receiveTypes.Contains(typeof(ComponentMessage<TComponent>)))
{ {
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);
} }
@ -175,6 +186,26 @@ namespace Encompass
return ReadMessages<ComponentMessage<TComponent>>().Where((message) => message.entity == entity).Select((message) => (message.componentID, message.component)); return ReadMessages<ComponentMessage<TComponent>>().Where((message) => message.entity == entity).Select((message) => (message.componentID, message.component));
} }
private IEnumerable<ValueTuple<Guid, TComponent>> NewComponentsOnEntity<TComponent>(Entity entity) where TComponent : struct, IComponent
{
if (!receiveTypes.Contains(typeof(NewComponentMessage<TComponent>)))
{
throw new IllegalReadException("Engine {0} tried to read undeclared new Component {1}", GetType().Name, typeof(TComponent).Name);
}
return ReadMessages<NewComponentMessage<TComponent>>().Where((message) => message.entity == entity).Select((message) => (message.componentID, message.component));
}
protected IEnumerable<ValueTuple<Guid, TComponent>> GetComponentsIncludingNew<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return ExistingComponentsOnEntity<TComponent>(entity).Union(NewComponentsOnEntity<TComponent>(entity));
}
protected IEnumerable<ValueTuple<Guid, TComponent>> GetComponents<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return ExistingComponentsOnEntity<TComponent>(entity);
}
protected ValueTuple<Guid, TComponent> GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent protected ValueTuple<Guid, TComponent> GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
return GetComponents<TComponent>(entity).First(); return GetComponents<TComponent>(entity).First();
@ -182,19 +213,14 @@ namespace Encompass
protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
{ {
if (!readTypes.Contains(typeof(ComponentMessage<TComponent>))) return GetComponents<TComponent>(entity).Any();
{
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name);
}
return ReadMessages<ComponentMessage<TComponent>>().Where((message) => message.entity == entity).Any();
} }
internal void UpdateComponentInWorld<TComponent>(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent internal void UpdateComponentInWorld<TComponent>(Guid componentID, TComponent newComponent) where TComponent : struct, IComponent
{ {
if (!updateTypes.Contains(typeof(TComponent))) if (!updateTypes.Contains(typeof(TComponent)))
{ {
throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); throw new IllegalSendException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
} }
componentManager.AddUpdateComponentOperation(componentID, newComponent); componentManager.AddUpdateComponentOperation(componentID, newComponent);
@ -209,7 +235,7 @@ namespace Encompass
{ {
if (!sendTypes.Contains(typeof(TMessage))) if (!sendTypes.Contains(typeof(TMessage)))
{ {
throw new IllegalWriteException("Engine {0} tried to write undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); throw new IllegalSendException("Engine {0} tried to write undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
} }
messageManager.AddMessage(message); messageManager.AddMessage(message);
@ -217,7 +243,7 @@ namespace Encompass
protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage
{ {
if (!readTypes.Contains(typeof(TMessage))) if (!receiveTypes.Contains(typeof(TMessage)))
{ {
throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name); throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
} }
@ -230,9 +256,9 @@ namespace Encompass
return ReadMessages<TMessage>().Single(); return ReadMessages<TMessage>().Single();
} }
protected IEnumerable<(Guid, TComponent)> ReadComponents<TComponent>() where TComponent : struct, IComponent protected IEnumerable<ValueTuple<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent
{ {
if (!readTypes.Contains(typeof(ComponentMessage<TComponent>))) if (!receiveTypes.Contains(typeof(ComponentMessage<TComponent>)))
{ {
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name); throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
} }
@ -240,14 +266,14 @@ namespace Encompass
return ReadMessages<ComponentMessage<TComponent>>().Select((message) => (message.componentID, message.component)); return ReadMessages<ComponentMessage<TComponent>>().Select((message) => (message.componentID, message.component));
} }
protected (Guid, TComponent) ReadComponent<TComponent>() where TComponent : struct, IComponent protected ValueTuple<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent
{ {
return ReadComponents<TComponent>().Single(); return ReadComponents<TComponent>().Single();
} }
protected bool SomeMessage<TMessage>() where TMessage : struct, IMessage protected bool SomeMessage<TMessage>() where TMessage : struct, IMessage
{ {
if (!readTypes.Contains(typeof(TMessage))) if (!receiveTypes.Contains(typeof(TMessage)))
{ {
throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", GetType().Name, typeof(TMessage).Name); throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", GetType().Name, typeof(TMessage).Name);
} }
@ -257,7 +283,7 @@ namespace Encompass
protected bool SomeComponent<TComponent>() where TComponent : struct, IComponent protected bool SomeComponent<TComponent>() where TComponent : struct, IComponent
{ {
if (!readTypes.Contains(typeof(ComponentMessage<TComponent>))) if (!receiveTypes.Contains(typeof(ComponentMessage<TComponent>)))
{ {
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);
} }

View File

@ -6,12 +6,6 @@ namespace Encompass.Engines
{ {
public ComponentMessageEmitter() : base() public ComponentMessageEmitter() : base()
{ {
var writesAttribute = GetType().GetCustomAttribute<Sends>(false);
if (writesAttribute != null)
{
writesAttribute.sendTypes.Add(typeof(ComponentMessage<TComponent>));
}
sendTypes.Add(typeof(ComponentMessage<TComponent>)); sendTypes.Add(typeof(ComponentMessage<TComponent>));
} }

View File

@ -0,0 +1,24 @@
using System.Reflection;
namespace Encompass.Engines
{
internal class NewComponentMessageEmitter<TComponent> : Engine where TComponent : struct, IComponent
{
public NewComponentMessageEmitter() : base()
{
sendTypes.Add(typeof(NewComponentMessage<TComponent>));
}
public override void Update(double dt)
{
foreach (var (entity, componentID, component) in ReadComponentsFromWorld<TComponent>())
{
NewComponentMessage<TComponent> newComponentMessage;
newComponentMessage.entity = entity;
newComponentMessage.componentID = componentID;
newComponentMessage.component = component;
SendMessage(newComponentMessage);
}
}
}
}

View File

@ -12,7 +12,7 @@ namespace Encompass.Engines
readsAttribute.readTypes.Add(typeof(TMessage)); readsAttribute.readTypes.Add(typeof(TMessage));
} }
readTypes.Add(typeof(TMessage)); receiveTypes.Add(typeof(TMessage));
} }
public override void Update(double dt) public override void Update(double dt)

View File

@ -2,9 +2,9 @@ using System;
namespace Encompass.Exceptions namespace Encompass.Exceptions
{ {
public class IllegalWriteException : Exception public class IllegalSendException : Exception
{ {
public IllegalWriteException( public IllegalSendException(
string format, string format,
params object[] args params object[] args
) : base(string.Format(format, args)) { } ) : base(string.Format(format, args)) { }

View File

@ -2,9 +2,9 @@ using System;
namespace Encompass.Exceptions namespace Encompass.Exceptions
{ {
public class IllegalWriteTypeException : Exception public class IllegalSendTypeException : Exception
{ {
public IllegalWriteTypeException( public IllegalSendTypeException(
string format, string format,
params object[] args params object[] args
) : base(string.Format(format, args)) { } ) : base(string.Format(format, args)) { }

View File

@ -0,0 +1,11 @@
using System;
namespace Encompass
{
public struct NewComponentMessage<TComponent> : IMessage where TComponent : struct, IComponent
{
public Entity entity;
public Guid componentID;
public TComponent component;
}
}

View File

@ -23,6 +23,7 @@ namespace Encompass
private readonly HashSet<Engine> senders = new HashSet<Engine>(); private readonly HashSet<Engine> senders = new HashSet<Engine>();
private readonly HashSet<Type> registeredComponentTypes = new HashSet<Type>(); private readonly HashSet<Type> registeredComponentTypes = new HashSet<Type>();
private readonly HashSet<Type> registeredNewComponentTypes = new HashSet<Type>();
public WorldBuilder() public WorldBuilder()
{ {
@ -66,6 +67,12 @@ namespace Encompass
AddEngine((Engine)Activator.CreateInstance(typeof(ComponentMessageEmitter<>).MakeGenericType(componentType))); AddEngine((Engine)Activator.CreateInstance(typeof(ComponentMessageEmitter<>).MakeGenericType(componentType)));
} }
internal void RegisterNewComponentEmitter(Type componentType)
{
registeredNewComponentTypes.Add(componentType);
AddEngine((Engine)Activator.CreateInstance(typeof(NewComponentMessageEmitter<>).MakeGenericType(componentType)));
}
public Engine AddEngine<TEngine>(TEngine engine) where TEngine : Engine public Engine AddEngine<TEngine>(TEngine engine) where TEngine : Engine
{ {
engine.AssignEntityManager(entityManager); engine.AssignEntityManager(entityManager);
@ -75,15 +82,10 @@ namespace Encompass
engines.Add(engine); engines.Add(engine);
engineGraph.AddVertex(engine); engineGraph.AddVertex(engine);
foreach (var activateType in engine.activateTypes) var messageReceiveTypes = engine.receiveTypes;
{
engine.sendTypes.Add(activateType);
}
var messageReadTypes = engine.readTypes;
var messageSendTypes = engine.sendTypes; var messageSendTypes = engine.sendTypes;
foreach (var messageType in messageReadTypes.Intersect(messageSendTypes)) foreach (var messageType in messageReceiveTypes.Intersect(messageSendTypes))
{ {
// ComponentMessages can safely self-cycle // ComponentMessages can safely self-cycle
// this does introduce a gotcha though: if you AddComponent and then HasComponent or GetComponent you will receive a false negative // this does introduce a gotcha though: if you AddComponent and then HasComponent or GetComponent you will receive a false negative
@ -99,23 +101,43 @@ namespace Encompass
senders.Add(engine); senders.Add(engine);
} }
foreach (var readType in engine.readTypes) foreach (var receiveType in engine.receiveTypes)
{ {
if (readType.IsGenericType && readType.GetGenericTypeDefinition() == typeof(ComponentMessage<>)) if (receiveType.IsGenericType)
{ {
var componentType = readType.GetGenericArguments().Single(); var genericTypeDefinition = receiveType.GetGenericTypeDefinition();
if (!registeredComponentTypes.Contains(componentType)) if (genericTypeDefinition == typeof(ComponentMessage<>) || genericTypeDefinition == typeof(NewComponentMessage<>))
{ {
RegisterComponent(componentType); var componentType = receiveType.GetGenericArguments().Single();
if (!registeredComponentTypes.Contains(componentType))
{
RegisterComponent(componentType);
}
} }
} }
if (!typeToReaders.ContainsKey(readType)) if (!typeToReaders.ContainsKey(receiveType))
{ {
typeToReaders.Add(readType, new HashSet<Engine>()); typeToReaders.Add(receiveType, new HashSet<Engine>());
} }
typeToReaders[readType].Add(engine); typeToReaders[receiveType].Add(engine);
}
foreach (var sendType in engine.sendTypes)
{
if (sendType.IsGenericType)
{
var genericTypeDefinition = sendType.GetGenericTypeDefinition();
if (genericTypeDefinition == typeof(ComponentMessage<>) || genericTypeDefinition == typeof(NewComponentMessage<>))
{
var componentType = sendType.GetGenericArguments().Single();
if (!registeredNewComponentTypes.Contains(componentType))
{
RegisterNewComponentEmitter(componentType);
}
}
}
} }
return engine; return engine;

View File

@ -24,7 +24,8 @@ namespace Tests
static IEnumerable<(Guid, MockComponent)> gottenMockComponentIDPairs = Enumerable.Empty<(Guid, MockComponent)>(); static IEnumerable<(Guid, MockComponent)> gottenMockComponentIDPairs = Enumerable.Empty<(Guid, MockComponent)>();
static (Guid, MockComponent) gottenMockComponentIDPair; static (Guid, MockComponent) gottenMockComponentIDPair;
[Reads(typeof(EntityMessage), typeof(MockComponent))] [Receives(typeof(EntityMessage))]
[Reads(typeof(MockComponent))]
class GetMockComponentEngine : Engine class GetMockComponentEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -42,7 +43,8 @@ namespace Tests
public MockComponent mockComponent; public MockComponent mockComponent;
} }
[Reads(typeof(AddComponentTestMessage), typeof(MockComponent))] [Receives(typeof(AddComponentTestMessage))]
[Reads(typeof(MockComponent))]
class AddComponentTestEngine : Engine class AddComponentTestEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -109,7 +111,7 @@ namespace Tests
} }
[Activates(typeof(MockComponent))] [Activates(typeof(MockComponent))]
[Reads(typeof(AddMockComponentMessage))] [Receives(typeof(AddMockComponentMessage))]
class AddMockComponentEngine : Engine class AddMockComponentEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -152,7 +154,8 @@ namespace Tests
world.Update(0.01); world.Update(0.01);
} }
[Reads(typeof(EntityMessage), typeof(MockComponent))] [Receives(typeof(EntityMessage))]
[Reads(typeof(MockComponent))]
class GetMockComponentsEngine : Engine class GetMockComponentsEngine : Engine
{ {
private Entity entity; private Entity entity;
@ -264,7 +267,8 @@ namespace Tests
public Entity entity; public Entity entity;
} }
[Reads(typeof(HasComponentTestMessage), typeof(MockComponent))] [Receives(typeof(HasComponentTestMessage))]
[Reads(typeof(MockComponent))]
class HasComponentTestEngine : Engine class HasComponentTestEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -304,7 +308,8 @@ namespace Tests
public Entity entity; public Entity entity;
} }
[Reads(typeof(HasComponentWhenInactiveTestMessage), typeof(MockComponent))] [Receives(typeof(HasComponentWhenInactiveTestMessage))]
[Reads(typeof(MockComponent))]
class HasComponentWhenInactiveTestEngine : Engine class HasComponentWhenInactiveTestEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -346,7 +351,7 @@ namespace Tests
public Guid componentID; public Guid componentID;
} }
[Reads(typeof(RemoveComponentTestMessage))] [Receives(typeof(RemoveComponentTestMessage))]
class RemoveComponentTestEngine : Engine class RemoveComponentTestEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -358,7 +363,7 @@ namespace Tests
} }
} }
[Reads(typeof(RemoveComponentTestMessage))] [Receives(typeof(RemoveComponentTestMessage))]
[Sends(typeof(CheckHasMockComponentMessage))] [Sends(typeof(CheckHasMockComponentMessage))]
class DoRemoveCheckEngine : Engine class DoRemoveCheckEngine : Engine
{ {
@ -421,7 +426,7 @@ namespace Tests
} }
[Activates(typeof(MockComponent))] [Activates(typeof(MockComponent))]
[Reads(typeof(ActivateComponentMessage))] [Receives(typeof(ActivateComponentMessage))]
class ActivateComponentEngine : Engine class ActivateComponentEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -439,7 +444,7 @@ namespace Tests
public bool shouldHaveComponent; public bool shouldHaveComponent;
} }
[Reads(typeof(ActivateComponentMessage))] [Receives(typeof(ActivateComponentMessage))]
[Sends(typeof(CheckHasMockComponentMessage))] [Sends(typeof(CheckHasMockComponentMessage))]
class DoActivateCheckEngine : Engine class DoActivateCheckEngine : Engine
{ {
@ -462,7 +467,8 @@ namespace Tests
} }
} }
[Reads(typeof(CheckHasMockComponentMessage), typeof(MockComponent))] [Receives(typeof(CheckHasMockComponentMessage))]
[Reads(typeof(MockComponent))]
class CheckHasMockComponentEngine : Engine class CheckHasMockComponentEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -508,7 +514,7 @@ namespace Tests
public Guid componentID; public Guid componentID;
} }
[Reads(typeof(DeactivateComponentMessage))] [Receives(typeof(DeactivateComponentMessage))]
class DeactivateComponentEngine : Engine class DeactivateComponentEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -520,7 +526,7 @@ namespace Tests
} }
} }
[Reads(typeof(DeactivateComponentMessage))] [Receives(typeof(DeactivateComponentMessage))]
[Sends(typeof(CheckHasMockComponentMessage))] [Sends(typeof(CheckHasMockComponentMessage))]
class DoDeactivateCheckEngine : Engine class DoDeactivateCheckEngine : Engine
{ {

View File

@ -191,7 +191,7 @@ namespace Tests
var world = worldBuilder.Build(); var world = worldBuilder.Build();
var ex = Assert.Throws<IllegalWriteException>(() => world.Update(0.01f)); var ex = Assert.Throws<IllegalSendException>(() => world.Update(0.01f));
Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredUpdateComponentTestEngine tried to write undeclared Component MockComponent")); Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredUpdateComponentTestEngine tried to write undeclared Component MockComponent"));
} }
@ -212,7 +212,7 @@ namespace Tests
} }
} }
[Reads(typeof(MockMessage))] [Receives(typeof(MockMessage))]
public class MessageReadEngine : Engine public class MessageReadEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -248,7 +248,7 @@ namespace Tests
static IEnumerable<MockMessage> emptyReadMessagesResult; static IEnumerable<MockMessage> emptyReadMessagesResult;
[Reads(typeof(MockMessage))] [Receives(typeof(MockMessage))]
class ReadMessagesWhenNoneExistEngine : Engine class ReadMessagesWhenNoneExistEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -278,7 +278,7 @@ namespace Tests
var world = worldBuilder.Build(); var world = worldBuilder.Build();
var ex = Assert.Throws<IllegalWriteException>(() => world.Update(0.01f)); var ex = Assert.Throws<IllegalSendException>(() => world.Update(0.01f));
Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredMessageEmitEngine tried to write undeclared Message MockMessage")); Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredMessageEmitEngine tried to write undeclared Message MockMessage"));
} }
@ -296,7 +296,7 @@ namespace Tests
} }
} }
[Reads(typeof(MockMessage))] [Receives(typeof(MockMessage))]
class SomeMessageTestEngine : Engine class SomeMessageTestEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)
@ -666,7 +666,7 @@ namespace Tests
public MockComponent mockComponent; public MockComponent mockComponent;
} }
[Reads(typeof(MockComponentUpdateMessage))] [Receives(typeof(MockComponentUpdateMessage))]
[Updates(typeof(MockComponent))] [Updates(typeof(MockComponent))]
class RepeatUpdateEngine : Engine class RepeatUpdateEngine : Engine
{ {

View File

@ -13,7 +13,7 @@ namespace Tests
struct AMessage : IMessage { } struct AMessage : IMessage { }
struct BMessage : IMessage { } struct BMessage : IMessage { }
[Reads(typeof(AMessage))] [Receives(typeof(AMessage))]
[Sends(typeof(BMessage))] [Sends(typeof(BMessage))]
class AEngine : Engine class AEngine : Engine
{ {
@ -24,7 +24,7 @@ namespace Tests
} }
} }
[Reads(typeof(BMessage))] [Receives(typeof(BMessage))]
[Sends(typeof(AMessage))] [Sends(typeof(AMessage))]
class BEngine : Engine class BEngine : Engine
{ {
@ -53,7 +53,7 @@ namespace Tests
struct CMessage : IMessage { } struct CMessage : IMessage { }
struct DMessage : IMessage { } struct DMessage : IMessage { }
[Reads(typeof(AMessage))] [Receives(typeof(AMessage))]
[Sends(typeof(BMessage))] [Sends(typeof(BMessage))]
class AEngine : Engine class AEngine : Engine
{ {
@ -64,7 +64,7 @@ namespace Tests
} }
} }
[Reads(typeof(BMessage))] [Receives(typeof(BMessage))]
[Sends(typeof(CMessage))] [Sends(typeof(CMessage))]
class BEngine : Engine class BEngine : Engine
{ {
@ -75,7 +75,7 @@ namespace Tests
} }
} }
[Reads(typeof(CMessage))] [Receives(typeof(CMessage))]
[Sends(typeof(DMessage))] [Sends(typeof(DMessage))]
class CEngine : Engine class CEngine : Engine
{ {
@ -86,7 +86,7 @@ namespace Tests
} }
} }
[Reads(typeof(DMessage))] [Receives(typeof(DMessage))]
[Sends(typeof(AMessage))] [Sends(typeof(AMessage))]
class DEngine : Engine class DEngine : Engine
{ {
@ -141,7 +141,7 @@ namespace Tests
{ {
struct AMessage : IMessage { } struct AMessage : IMessage { }
[Reads(typeof(AMessage))] [Receives(typeof(AMessage))]
[Sends(typeof(AMessage))] [Sends(typeof(AMessage))]
class AEngine : Engine class AEngine : Engine
{ {
@ -200,7 +200,7 @@ namespace Tests
{ {
var worldBuilder = new WorldBuilder(); var worldBuilder = new WorldBuilder();
Assert.Throws<IllegalWriteTypeException>(() => worldBuilder.AddEngine(new MyEngine()), "ANonMessage must be a Message or Component"); Assert.Throws<IllegalSendTypeException>(() => worldBuilder.AddEngine(new MyEngine()), "ANonMessage must be a Message or Component");
} }
} }
@ -234,7 +234,7 @@ namespace Tests
} }
} }
[Reads(typeof(AMessage), typeof(BMessage))] [Receives(typeof(AMessage), typeof(BMessage))]
[Sends(typeof(DMessage))] [Sends(typeof(DMessage))]
class CEngine : Engine class CEngine : Engine
{ {
@ -244,7 +244,7 @@ namespace Tests
} }
} }
[Reads(typeof(DMessage))] [Receives(typeof(DMessage))]
class DEngine : Engine class DEngine : Engine
{ {
public override void Update(double dt) public override void Update(double dt)