Merge pull request #2 from thatcosmonaut/rework_component_write
Rework Component Read/Writepull/5/head
commit
ac744f436b
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Encompass.Exceptions;
|
||||||
|
|
||||||
|
namespace Encompass
|
||||||
|
{
|
||||||
|
[System.AttributeUsage(System.AttributeTargets.Class)]
|
||||||
|
public class Reads : System.Attribute
|
||||||
|
{
|
||||||
|
public readonly HashSet<Type> readTypes;
|
||||||
|
|
||||||
|
public Reads(params Type[] readTypes)
|
||||||
|
{
|
||||||
|
foreach (var readType in readTypes)
|
||||||
|
{
|
||||||
|
if (!readType.GetInterfaces().Contains(typeof(IMessage)) && !readType.GetInterfaces().Contains(typeof(IComponent)))
|
||||||
|
{
|
||||||
|
throw new IllegalReadTypeException("{0} must be a Message or Component", readType.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.readTypes = new HashSet<Type>(readTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Encompass.Exceptions;
|
||||||
|
|
||||||
|
namespace Encompass
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
public class Writes : Attribute
|
||||||
|
{
|
||||||
|
public readonly HashSet<Type> writeTypes;
|
||||||
|
|
||||||
|
public Writes(params Type[] writeTypes)
|
||||||
|
{
|
||||||
|
foreach (var writeType in writeTypes)
|
||||||
|
{
|
||||||
|
if (!writeType.GetInterfaces().Contains(typeof(IMessage)) && !writeType.GetInterfaces().Contains(typeof(IComponent)))
|
||||||
|
{
|
||||||
|
throw new IllegalWriteTypeException("{0} must be a Message or Component", writeType.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.writeTypes = new HashSet<Type>(writeTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,10 +18,6 @@ namespace Encompass
|
||||||
private readonly List<Guid> activeComponents = new List<Guid>();
|
private readonly List<Guid> activeComponents = new List<Guid>();
|
||||||
private readonly List<Guid> inactiveComponents = new List<Guid>();
|
private readonly List<Guid> inactiveComponents = new List<Guid>();
|
||||||
|
|
||||||
private readonly HashSet<Guid> componentsToActivate = new HashSet<Guid>();
|
|
||||||
private readonly HashSet<Guid> componentsToDeactivate = new HashSet<Guid>();
|
|
||||||
private readonly HashSet<Guid> componentsToRemove = new HashSet<Guid>();
|
|
||||||
|
|
||||||
//shared references with EntityManager
|
//shared references with EntityManager
|
||||||
private readonly HashSet<Guid> entitiesWithAddedComponents;
|
private readonly HashSet<Guid> entitiesWithAddedComponents;
|
||||||
private readonly HashSet<Guid> entitiesWithRemovedComponents;
|
private readonly HashSet<Guid> entitiesWithRemovedComponents;
|
||||||
|
@ -60,7 +56,7 @@ namespace Encompass
|
||||||
componentIDToEntityID[componentID] = entityID;
|
componentIDToEntityID[componentID] = entityID;
|
||||||
|
|
||||||
inactiveComponents.Add(componentID);
|
inactiveComponents.Add(componentID);
|
||||||
MarkForActivation(componentID);
|
Activate(componentID);
|
||||||
|
|
||||||
entitiesWithAddedComponents.Add(entityID);
|
entitiesWithAddedComponents.Add(entityID);
|
||||||
|
|
||||||
|
@ -158,67 +154,35 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
var componentIDs = entityIDToComponentIDs[entityID];
|
var componentIDs = entityIDToComponentIDs[entityID];
|
||||||
|
|
||||||
foreach (var componentID in componentIDs)
|
for (int i = componentIDs.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
MarkForRemoval(componentID);
|
Remove(componentIDs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void MarkForActivation(Guid componentID)
|
internal void Activate(Guid componentID)
|
||||||
{
|
{
|
||||||
componentsToActivate.Add(componentID);
|
if (inactiveComponents.Remove(componentID))
|
||||||
|
{
|
||||||
|
activeComponents.Add(componentID);
|
||||||
|
}
|
||||||
|
|
||||||
var entityID = GetEntityIDByComponentID(componentID);
|
var entityID = GetEntityIDByComponentID(componentID);
|
||||||
entitiesWithAddedComponents.Add(entityID);
|
entitiesWithAddedComponents.Add(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void MarkForDeactivation(Guid componentID)
|
internal void Deactivate(Guid componentID)
|
||||||
{
|
{
|
||||||
componentsToDeactivate.Add(componentID);
|
|
||||||
|
|
||||||
var entityID = GetEntityIDByComponentID(componentID);
|
|
||||||
entitiesWithRemovedComponents.Add(entityID);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void MarkForRemoval(Guid componentID)
|
|
||||||
{
|
|
||||||
componentsToRemove.Add(componentID);
|
|
||||||
|
|
||||||
var entityID = GetEntityIDByComponentID(componentID);
|
|
||||||
entitiesWithRemovedComponents.Add(entityID);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void ActivateMarkedComponents()
|
|
||||||
{
|
|
||||||
foreach (var componentID in componentsToActivate)
|
|
||||||
{
|
|
||||||
var component = IDToComponent[componentID];
|
|
||||||
if (inactiveComponents.Remove(componentID))
|
|
||||||
{
|
|
||||||
activeComponents.Add(componentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentsToActivate.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void DeactivateMarkedComponents()
|
|
||||||
{
|
|
||||||
foreach (var componentID in componentsToDeactivate)
|
|
||||||
{
|
|
||||||
var component = IDToComponent[componentID];
|
|
||||||
if (activeComponents.Remove(componentID))
|
if (activeComponents.Remove(componentID))
|
||||||
{
|
{
|
||||||
inactiveComponents.Add(componentID);
|
inactiveComponents.Add(componentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var entityID = GetEntityIDByComponentID(componentID);
|
||||||
|
entitiesWithRemovedComponents.Add(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentsToDeactivate.Clear();
|
internal void Remove(Guid componentID)
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveMarkedComponents()
|
|
||||||
{
|
|
||||||
foreach (var componentID in componentsToRemove)
|
|
||||||
{
|
{
|
||||||
var component = IDToComponent[componentID];
|
var component = IDToComponent[componentID];
|
||||||
var type = componentIDToType[componentID];
|
var type = componentIDToType[componentID];
|
||||||
|
@ -238,9 +202,8 @@ namespace Encompass
|
||||||
typeToComponentIDs[type].Remove(componentID);
|
typeToComponentIDs[type].Remove(componentID);
|
||||||
|
|
||||||
drawLayerManager.UnRegisterComponentWithLayer(componentID);
|
drawLayerManager.UnRegisterComponentWithLayer(componentID);
|
||||||
}
|
|
||||||
|
|
||||||
componentsToRemove.Clear();
|
entitiesWithRemovedComponents.Add(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterDestroyedEntity(Guid entityID)
|
public void RegisterDestroyedEntity(Guid entityID)
|
||||||
|
|
|
@ -8,9 +8,8 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
public abstract class Engine
|
public abstract class Engine
|
||||||
{
|
{
|
||||||
internal readonly List<Type> mutateComponentTypes = new List<Type>();
|
internal readonly HashSet<Type> writeTypes = new HashSet<Type>();
|
||||||
internal readonly List<Type> emitMessageTypes = new List<Type>();
|
internal readonly HashSet<Type> readTypes = new HashSet<Type>();
|
||||||
internal readonly List<Type> readMessageTypes = new List<Type>();
|
|
||||||
|
|
||||||
private EntityManager entityManager;
|
private EntityManager entityManager;
|
||||||
private ComponentManager componentManager;
|
private ComponentManager componentManager;
|
||||||
|
@ -18,22 +17,16 @@ namespace Encompass
|
||||||
|
|
||||||
protected Engine()
|
protected Engine()
|
||||||
{
|
{
|
||||||
var mutatesAttribute = GetType().GetCustomAttribute<Mutates>(false);
|
var writesAttribute = GetType().GetCustomAttribute<Writes>(false);
|
||||||
if (mutatesAttribute != null)
|
if (writesAttribute != null)
|
||||||
{
|
{
|
||||||
mutateComponentTypes = mutatesAttribute.mutateComponentTypes;
|
writeTypes = writesAttribute.writeTypes;
|
||||||
}
|
|
||||||
|
|
||||||
var emitsAttribute = GetType().GetCustomAttribute<Emits>(false);
|
|
||||||
if (emitsAttribute != null)
|
|
||||||
{
|
|
||||||
emitMessageTypes = emitsAttribute.emitMessageTypes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var readsAttribute = GetType().GetCustomAttribute<Reads>(false);
|
var readsAttribute = GetType().GetCustomAttribute<Reads>(false);
|
||||||
if (readsAttribute != null)
|
if (readsAttribute != null)
|
||||||
{
|
{
|
||||||
readMessageTypes = readsAttribute.readMessageTypes;
|
readTypes = readsAttribute.readTypes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,37 +74,110 @@ namespace Encompass
|
||||||
|
|
||||||
protected TComponent GetComponentByID<TComponent>(Guid componentID) where TComponent : struct, IComponent
|
protected TComponent GetComponentByID<TComponent>(Guid componentID) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
if (componentManager.GetComponentTypeByID(componentID) == typeof(TComponent))
|
if (!readTypes.Contains(typeof(TComponent)))
|
||||||
{
|
{
|
||||||
return (TComponent)componentManager.GetComponentByID(componentID);
|
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (componentManager.GetComponentTypeByID(componentID) != typeof(TComponent))
|
||||||
{
|
{
|
||||||
throw new ComponentTypeMismatchException("Expected Component to be of type {0} but was actually of type {1}", typeof(TComponent).Name, componentManager.GetComponentTypeByID(componentID).Name);
|
throw new ComponentTypeMismatchException("Expected Component to be of type {0} but was actually of type {1}", typeof(TComponent).Name, componentManager.GetComponentTypeByID(componentID).Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (TComponent)componentManager.GetComponentByID(componentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<ValueTuple<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent
|
protected IEnumerable<ValueTuple<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
|
if (!readTypes.Contains(typeof(TComponent)))
|
||||||
|
{
|
||||||
|
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
|
||||||
|
}
|
||||||
|
|
||||||
return componentManager.GetActiveComponentsByType<TComponent>();
|
return componentManager.GetActiveComponentsByType<TComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ValueTuple<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent
|
protected ValueTuple<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
|
if (!readTypes.Contains(typeof(TComponent)))
|
||||||
|
{
|
||||||
|
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
|
||||||
|
}
|
||||||
|
|
||||||
return componentManager.GetActiveComponentByType<TComponent>();
|
return componentManager.GetActiveComponentByType<TComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Guid AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
if (!writeTypes.Contains(typeof(TComponent)))
|
||||||
|
{
|
||||||
|
throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return componentManager.AddComponent(entity.ID, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Guid AddDrawComponent<TComponent>(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
if (!writeTypes.Contains(typeof(TComponent)))
|
||||||
|
{
|
||||||
|
throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return componentManager.AddDrawComponent(entity.ID, component, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void ActivateComponent(Guid componentID)
|
||||||
|
{
|
||||||
|
var type = componentManager.GetComponentTypeByID(componentID);
|
||||||
|
if (!writeTypes.Contains(type))
|
||||||
|
{
|
||||||
|
throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, type.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentManager.Activate(componentID);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void DeactivateComponent(Guid componentID)
|
||||||
|
{
|
||||||
|
var type = componentManager.GetComponentTypeByID(componentID);
|
||||||
|
if (!writeTypes.Contains(type))
|
||||||
|
{
|
||||||
|
throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, type.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentManager.Deactivate(componentID);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IEnumerable<ValueTuple<Guid, TComponent>> GetComponents<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
if (!readTypes.Contains(typeof(TComponent)))
|
||||||
|
{
|
||||||
|
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return componentManager.GetComponentsByEntityAndType<TComponent>(entity.ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ValueTuple<Guid, TComponent> GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
return GetComponents<TComponent>(entity).First();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool HasComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
return componentManager.EntityHasComponentOfType<TComponent>(entity.ID);
|
||||||
|
}
|
||||||
|
|
||||||
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 (mutateComponentTypes.Contains(typeof(TComponent)))
|
if (!writeTypes.Contains(typeof(TComponent)))
|
||||||
{
|
{
|
||||||
|
throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
|
||||||
|
}
|
||||||
|
|
||||||
componentManager.UpdateComponent(componentID, newComponent);
|
componentManager.UpdateComponent(componentID, newComponent);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalComponentMutationException("Engine {0} tried to mutate undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateComponent<TComponent>(Guid componentID, TComponent newComponentValue) where TComponent : struct, IComponent
|
protected void UpdateComponent<TComponent>(Guid componentID, TComponent newComponentValue) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
|
@ -120,43 +186,59 @@ namespace Encompass
|
||||||
|
|
||||||
protected void EmitMessage<TMessage>(TMessage message) where TMessage : struct, IMessage
|
protected void EmitMessage<TMessage>(TMessage message) where TMessage : struct, IMessage
|
||||||
{
|
{
|
||||||
if (emitMessageTypes.Contains(typeof(TMessage)))
|
if (!writeTypes.Contains(typeof(TMessage)))
|
||||||
{
|
{
|
||||||
|
throw new IllegalWriteException("Engine {0} tried to emit undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
|
||||||
|
}
|
||||||
|
|
||||||
messageManager.AddMessage(message);
|
messageManager.AddMessage(message);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalMessageEmitException("Engine {0} tried to emit undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage
|
protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage
|
||||||
{
|
{
|
||||||
if (readMessageTypes.Contains(typeof(TMessage)))
|
if (!readTypes.Contains(typeof(TMessage)))
|
||||||
{
|
{
|
||||||
return messageManager.GetMessagesByType<TMessage>();
|
throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new IllegalMessageReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool Some<TMessage>() where TMessage : struct, IMessage
|
return messageManager.GetMessagesByType<TMessage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool SomeMessage<TMessage>() where TMessage : struct, IMessage
|
||||||
{
|
{
|
||||||
if (readMessageTypes.Contains(typeof(TMessage)))
|
if (!readTypes.Contains(typeof(TMessage)))
|
||||||
{
|
{
|
||||||
|
throw new IllegalReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
|
||||||
|
}
|
||||||
|
|
||||||
return messageManager.GetMessagesByType<TMessage>().Any();
|
return messageManager.GetMessagesByType<TMessage>().Any();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
protected bool SomeComponent<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
throw new IllegalMessageReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
|
if (!readTypes.Contains(typeof(TComponent)))
|
||||||
|
{
|
||||||
|
throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return componentManager.GetActiveComponentsByType<TComponent>().Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Destroy(Guid entityID)
|
protected void Destroy(Guid entityID)
|
||||||
{
|
{
|
||||||
entityManager.MarkForDestroy(entityID);
|
entityManager.MarkForDestroy(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void RemoveComponent(Guid componentID)
|
||||||
|
{
|
||||||
|
var type = componentManager.GetComponentTypeByID(componentID);
|
||||||
|
if (!writeTypes.Contains(type))
|
||||||
|
{
|
||||||
|
throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, type.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentManager.Remove(componentID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Encompass.Exceptions;
|
|
||||||
|
|
||||||
namespace Encompass.Engines
|
|
||||||
{
|
|
||||||
public abstract class Detector : Engine, IEntityTracker
|
|
||||||
{
|
|
||||||
private readonly List<Type> componentTypes = new List<Type>();
|
|
||||||
private readonly EntityTracker entityTracker = new EntityTracker();
|
|
||||||
|
|
||||||
public IEnumerable<Type> ComponentTypes { get { return componentTypes; } }
|
|
||||||
|
|
||||||
protected Detector() : base()
|
|
||||||
{
|
|
||||||
var detectsAttribute = GetType().GetCustomAttribute<Detects>(false);
|
|
||||||
if (detectsAttribute != null)
|
|
||||||
{
|
|
||||||
componentTypes = detectsAttribute.componentTypes;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new DetectorWithoutComponentTypesException("Detector {0} does not have any component types declared. Use the Detects attribute to declare component types", GetType().Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(double dt)
|
|
||||||
{
|
|
||||||
foreach (var id in entityTracker.TrackedEntityIDs)
|
|
||||||
{
|
|
||||||
Detect(GetEntity(id), dt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void Detect(Entity entity, double dt);
|
|
||||||
|
|
||||||
public bool CheckAndTrackEntity(Guid entityID)
|
|
||||||
{
|
|
||||||
var entity = GetEntity(entityID);
|
|
||||||
var shouldTrack = CheckEntity(entity);
|
|
||||||
if (shouldTrack) { entityTracker.TrackEntity(entityID); }
|
|
||||||
return shouldTrack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CheckAndUntrackEntity(Guid entityID)
|
|
||||||
{
|
|
||||||
var entity = GetEntity(entityID);
|
|
||||||
var shouldUntrack = !CheckEntity(entity);
|
|
||||||
if (shouldUntrack) { entityTracker.UntrackEntity(entityID); }
|
|
||||||
return shouldUntrack;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CheckEntity(Entity entity)
|
|
||||||
{
|
|
||||||
return EntityChecker.CheckEntity(entity, componentTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,10 +9,10 @@ namespace Encompass.Engines
|
||||||
var readsAttribute = GetType().GetCustomAttribute<Reads>(false);
|
var readsAttribute = GetType().GetCustomAttribute<Reads>(false);
|
||||||
if (readsAttribute != null)
|
if (readsAttribute != null)
|
||||||
{
|
{
|
||||||
readsAttribute.readMessageTypes.Add(typeof(TMessage));
|
readsAttribute.readTypes.Add(typeof(TMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
readMessageTypes.Add(typeof(TMessage));
|
readTypes.Add(typeof(TMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
|
|
@ -1,69 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Encompass
|
namespace Encompass
|
||||||
{
|
{
|
||||||
public struct Entity
|
public struct Entity
|
||||||
{
|
{
|
||||||
public readonly Guid id;
|
public readonly Guid ID;
|
||||||
|
|
||||||
private readonly ComponentManager componentManager;
|
internal Entity(Guid id)
|
||||||
|
|
||||||
internal Entity(Guid id, ComponentManager componentManager)
|
|
||||||
{
|
{
|
||||||
this.id = id;
|
this.ID = id;
|
||||||
this.componentManager = componentManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Guid AddComponent<TComponent>(TComponent component) where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
return componentManager.AddComponent(id, component);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Guid AddDrawComponent<TComponent>(TComponent component, int layer = 0) where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
return componentManager.AddDrawComponent(id, component, layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<ValueTuple<Guid, TComponent>> GetComponents<TComponent>() where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
return componentManager.GetComponentsByEntityAndType<TComponent>(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueTuple<Guid, TComponent> GetComponent<TComponent>() where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
return GetComponents<TComponent>().First();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasComponent<TComponent>() where TComponent : struct, IComponent
|
|
||||||
{
|
|
||||||
return componentManager.EntityHasComponentOfType<TComponent>(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal bool HasComponent(Type type)
|
|
||||||
{
|
|
||||||
return componentManager.EntityHasComponentOfType(id, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ActivateComponent(Guid componentID)
|
|
||||||
{
|
|
||||||
componentManager.MarkForActivation(componentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeactivateComponent(Guid componentID)
|
|
||||||
{
|
|
||||||
componentManager.MarkForDeactivation(componentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveComponent(Guid componentID)
|
|
||||||
{
|
|
||||||
componentManager.MarkForRemoval(componentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void RemoveAllComponents()
|
|
||||||
{
|
|
||||||
componentManager.RemoveAllComponentsFromEntity(id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace Encompass
|
||||||
public Entity CreateEntity()
|
public Entity CreateEntity()
|
||||||
{
|
{
|
||||||
var id = NextID();
|
var id = NextID();
|
||||||
var entity = new Entity(id, componentManager);
|
var entity = new Entity(id);
|
||||||
IDToEntity[id] = entity;
|
IDToEntity[id] = entity;
|
||||||
componentManager.RegisterEntity(id);
|
componentManager.RegisterEntity(id);
|
||||||
return entity;
|
return entity;
|
||||||
|
@ -56,8 +56,7 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
foreach (var entityID in entitiesMarkedForDestroy)
|
foreach (var entityID in entitiesMarkedForDestroy)
|
||||||
{
|
{
|
||||||
var entity = IDToEntity[entityID];
|
componentManager.RemoveAllComponentsFromEntity(entityID);
|
||||||
entity.RemoveAllComponents();
|
|
||||||
IDToEntity.Remove(entityID);
|
IDToEntity.Remove(entityID);
|
||||||
entityToEntityTrackers.Remove(entityID);
|
entityToEntityTrackers.Remove(entityID);
|
||||||
componentManager.RegisterDestroyedEntity(entityID);
|
componentManager.RegisterDestroyedEntity(entityID);
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Encompass.Exceptions
|
|
||||||
{
|
|
||||||
public class DetectorWithoutComponentTypesException : Exception
|
|
||||||
{
|
|
||||||
public DetectorWithoutComponentTypesException(
|
|
||||||
string format,
|
|
||||||
params object[] args
|
|
||||||
) : base(string.Format(format, args)) { }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,9 +2,9 @@ using System;
|
||||||
|
|
||||||
namespace Encompass.Exceptions
|
namespace Encompass.Exceptions
|
||||||
{
|
{
|
||||||
public class EngineMutationConflictException : Exception
|
public class EngineMessageSelfCycleException : Exception
|
||||||
{
|
{
|
||||||
public EngineMutationConflictException(
|
public EngineMessageSelfCycleException(
|
||||||
string format,
|
string format,
|
||||||
params object[] args
|
params object[] args
|
||||||
) : base(string.Format(format, args)) { }
|
) : base(string.Format(format, args)) { }
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Encompass.Exceptions
|
||||||
|
{
|
||||||
|
public class EngineWriteConflictException : Exception
|
||||||
|
{
|
||||||
|
public EngineWriteConflictException(
|
||||||
|
string format,
|
||||||
|
params object[] args
|
||||||
|
) : base(string.Format(format, args)) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,9 +2,9 @@ using System;
|
||||||
|
|
||||||
namespace Encompass.Exceptions
|
namespace Encompass.Exceptions
|
||||||
{
|
{
|
||||||
public class IllegalMessageReadException : Exception
|
public class IllegalReadException : Exception
|
||||||
{
|
{
|
||||||
public IllegalMessageReadException(
|
public IllegalReadException(
|
||||||
string format,
|
string format,
|
||||||
params object[] args
|
params object[] args
|
||||||
) : base(string.Format(format, args)) { }
|
) : base(string.Format(format, args)) { }
|
|
@ -2,9 +2,9 @@ using System;
|
||||||
|
|
||||||
namespace Encompass.Exceptions
|
namespace Encompass.Exceptions
|
||||||
{
|
{
|
||||||
public class IllegalMessageEmitException : Exception
|
public class IllegalReadTypeException : Exception
|
||||||
{
|
{
|
||||||
public IllegalMessageEmitException(
|
public IllegalReadTypeException(
|
||||||
string format,
|
string format,
|
||||||
params object[] args
|
params object[] args
|
||||||
) : base(string.Format(format, args)) { }
|
) : base(string.Format(format, args)) { }
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Encompass.Exceptions
|
||||||
|
{
|
||||||
|
public class IllegalWriteException : Exception
|
||||||
|
{
|
||||||
|
public IllegalWriteException(
|
||||||
|
string format,
|
||||||
|
params object[] args
|
||||||
|
) : base(string.Format(format, args)) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Encompass.Exceptions
|
||||||
|
{
|
||||||
|
public class IllegalWriteTypeException : Exception
|
||||||
|
{
|
||||||
|
public IllegalWriteTypeException(
|
||||||
|
string format,
|
||||||
|
params object[] args
|
||||||
|
) : base(string.Format(format, args)) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ namespace Encompass
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<T> _vertices = new List<T>();
|
protected List<T> _vertices = new List<T>();
|
||||||
protected Dictionary<T, List<T>> _neighbors = new Dictionary<T, List<T>>();
|
protected Dictionary<T, HashSet<T>> _neighbors = new Dictionary<T, HashSet<T>>();
|
||||||
|
|
||||||
public IEnumerable<T> Vertices { get { return _vertices; } }
|
public IEnumerable<T> Vertices { get { return _vertices; } }
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ namespace Encompass
|
||||||
if (!VertexExists(vertex))
|
if (!VertexExists(vertex))
|
||||||
{
|
{
|
||||||
_vertices.Add(vertex);
|
_vertices.Add(vertex);
|
||||||
_neighbors.Add(vertex, new List<T>());
|
_neighbors.Add(vertex, new HashSet<T>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Encompass
|
namespace Encompass
|
||||||
{
|
{
|
||||||
public abstract class Renderer
|
public abstract class Renderer
|
||||||
{
|
{
|
||||||
private EntityManager entityManager;
|
internal EntityManager entityManager;
|
||||||
private ComponentManager componentManager;
|
internal ComponentManager componentManager;
|
||||||
|
|
||||||
internal void AssignEntityManager(EntityManager entityManager)
|
internal void AssignEntityManager(EntityManager entityManager)
|
||||||
{
|
{
|
||||||
|
@ -48,5 +48,15 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
return componentManager.GetActiveComponentByType<TComponent>();
|
return componentManager.GetActiveComponentByType<TComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected IEnumerable<ValueTuple<Guid, TComponent>> GetComponents<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
return componentManager.GetComponentsByEntityAndType<TComponent>(entity.ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ValueTuple<Guid, TComponent> GetComponent<TComponent>(Entity entity) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
return GetComponents<TComponent>(entity).First();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,8 @@ namespace Encompass
|
||||||
|
|
||||||
private bool CheckEntity(Entity entity)
|
private bool CheckEntity(Entity entity)
|
||||||
{
|
{
|
||||||
return EntityChecker.CheckEntity(entity, componentTypes)
|
return EntityChecker.CheckEntity(componentManager, entity, componentTypes)
|
||||||
&& entity.HasComponent(DrawComponentType);
|
&& componentManager.EntityHasComponentOfType(entity.ID, DrawComponentType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Encompass
|
||||||
|
{
|
||||||
|
internal static class EntityChecker
|
||||||
|
{
|
||||||
|
public static bool CheckEntity(ComponentManager componentManager, Entity entity, IEnumerable<Type> componentTypes)
|
||||||
|
{
|
||||||
|
return componentTypes.All((componentType) => componentManager.EntityHasComponentOfType(entity.ID, componentType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,10 +35,6 @@ namespace Encompass
|
||||||
messageManager.ClearMessages();
|
messageManager.ClearMessages();
|
||||||
entityManager.DestroyMarkedEntities();
|
entityManager.DestroyMarkedEntities();
|
||||||
|
|
||||||
componentManager.ActivateMarkedComponents();
|
|
||||||
componentManager.DeactivateMarkedComponents();
|
|
||||||
componentManager.RemoveMarkedComponents();
|
|
||||||
|
|
||||||
entityManager.CheckEntitiesWithAddedComponents();
|
entityManager.CheckEntitiesWithAddedComponents();
|
||||||
entityManager.CheckEntitiesWithRemovedComponents();
|
entityManager.CheckEntitiesWithRemovedComponents();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@ namespace Encompass
|
||||||
private readonly DrawLayerManager drawLayerManager;
|
private readonly DrawLayerManager drawLayerManager;
|
||||||
private readonly RenderManager renderManager;
|
private readonly RenderManager renderManager;
|
||||||
|
|
||||||
private readonly Dictionary<Type, HashSet<Engine>> messageTypeToEmitters = new Dictionary<Type, HashSet<Engine>>();
|
private readonly Dictionary<Type, HashSet<Engine>> typeToEmitters = new Dictionary<Type, HashSet<Engine>>();
|
||||||
private readonly Dictionary<Type, HashSet<Engine>> messageTypeToReaders = new Dictionary<Type, HashSet<Engine>>();
|
private readonly Dictionary<Type, HashSet<Engine>> typeToReaders = new Dictionary<Type, HashSet<Engine>>();
|
||||||
|
|
||||||
public WorldBuilder()
|
public WorldBuilder()
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,21 @@ namespace Encompass
|
||||||
messageManager.AddMessage(message);
|
messageManager.AddMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Guid AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
return componentManager.AddComponent(entity.ID, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guid AddDrawComponent<TComponent>(Entity entity, TComponent component, int layer = 0) where TComponent : struct, IComponent
|
||||||
|
{
|
||||||
|
return componentManager.AddDrawComponent(entity.ID, component, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeactivateComponent(Guid componentID)
|
||||||
|
{
|
||||||
|
componentManager.Deactivate(componentID);
|
||||||
|
}
|
||||||
|
|
||||||
public Engine AddEngine<TEngine>(TEngine engine) where TEngine : Engine
|
public Engine AddEngine<TEngine>(TEngine engine) where TEngine : Engine
|
||||||
{
|
{
|
||||||
engine.AssignEntityManager(entityManager);
|
engine.AssignEntityManager(entityManager);
|
||||||
|
@ -55,41 +70,61 @@ namespace Encompass
|
||||||
entityManager.RegisterEntityTracker(engine as IEntityTracker);
|
entityManager.RegisterEntityTracker(engine as IEntityTracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var emitMessageType in engine.emitMessageTypes)
|
foreach (var writeType in engine.writeTypes)
|
||||||
{
|
{
|
||||||
if (!messageTypeToEmitters.ContainsKey(emitMessageType))
|
if (!typeToEmitters.ContainsKey(writeType))
|
||||||
{
|
{
|
||||||
messageTypeToEmitters.Add(emitMessageType, new HashSet<Engine>());
|
typeToEmitters.Add(writeType, new HashSet<Engine>());
|
||||||
}
|
}
|
||||||
|
|
||||||
messageTypeToEmitters[emitMessageType].Add(engine);
|
typeToEmitters[writeType].Add(engine);
|
||||||
|
|
||||||
if (messageTypeToReaders.ContainsKey(emitMessageType))
|
if (typeToReaders.ContainsKey(writeType))
|
||||||
{
|
{
|
||||||
foreach (var reader in messageTypeToReaders[emitMessageType])
|
foreach (var reader in typeToReaders[writeType])
|
||||||
|
{
|
||||||
|
if (engine == reader)
|
||||||
|
{
|
||||||
|
if (writeType.GetInterfaces().Contains(typeof(IMessage)))
|
||||||
|
{
|
||||||
|
throw new EngineMessageSelfCycleException("Engine both reads and writes Message {0}", writeType.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
engineGraph.AddEdge(engine, reader);
|
engineGraph.AddEdge(engine, reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var readMessageType in engine.readMessageTypes)
|
|
||||||
{
|
|
||||||
if (!messageTypeToReaders.ContainsKey(readMessageType))
|
|
||||||
{
|
|
||||||
messageTypeToReaders.Add(readMessageType, new HashSet<Engine>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
messageTypeToReaders[readMessageType].Add(engine);
|
foreach (var readType in engine.readTypes)
|
||||||
|
|
||||||
if (messageTypeToEmitters.ContainsKey(readMessageType))
|
|
||||||
{
|
{
|
||||||
foreach (var emitter in messageTypeToEmitters[readMessageType])
|
if (!typeToReaders.ContainsKey(readType))
|
||||||
|
{
|
||||||
|
typeToReaders.Add(readType, new HashSet<Engine>());
|
||||||
|
}
|
||||||
|
|
||||||
|
typeToReaders[readType].Add(engine);
|
||||||
|
|
||||||
|
if (typeToEmitters.ContainsKey(readType))
|
||||||
|
{
|
||||||
|
foreach (var emitter in typeToEmitters[readType])
|
||||||
|
{
|
||||||
|
if (emitter == engine)
|
||||||
|
{
|
||||||
|
if (readType.GetInterfaces().Contains(typeof(IMessage)))
|
||||||
|
{
|
||||||
|
throw new EngineMessageSelfCycleException("Engine both reads and writes Message {0}", readType.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
engineGraph.AddEdge(emitter, engine);
|
engineGraph.AddEdge(emitter, engine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return engine;
|
return engine;
|
||||||
}
|
}
|
||||||
|
@ -140,41 +175,44 @@ namespace Encompass
|
||||||
|
|
||||||
foreach (var engine in engines)
|
foreach (var engine in engines)
|
||||||
{
|
{
|
||||||
var mutateAttribute = engine.GetType().GetCustomAttribute<Mutates>(false);
|
var writeAttribute = engine.GetType().GetCustomAttribute<Writes>(false);
|
||||||
if (mutateAttribute != null)
|
if (writeAttribute != null)
|
||||||
{
|
{
|
||||||
foreach (var mutateComponentType in engine.GetType().GetCustomAttribute<Mutates>(false).mutateComponentTypes)
|
foreach (var writeType in writeAttribute.writeTypes)
|
||||||
{
|
{
|
||||||
if (mutatedComponentTypes.Contains(mutateComponentType))
|
if (writeType.GetInterfaces().Contains(typeof(IComponent))) // if our write type is a component
|
||||||
{
|
{
|
||||||
duplicateMutations.Add(mutateComponentType);
|
if (mutatedComponentTypes.Contains(writeType))
|
||||||
|
{
|
||||||
|
duplicateMutations.Add(writeType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mutatedComponentTypes.Add(mutateComponentType);
|
mutatedComponentTypes.Add(writeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!componentToEngines.ContainsKey(mutateComponentType))
|
if (!componentToEngines.ContainsKey(writeType))
|
||||||
{
|
{
|
||||||
componentToEngines[mutateComponentType] = new List<Engine>();
|
componentToEngines[writeType] = new List<Engine>();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentToEngines[mutateComponentType].Add(engine);
|
componentToEngines[writeType].Add(engine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (duplicateMutations.Count > 0)
|
if (duplicateMutations.Count > 0)
|
||||||
{
|
{
|
||||||
var errorString = "Multiple Engines mutate the same Component: ";
|
var errorString = "Multiple Engines write the same Component: ";
|
||||||
foreach (var componentType in duplicateMutations)
|
foreach (var componentType in duplicateMutations)
|
||||||
{
|
{
|
||||||
errorString += "\n" +
|
errorString += "\n" +
|
||||||
componentType.Name + " mutated by: " +
|
componentType.Name + " written by: " +
|
||||||
string.Join(", ", componentToEngines[componentType].Select((engine) => engine.GetType().Name));
|
string.Join(", ", componentToEngines[componentType].Select((engine) => engine.GetType().Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new EngineMutationConflictException(errorString);
|
throw new EngineWriteConflictException(errorString);
|
||||||
}
|
}
|
||||||
|
|
||||||
var engineOrder = new List<Engine>();
|
var engineOrder = new List<Engine>();
|
||||||
|
@ -191,10 +229,6 @@ namespace Encompass
|
||||||
renderManager
|
renderManager
|
||||||
);
|
);
|
||||||
|
|
||||||
componentManager.ActivateMarkedComponents();
|
|
||||||
componentManager.DeactivateMarkedComponents();
|
|
||||||
componentManager.RemoveMarkedComponents();
|
|
||||||
|
|
||||||
entityManager.CheckEntitiesWithAddedComponents();
|
entityManager.CheckEntitiesWithAddedComponents();
|
||||||
entityManager.CheckEntitiesWithRemovedComponents();
|
entityManager.CheckEntitiesWithRemovedComponents();
|
||||||
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Encompass
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
|
||||||
public class Emits : Attribute
|
|
||||||
{
|
|
||||||
public readonly List<Type> emitMessageTypes;
|
|
||||||
|
|
||||||
public Emits(params Type[] emitMessageTypes)
|
|
||||||
{
|
|
||||||
this.emitMessageTypes = new List<Type>(emitMessageTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Encompass
|
|
||||||
{
|
|
||||||
[System.AttributeUsage(System.AttributeTargets.Class)]
|
|
||||||
public class Mutates : System.Attribute
|
|
||||||
{
|
|
||||||
public readonly List<Type> mutateComponentTypes;
|
|
||||||
|
|
||||||
public Mutates(params Type[] mutateComponentTypes)
|
|
||||||
{
|
|
||||||
this.mutateComponentTypes = new List<Type>(mutateComponentTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Encompass
|
|
||||||
{
|
|
||||||
[System.AttributeUsage(System.AttributeTargets.Class)]
|
|
||||||
public class Reads : System.Attribute
|
|
||||||
{
|
|
||||||
public readonly List<Type> readMessageTypes;
|
|
||||||
|
|
||||||
public Reads(params Type[] readMessageTypes)
|
|
||||||
{
|
|
||||||
this.readMessageTypes = new List<Type>(readMessageTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Encompass.Exceptions
|
|
||||||
{
|
|
||||||
public class IllegalComponentMutationException : Exception
|
|
||||||
{
|
|
||||||
public IllegalComponentMutationException(
|
|
||||||
string format,
|
|
||||||
params object[] args
|
|
||||||
) : base(string.Format(format, args)) { }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Encompass
|
|
||||||
{
|
|
||||||
internal static class EntityChecker
|
|
||||||
{
|
|
||||||
public static bool CheckEntity(Entity entity, IEnumerable<Type> componentTypes)
|
|
||||||
{
|
|
||||||
return componentTypes.All((componentType) => entity.HasComponent(componentType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,377 @@
|
||||||
|
using NUnit.Framework;
|
||||||
|
using FluentAssertions;
|
||||||
|
|
||||||
|
using Encompass;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
public class ComponentTests
|
||||||
|
{
|
||||||
|
struct MockComponent : IComponent
|
||||||
|
{
|
||||||
|
public string myString;
|
||||||
|
public int myInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EntityMessage : IMessage
|
||||||
|
{
|
||||||
|
public Entity entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IEnumerable<(Guid, MockComponent)> gottenMockComponentIDPairs = Enumerable.Empty<(Guid, MockComponent)>();
|
||||||
|
static (Guid, MockComponent) gottenMockComponentIDPair;
|
||||||
|
|
||||||
|
[Reads(typeof(EntityMessage), typeof(MockComponent))]
|
||||||
|
class GetMockComponentsEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
gottenMockComponentIDPairs = Enumerable.Empty<(Guid, MockComponent)>();
|
||||||
|
|
||||||
|
foreach (var entityMessage in ReadMessages<EntityMessage>())
|
||||||
|
{
|
||||||
|
gottenMockComponentIDPairs = GetComponents<MockComponent>(entityMessage.entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(EntityMessage), typeof(MockComponent))]
|
||||||
|
class GetMockComponentEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
foreach (var entityMessage in ReadMessages<EntityMessage>())
|
||||||
|
{
|
||||||
|
gottenMockComponentIDPair = GetComponent<MockComponent>(entityMessage.entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AddComponentTestMessage : IMessage
|
||||||
|
{
|
||||||
|
public Entity entity;
|
||||||
|
public MockComponent mockComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(AddComponentTestMessage), typeof(MockComponent))]
|
||||||
|
class AddComponentEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
foreach (var addComponentTestMessage in ReadMessages<AddComponentTestMessage>())
|
||||||
|
{
|
||||||
|
Assert.IsTrue(HasComponent<MockComponent>(addComponentTestMessage.entity));
|
||||||
|
Assert.That(GetComponent<MockComponent>(addComponentTestMessage.entity).Item2, Is.EqualTo(addComponentTestMessage.mockComponent));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AddComponent()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new AddComponentEngine());
|
||||||
|
worldBuilder.AddEngine(new GetMockComponentEngine());
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
|
MockComponent mockComponent;
|
||||||
|
mockComponent.myInt = 3;
|
||||||
|
mockComponent.myString = "hello";
|
||||||
|
|
||||||
|
worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
|
AddComponentTestMessage addComponentTestMessage;
|
||||||
|
addComponentTestMessage.entity = entity;
|
||||||
|
addComponentTestMessage.mockComponent = mockComponent;
|
||||||
|
worldBuilder.EmitMessage(addComponentTestMessage);
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
world.Update(0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetComponents()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new GetMockComponentsEngine());
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
|
MockComponent mockComponentA;
|
||||||
|
mockComponentA.myInt = 3;
|
||||||
|
mockComponentA.myString = "hello";
|
||||||
|
|
||||||
|
MockComponent mockComponentB;
|
||||||
|
mockComponentB.myInt = 5;
|
||||||
|
mockComponentB.myString = "wassup";
|
||||||
|
|
||||||
|
MockComponent mockComponentC;
|
||||||
|
mockComponentC.myInt = 1;
|
||||||
|
mockComponentC.myString = "howdy";
|
||||||
|
|
||||||
|
var componentAID = worldBuilder.AddComponent(entity, mockComponentA);
|
||||||
|
var componentBID = worldBuilder.AddComponent(entity, mockComponentB);
|
||||||
|
var componentCID = worldBuilder.AddComponent(entity, mockComponentC);
|
||||||
|
|
||||||
|
EntityMessage entityMessage;
|
||||||
|
entityMessage.entity = entity;
|
||||||
|
worldBuilder.EmitMessage(entityMessage);
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
world.Update(0.01);
|
||||||
|
|
||||||
|
gottenMockComponentIDPairs.Should().Contain((componentAID, mockComponentA));
|
||||||
|
gottenMockComponentIDPairs.Should().Contain((componentBID, mockComponentB));
|
||||||
|
gottenMockComponentIDPairs.Should().Contain((componentCID, mockComponentC));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetComponent()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new GetMockComponentEngine());
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
|
MockComponent mockComponent;
|
||||||
|
mockComponent.myInt = 3;
|
||||||
|
mockComponent.myString = "hello";
|
||||||
|
|
||||||
|
var componentID = worldBuilder.AddComponent<MockComponent>(entity, mockComponent);
|
||||||
|
|
||||||
|
EntityMessage entityMessage;
|
||||||
|
entityMessage.entity = entity;
|
||||||
|
worldBuilder.EmitMessage(entityMessage);
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
world.Update(0.01);
|
||||||
|
|
||||||
|
Assert.AreEqual((componentID, mockComponent), gottenMockComponentIDPair);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HasComponentTestMessage : IMessage
|
||||||
|
{
|
||||||
|
public Entity entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(HasComponentTestMessage), typeof(MockComponent))]
|
||||||
|
class HasComponentTestEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
foreach (var hasComponentTestEngine in ReadMessages<HasComponentTestMessage>())
|
||||||
|
{
|
||||||
|
Assert.IsTrue(HasComponent<MockComponent>(hasComponentTestEngine.entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void HasComponent()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new HasComponentTestEngine());
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
|
MockComponent mockComponent;
|
||||||
|
mockComponent.myInt = 3;
|
||||||
|
mockComponent.myString = "hello";
|
||||||
|
|
||||||
|
worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
|
HasComponentTestMessage hasComponentTestMessage;
|
||||||
|
hasComponentTestMessage.entity = entity;
|
||||||
|
worldBuilder.EmitMessage(hasComponentTestMessage);
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
world.Update(0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HasComponentWhenInactiveTestMessage : IMessage
|
||||||
|
{
|
||||||
|
public Entity entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(HasComponentWhenInactiveTestMessage))]
|
||||||
|
class HasComponentWhenInactiveTestEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
foreach (var hasComponentTestEngine in ReadMessages<HasComponentWhenInactiveTestMessage>())
|
||||||
|
{
|
||||||
|
Assert.IsFalse(HasComponent<MockComponent>(hasComponentTestEngine.entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void HasComponentWhenInactive()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new HasComponentWhenInactiveTestEngine());
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
|
MockComponent mockComponent;
|
||||||
|
mockComponent.myInt = 3;
|
||||||
|
mockComponent.myString = "hello";
|
||||||
|
|
||||||
|
var componentID = worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
|
HasComponentWhenInactiveTestMessage testMessage;
|
||||||
|
testMessage.entity = entity;
|
||||||
|
worldBuilder.EmitMessage(testMessage);
|
||||||
|
|
||||||
|
worldBuilder.DeactivateComponent(componentID);
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
world.Update(0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RemoveComponentTestMessage : IMessage
|
||||||
|
{
|
||||||
|
public Entity entity;
|
||||||
|
public Guid componentID;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(RemoveComponentTestMessage), typeof(MockComponent))]
|
||||||
|
[Writes(typeof(MockComponent))]
|
||||||
|
class RemoveComponentTestEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
foreach (var removeComponentMessage in ReadMessages<RemoveComponentTestMessage>())
|
||||||
|
{
|
||||||
|
RemoveComponent(removeComponentMessage.componentID);
|
||||||
|
|
||||||
|
Assert.IsFalse(HasComponent<MockComponent>(removeComponentMessage.entity));
|
||||||
|
Assert.IsEmpty(GetComponents<MockComponent>(removeComponentMessage.entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void RemoveComponent()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new RemoveComponentTestEngine());
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
|
MockComponent mockComponent;
|
||||||
|
mockComponent.myInt = 3;
|
||||||
|
mockComponent.myString = "hello";
|
||||||
|
|
||||||
|
var componentID = worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
|
RemoveComponentTestMessage removeComponentMessage;
|
||||||
|
removeComponentMessage.entity = entity;
|
||||||
|
removeComponentMessage.componentID = componentID;
|
||||||
|
worldBuilder.EmitMessage(removeComponentMessage);
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
|
||||||
|
world.Update(0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ActivateComponentMessage : IMessage
|
||||||
|
{
|
||||||
|
public Entity entity;
|
||||||
|
public Guid componentID;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(ActivateComponentMessage))]
|
||||||
|
[Writes(typeof(MockComponent))]
|
||||||
|
class ActivateComponentEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
foreach (var activateComponentMessage in ReadMessages<ActivateComponentMessage>())
|
||||||
|
{
|
||||||
|
ActivateComponent(activateComponentMessage.componentID);
|
||||||
|
Assert.IsTrue(HasComponent<MockComponent>(activateComponentMessage.entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ActivateComponent()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new ActivateComponentEngine());
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
|
MockComponent mockComponent;
|
||||||
|
mockComponent.myInt = 3;
|
||||||
|
mockComponent.myString = "hello";
|
||||||
|
|
||||||
|
var componentID = worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
|
worldBuilder.DeactivateComponent(componentID);
|
||||||
|
|
||||||
|
ActivateComponentMessage activateMessage;
|
||||||
|
activateMessage.entity = entity;
|
||||||
|
activateMessage.componentID = componentID;
|
||||||
|
worldBuilder.EmitMessage(activateMessage);
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
world.Update(0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DeactivateComponentMessage : IMessage
|
||||||
|
{
|
||||||
|
public Entity entity;
|
||||||
|
public Guid componentID;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(DeactivateComponentMessage))]
|
||||||
|
[Writes(typeof(MockComponent))]
|
||||||
|
class DeactivateComponentEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
foreach (var deactivateComponentMessage in ReadMessages<DeactivateComponentMessage>())
|
||||||
|
{
|
||||||
|
DeactivateComponent(deactivateComponentMessage.componentID);
|
||||||
|
Assert.IsFalse(HasComponent<MockComponent>(deactivateComponentMessage.entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DeactivateComponent()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new DeactivateComponentEngine());
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
|
MockComponent mockComponent;
|
||||||
|
mockComponent.myInt = 3;
|
||||||
|
mockComponent.myString = "hello";
|
||||||
|
|
||||||
|
var componentID = worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
|
DeactivateComponentMessage deactivateComponentMessage;
|
||||||
|
deactivateComponentMessage.entity = entity;
|
||||||
|
deactivateComponentMessage.componentID = componentID;
|
||||||
|
worldBuilder.EmitMessage(deactivateComponentMessage);
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
world.Update(0.01);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,123 +0,0 @@
|
||||||
using NUnit.Framework;
|
|
||||||
using FluentAssertions;
|
|
||||||
|
|
||||||
using Encompass;
|
|
||||||
using Encompass.Engines;
|
|
||||||
using Encompass.Exceptions;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Tests
|
|
||||||
{
|
|
||||||
class DetectorTest
|
|
||||||
{
|
|
||||||
class NoComponentTypesDetector : Detector
|
|
||||||
{
|
|
||||||
public override void Detect(Entity entity, double dt) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void DetectorWithNoComponentTypes()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
|
|
||||||
Action addEngine = () => worldBuilder.AddEngine(new NoComponentTypesDetector());
|
|
||||||
addEngine.Should().Throw<DetectorWithoutComponentTypesException>();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AComponent : IComponent { }
|
|
||||||
struct BComponent : IComponent { }
|
|
||||||
struct CComponent : IComponent { }
|
|
||||||
|
|
||||||
static List<Entity> trackedEntities = new List<Entity>();
|
|
||||||
|
|
||||||
[Detects(typeof(AComponent), typeof(BComponent))]
|
|
||||||
class TestDetector : Detector
|
|
||||||
{
|
|
||||||
public override void Detect(Entity entity, double dt)
|
|
||||||
{
|
|
||||||
trackedEntities.Add(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void CheckAndTrackEntities()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
var detector = worldBuilder.AddEngine(new TestDetector());
|
|
||||||
|
|
||||||
var entityToTrack = worldBuilder.CreateEntity();
|
|
||||||
entityToTrack.AddComponent(new AComponent());
|
|
||||||
entityToTrack.AddComponent(new BComponent());
|
|
||||||
|
|
||||||
var entityNotToTrack = worldBuilder.CreateEntity();
|
|
||||||
entityNotToTrack.AddComponent(new AComponent());
|
|
||||||
entityNotToTrack.AddComponent(new CComponent());
|
|
||||||
|
|
||||||
var entityWithDeactivatedComponents = worldBuilder.CreateEntity();
|
|
||||||
var aComponent = entityWithDeactivatedComponents.AddComponent(new AComponent());
|
|
||||||
entityWithDeactivatedComponents.AddComponent(new BComponent());
|
|
||||||
entityWithDeactivatedComponents.DeactivateComponent(aComponent);
|
|
||||||
|
|
||||||
var entityWithOneDeactivatedComponent = worldBuilder.CreateEntity();
|
|
||||||
var inactiveComponent = entityWithOneDeactivatedComponent.AddComponent(new AComponent());
|
|
||||||
entityWithOneDeactivatedComponent.AddComponent(new AComponent());
|
|
||||||
entityWithOneDeactivatedComponent.AddComponent(new BComponent());
|
|
||||||
entityWithOneDeactivatedComponent.DeactivateComponent(inactiveComponent);
|
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
|
||||||
world.Update(0.01);
|
|
||||||
|
|
||||||
trackedEntities.Should().Contain(entityToTrack);
|
|
||||||
trackedEntities.Should().NotContain(entityNotToTrack);
|
|
||||||
trackedEntities.Should().NotContain(entityWithDeactivatedComponents);
|
|
||||||
trackedEntities.Should().Contain(entityWithOneDeactivatedComponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void EntityUntrackedWhenComponentRemoved()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
worldBuilder.AddEngine(new TestDetector());
|
|
||||||
|
|
||||||
var entityToUntrack = worldBuilder.CreateEntity();
|
|
||||||
entityToUntrack.AddComponent(new AComponent());
|
|
||||||
var bComponent = entityToUntrack.AddComponent(new BComponent());
|
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
|
||||||
|
|
||||||
// have to update twice because we are updating from outside the world
|
|
||||||
entityToUntrack.RemoveComponent(bComponent);
|
|
||||||
world.Update(0.01);
|
|
||||||
|
|
||||||
trackedEntities.Clear();
|
|
||||||
world.Update(0.01);
|
|
||||||
|
|
||||||
trackedEntities.Should().NotContain(entityToUntrack);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void DetectCalledPerTrackedEntityOnWorldUpdat()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
worldBuilder.AddEngine(new TestDetector());
|
|
||||||
|
|
||||||
var entityOne = worldBuilder.CreateEntity();
|
|
||||||
entityOne.AddComponent(new AComponent());
|
|
||||||
entityOne.AddComponent(new BComponent());
|
|
||||||
|
|
||||||
var entityTwo = worldBuilder.CreateEntity();
|
|
||||||
entityTwo.AddComponent(new AComponent());
|
|
||||||
entityTwo.AddComponent(new BComponent());
|
|
||||||
|
|
||||||
trackedEntities.Clear();
|
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
|
||||||
|
|
||||||
world.Update(0.01);
|
|
||||||
|
|
||||||
trackedEntities.Should().Contain(entityOne);
|
|
||||||
trackedEntities.Should().Contain(entityTwo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,6 +10,12 @@ using Encompass.Exceptions;
|
||||||
|
|
||||||
namespace Tests
|
namespace Tests
|
||||||
{
|
{
|
||||||
|
struct MockComponent : IComponent
|
||||||
|
{
|
||||||
|
public int myInt;
|
||||||
|
public string myString;
|
||||||
|
}
|
||||||
|
|
||||||
public class EngineTest
|
public class EngineTest
|
||||||
{
|
{
|
||||||
static List<ValueTuple<Guid, MockComponent>> resultComponents;
|
static List<ValueTuple<Guid, MockComponent>> resultComponents;
|
||||||
|
@ -17,6 +23,7 @@ namespace Tests
|
||||||
|
|
||||||
static List<MockMessage> resultMessages;
|
static List<MockMessage> resultMessages;
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent))]
|
||||||
public class ReadComponentsTestEngine : Engine
|
public class ReadComponentsTestEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -25,6 +32,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent))]
|
||||||
public class ReadComponentTestEngine : Engine
|
public class ReadComponentTestEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -49,11 +57,11 @@ namespace Tests
|
||||||
mockComponentB.myInt = 1;
|
mockComponentB.myInt = 1;
|
||||||
mockComponentB.myString = "howdy";
|
mockComponentB.myString = "howdy";
|
||||||
|
|
||||||
var componentAID = entity.AddComponent(mockComponent);
|
var componentAID = worldBuilder.AddComponent(entity, mockComponent);
|
||||||
var componentBID = entity.AddComponent(mockComponentB);
|
var componentBID = worldBuilder.AddComponent(entity, mockComponentB);
|
||||||
var inactiveComponentAID = entity.AddComponent(mockComponent);
|
var inactiveComponentAID = worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
entity.DeactivateComponent(inactiveComponentAID);
|
worldBuilder.DeactivateComponent(inactiveComponentAID);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
@ -77,7 +85,7 @@ namespace Tests
|
||||||
mockComponent.myInt = 0;
|
mockComponent.myInt = 0;
|
||||||
mockComponent.myString = "hello";
|
mockComponent.myString = "hello";
|
||||||
|
|
||||||
entity.AddComponent(mockComponent);
|
worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
@ -102,15 +110,16 @@ namespace Tests
|
||||||
mockComponentB.myInt = 1;
|
mockComponentB.myInt = 1;
|
||||||
mockComponentB.myString = "howdy";
|
mockComponentB.myString = "howdy";
|
||||||
|
|
||||||
entity.AddComponent(mockComponent);
|
worldBuilder.AddComponent(entity, mockComponent);
|
||||||
entity.AddComponent(mockComponentB);
|
worldBuilder.AddComponent(entity, mockComponentB);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
Assert.Throws<InvalidOperationException>(() => world.Update(0.01f));
|
Assert.Throws<InvalidOperationException>(() => world.Update(0.01f));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Mutates(typeof(MockComponent))]
|
[Reads(typeof(MockComponent))]
|
||||||
|
[Writes(typeof(MockComponent))]
|
||||||
public class UpdateComponentTestEngine : Engine
|
public class UpdateComponentTestEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -137,7 +146,7 @@ namespace Tests
|
||||||
mockComponent.myInt = 0;
|
mockComponent.myInt = 0;
|
||||||
mockComponent.myString = "hello";
|
mockComponent.myString = "hello";
|
||||||
|
|
||||||
entity.AddComponent(mockComponent);
|
worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
@ -147,6 +156,7 @@ namespace Tests
|
||||||
Assert.AreEqual("blaze it", resultComponent.myString);
|
Assert.AreEqual("blaze it", resultComponent.myString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent))]
|
||||||
public class UndeclaredUpdateComponentTestEngine : Engine
|
public class UndeclaredUpdateComponentTestEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -173,12 +183,12 @@ namespace Tests
|
||||||
mockComponent.myInt = 0;
|
mockComponent.myInt = 0;
|
||||||
mockComponent.myString = "hello";
|
mockComponent.myString = "hello";
|
||||||
|
|
||||||
entity.AddComponent(mockComponent);
|
worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
var ex = Assert.Throws<IllegalComponentMutationException>(() => world.Update(0.01f));
|
var ex = Assert.Throws<IllegalWriteException>(() => world.Update(0.01f));
|
||||||
Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredUpdateComponentTestEngine tried to mutate undeclared Component MockComponent"));
|
Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredUpdateComponentTestEngine tried to write undeclared Component MockComponent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MockMessage : IMessage
|
struct MockMessage : IMessage
|
||||||
|
@ -186,7 +196,7 @@ namespace Tests
|
||||||
public string myString;
|
public string myString;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Emits(typeof(MockMessage))]
|
[Writes(typeof(MockMessage))]
|
||||||
public class MessageEmitEngine : Engine
|
public class MessageEmitEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -263,13 +273,13 @@ namespace Tests
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
var ex = Assert.Throws<IllegalMessageEmitException>(() => world.Update(0.01f));
|
var ex = Assert.Throws<IllegalWriteException>(() => world.Update(0.01f));
|
||||||
Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredMessageEmitEngine tried to emit undeclared Message MockMessage"));
|
Assert.That(ex.Message, Is.EqualTo("Engine UndeclaredMessageEmitEngine tried to emit undeclared Message MockMessage"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool someTest;
|
static bool someTest;
|
||||||
|
|
||||||
[Emits(typeof(MockMessage))]
|
[Writes(typeof(MockMessage))]
|
||||||
class EmitMockMessageEngine : Engine
|
class EmitMockMessageEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -282,20 +292,20 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reads(typeof(MockMessage))]
|
[Reads(typeof(MockMessage))]
|
||||||
class SomeTestEngine : Engine
|
class SomeMessageTestEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
{
|
{
|
||||||
someTest = this.Some<MockMessage>();
|
someTest = this.SomeMessage<MockMessage>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Some()
|
public void SomeMessage()
|
||||||
{
|
{
|
||||||
var worldBuilder = new WorldBuilder();
|
var worldBuilder = new WorldBuilder();
|
||||||
worldBuilder.AddEngine(new EmitMockMessageEngine());
|
worldBuilder.AddEngine(new EmitMockMessageEngine());
|
||||||
worldBuilder.AddEngine(new SomeTestEngine());
|
worldBuilder.AddEngine(new SomeMessageTestEngine());
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
@ -304,29 +314,74 @@ namespace Tests
|
||||||
Assert.That(someTest, Is.True);
|
Assert.That(someTest, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
class UndeclaredSomeEngine : Engine
|
class UndeclaredSomeMessageEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
{
|
{
|
||||||
someTest = this.Some<MockMessage>();
|
someTest = this.SomeMessage<MockMessage>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void IllegalSome()
|
public void UndeclaredSomeMessage()
|
||||||
{
|
{
|
||||||
var worldBuilder = new WorldBuilder();
|
var worldBuilder = new WorldBuilder();
|
||||||
worldBuilder.AddEngine(new EmitMockMessageEngine());
|
worldBuilder.AddEngine(new EmitMockMessageEngine());
|
||||||
worldBuilder.AddEngine(new UndeclaredSomeEngine());
|
worldBuilder.AddEngine(new UndeclaredSomeMessageEngine());
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
Assert.Throws<IllegalMessageReadException>(() => world.Update(0.01f));
|
Assert.Throws<IllegalReadException>(() => world.Update(0.01f));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent))]
|
||||||
|
class SomeComponentTestEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(SomeComponent<MockComponent>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void SomeComponent()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
worldBuilder.AddComponent(entity, new MockComponent());
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
world.Update(0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
class UndeclaredSomeComponentEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
SomeComponent<MockComponent>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void UndeclaredSomeComponent()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new UndeclaredSomeComponentEngine());
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
worldBuilder.AddComponent(entity, new MockComponent());
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
Assert.Throws<IllegalReadException>(() => world.Update(0.01));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ValueTuple<Guid, MockComponent> pairA;
|
static ValueTuple<Guid, MockComponent> pairA;
|
||||||
static ValueTuple<Guid, MockComponent> pairB;
|
static ValueTuple<Guid, MockComponent> pairB;
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent))]
|
||||||
class SameValueComponentReadEngine : Engine
|
class SameValueComponentReadEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -354,8 +409,8 @@ namespace Tests
|
||||||
componentB.myString = "hello";
|
componentB.myString = "hello";
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
entity.AddComponent(componentA);
|
worldBuilder.AddComponent(entity, componentA);
|
||||||
entity.AddComponent(componentB);
|
worldBuilder.AddComponent(entity, componentB);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
world.Update(0.01f);
|
world.Update(0.01f);
|
||||||
|
@ -366,6 +421,7 @@ namespace Tests
|
||||||
|
|
||||||
static IEnumerable<ValueTuple<Guid, MockComponent>> emptyComponentReadResult;
|
static IEnumerable<ValueTuple<Guid, MockComponent>> emptyComponentReadResult;
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent))]
|
||||||
class ReadEmptyMockComponentsEngine : Engine
|
class ReadEmptyMockComponentsEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -388,6 +444,7 @@ namespace Tests
|
||||||
|
|
||||||
struct DestroyerComponent : IComponent { }
|
struct DestroyerComponent : IComponent { }
|
||||||
|
|
||||||
|
[Reads(typeof(DestroyerComponent))]
|
||||||
class DestroyerEngine : Engine
|
class DestroyerEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -402,6 +459,8 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
static IEnumerable<ValueTuple<Guid, MockComponent>> results;
|
static IEnumerable<ValueTuple<Guid, MockComponent>> results;
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent))]
|
||||||
class ReaderEngine : Engine
|
class ReaderEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -425,11 +484,11 @@ namespace Tests
|
||||||
mockComponent.myInt = 2;
|
mockComponent.myInt = 2;
|
||||||
mockComponent.myString = "blah";
|
mockComponent.myString = "blah";
|
||||||
|
|
||||||
entity.AddComponent(destroyerComponent);
|
worldBuilder.AddComponent(entity, destroyerComponent);
|
||||||
var componentID = entity.AddComponent(mockComponent);
|
var componentID = worldBuilder.AddComponent(entity, mockComponent);
|
||||||
|
|
||||||
entityB.AddComponent(destroyerComponent);
|
worldBuilder.AddComponent(entityB, destroyerComponent);
|
||||||
var componentBID = entityB.AddComponent(mockComponent);
|
var componentBID = worldBuilder.AddComponent(entityB, mockComponent);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
@ -439,6 +498,8 @@ namespace Tests
|
||||||
Assert.That(results, Does.Not.Contain((componentBID, mockComponent)));
|
Assert.That(results, Does.Not.Contain((componentBID, mockComponent)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(DestroyerComponent), typeof(MockComponent))]
|
||||||
|
[Writes(typeof(MockComponent))]
|
||||||
class DestroyAndAddComponentEngine : Engine
|
class DestroyAndAddComponentEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -447,9 +508,9 @@ namespace Tests
|
||||||
{
|
{
|
||||||
var componentID = componentPair.Item1;
|
var componentID = componentPair.Item1;
|
||||||
var entity = GetEntityByComponentID(componentID);
|
var entity = GetEntityByComponentID(componentID);
|
||||||
var (id, _) = entity.GetComponent<MockComponent>();
|
var (id, _) = GetComponent<MockComponent>(entity);
|
||||||
entity.RemoveComponent(id);
|
RemoveComponent(id);
|
||||||
Destroy(entity.id);
|
Destroy(entity.ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,8 +524,8 @@ namespace Tests
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
entity.AddComponent(new DestroyerComponent());
|
worldBuilder.AddComponent(entity, new DestroyerComponent());
|
||||||
entity.AddComponent(new MockComponent());
|
worldBuilder.AddComponent(entity, new MockComponent());
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
@ -472,6 +533,8 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
static Entity entityFromComponentIDResult;
|
static Entity entityFromComponentIDResult;
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent))]
|
||||||
class GetEntityFromComponentIDEngine : Engine
|
class GetEntityFromComponentIDEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -492,7 +555,7 @@ namespace Tests
|
||||||
component.myString = "howdy";
|
component.myString = "howdy";
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
entity.AddComponent(component);
|
worldBuilder.AddComponent(entity, component);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
world.Update(0.01f);
|
world.Update(0.01f);
|
||||||
|
@ -501,6 +564,8 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
static MockComponent mockComponentByIDResult;
|
static MockComponent mockComponentByIDResult;
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent))]
|
||||||
class GetComponentByIDEngine : Engine
|
class GetComponentByIDEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -520,7 +585,7 @@ namespace Tests
|
||||||
component.myString = "howdy";
|
component.myString = "howdy";
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
entity.AddComponent(component);
|
worldBuilder.AddComponent(entity, component);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
world.Update(0.01f);
|
world.Update(0.01f);
|
||||||
|
@ -530,6 +595,7 @@ namespace Tests
|
||||||
|
|
||||||
struct OtherComponent : IComponent { }
|
struct OtherComponent : IComponent { }
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent), typeof(OtherComponent))]
|
||||||
class GetComponentByIDWithTypeMismatchEngine : Engine
|
class GetComponentByIDWithTypeMismatchEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -550,7 +616,7 @@ namespace Tests
|
||||||
component.myString = "howdy";
|
component.myString = "howdy";
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
entity.AddComponent(component);
|
worldBuilder.AddComponent(entity, component);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
@ -559,6 +625,8 @@ namespace Tests
|
||||||
|
|
||||||
struct EntityIDComponent : IComponent { public Guid entityID; }
|
struct EntityIDComponent : IComponent { public Guid entityID; }
|
||||||
static bool hasEntity;
|
static bool hasEntity;
|
||||||
|
|
||||||
|
[Reads(typeof(EntityIDComponent))]
|
||||||
class HasEntityTestEngine : Engine
|
class HasEntityTestEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -581,9 +649,9 @@ namespace Tests
|
||||||
var entityTwo = worldBuilder.CreateEntity();
|
var entityTwo = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
EntityIDComponent entityIDComponent;
|
EntityIDComponent entityIDComponent;
|
||||||
entityIDComponent.entityID = entityTwo.id;
|
entityIDComponent.entityID = entityTwo.ID;
|
||||||
|
|
||||||
entity.AddComponent(entityIDComponent);
|
worldBuilder.AddComponent(entity, entityIDComponent);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
|
|
@ -32,27 +32,27 @@ namespace Tests
|
||||||
TestDrawComponent testDrawComponent = default(TestDrawComponent);
|
TestDrawComponent testDrawComponent = default(TestDrawComponent);
|
||||||
|
|
||||||
var entityToTrack = worldBuilder.CreateEntity();
|
var entityToTrack = worldBuilder.CreateEntity();
|
||||||
entityToTrack.AddComponent(aComponent);
|
worldBuilder.AddComponent(entityToTrack, aComponent);
|
||||||
entityToTrack.AddComponent(bComponent);
|
worldBuilder.AddComponent(entityToTrack, bComponent);
|
||||||
entityToTrack.AddComponent(testDrawComponent);
|
worldBuilder.AddComponent(entityToTrack, testDrawComponent);
|
||||||
|
|
||||||
var entityNotToTrack = worldBuilder.CreateEntity();
|
var entityNotToTrack = worldBuilder.CreateEntity();
|
||||||
entityNotToTrack.AddComponent(aComponent);
|
worldBuilder.AddComponent(entityNotToTrack, aComponent);
|
||||||
entityNotToTrack.AddComponent(testDrawComponent);
|
worldBuilder.AddComponent(entityNotToTrack, testDrawComponent);
|
||||||
|
|
||||||
var entityWithoutDrawComponent = worldBuilder.CreateEntity();
|
var entityWithoutDrawComponent = worldBuilder.CreateEntity();
|
||||||
entityWithoutDrawComponent.AddComponent(aComponent);
|
worldBuilder.AddComponent(entityWithoutDrawComponent, aComponent);
|
||||||
entityWithoutDrawComponent.AddComponent(bComponent);
|
worldBuilder.AddComponent(entityWithoutDrawComponent, bComponent);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
world.Update(0.01f);
|
world.Update(0.01f);
|
||||||
|
|
||||||
Console.WriteLine(renderer.IsTracking(entityNotToTrack.id));
|
Console.WriteLine(renderer.IsTracking(entityNotToTrack.ID));
|
||||||
|
|
||||||
Assert.IsTrue(renderer.IsTracking(entityToTrack.id));
|
Assert.IsTrue(renderer.IsTracking(entityToTrack.ID));
|
||||||
Assert.IsFalse(renderer.IsTracking(entityNotToTrack.id));
|
Assert.IsFalse(renderer.IsTracking(entityNotToTrack.ID));
|
||||||
Assert.IsFalse(renderer.IsTracking(entityWithoutDrawComponent.id));
|
Assert.IsFalse(renderer.IsTracking(entityWithoutDrawComponent.ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool called = false;
|
static bool called = false;
|
||||||
|
@ -75,19 +75,17 @@ namespace Tests
|
||||||
TestDrawComponent testDrawComponent = default(TestDrawComponent);
|
TestDrawComponent testDrawComponent = default(TestDrawComponent);
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
entity.AddComponent(aComponent);
|
worldBuilder.AddComponent(entity, aComponent);
|
||||||
entity.AddComponent(bComponent);
|
worldBuilder.AddComponent(entity, bComponent);
|
||||||
var testDrawComponentID = entity.AddDrawComponent(testDrawComponent, 1);
|
var testDrawComponentID = worldBuilder.AddDrawComponent(entity, testDrawComponent, 1);
|
||||||
|
|
||||||
|
worldBuilder.DeactivateComponent(testDrawComponentID);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
world.Update(0.01f);
|
world.Update(0.01f);
|
||||||
|
|
||||||
entity.DeactivateComponent(testDrawComponentID);
|
Assert.IsFalse(renderer.IsTracking(entity.ID));
|
||||||
|
|
||||||
world.Update(0.01f);
|
|
||||||
|
|
||||||
Assert.IsFalse(renderer.IsTracking(entity.id));
|
|
||||||
|
|
||||||
world.Draw();
|
world.Draw();
|
||||||
|
|
||||||
|
@ -101,7 +99,7 @@ namespace Tests
|
||||||
{
|
{
|
||||||
public override void Render(Entity entity)
|
public override void Render(Entity entity)
|
||||||
{
|
{
|
||||||
resultComponents = entity.GetComponents<TestDrawComponent>();
|
resultComponents = GetComponents<TestDrawComponent>(entity);
|
||||||
calledOnDraw = true;
|
calledOnDraw = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,16 +115,16 @@ namespace Tests
|
||||||
TestDrawComponent testDrawComponent;
|
TestDrawComponent testDrawComponent;
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
entity.AddComponent(aComponent);
|
worldBuilder.AddComponent(entity, aComponent);
|
||||||
entity.AddComponent(cComponent);
|
worldBuilder.AddComponent(entity, cComponent);
|
||||||
var testDrawComponentID = entity.AddDrawComponent(testDrawComponent, 2);
|
var testDrawComponentID = worldBuilder.AddDrawComponent(entity, testDrawComponent, 2);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
world.Update(0.01f);
|
world.Update(0.01f);
|
||||||
world.Draw();
|
world.Draw();
|
||||||
|
|
||||||
Assert.IsTrue(renderer.IsTracking(entity.id));
|
Assert.IsTrue(renderer.IsTracking(entity.ID));
|
||||||
Assert.IsTrue(calledOnDraw);
|
Assert.IsTrue(calledOnDraw);
|
||||||
resultComponents.Should().Contain(new ValueTuple<Guid, TestDrawComponent>(testDrawComponentID, testDrawComponent));
|
resultComponents.Should().Contain(new ValueTuple<Guid, TestDrawComponent>(testDrawComponentID, testDrawComponent));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,172 +0,0 @@
|
||||||
using NUnit.Framework;
|
|
||||||
using FluentAssertions;
|
|
||||||
|
|
||||||
using Encompass;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Tests
|
|
||||||
{
|
|
||||||
struct MockComponent : IComponent
|
|
||||||
{
|
|
||||||
public string myString;
|
|
||||||
public int myInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EntityTest
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void AddComponent()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
|
||||||
|
|
||||||
MockComponent mockComponent;
|
|
||||||
mockComponent.myInt = 3;
|
|
||||||
mockComponent.myString = "hello";
|
|
||||||
|
|
||||||
entity.AddComponent(mockComponent);
|
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
|
||||||
|
|
||||||
Assert.IsTrue(entity.HasComponent<MockComponent>());
|
|
||||||
Assert.That(entity.GetComponent<MockComponent>().Item2, Is.EqualTo(mockComponent));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void GetComponents()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
|
||||||
|
|
||||||
MockComponent mockComponentA;
|
|
||||||
mockComponentA.myInt = 3;
|
|
||||||
mockComponentA.myString = "hello";
|
|
||||||
|
|
||||||
MockComponent mockComponentB;
|
|
||||||
mockComponentB.myInt = 5;
|
|
||||||
mockComponentB.myString = "wassup";
|
|
||||||
|
|
||||||
MockComponent mockComponentC;
|
|
||||||
mockComponentC.myInt = 1;
|
|
||||||
mockComponentC.myString = "howdy";
|
|
||||||
|
|
||||||
var componentAID = entity.AddComponent(mockComponentA);
|
|
||||||
var componentBID = entity.AddComponent(mockComponentB);
|
|
||||||
var componentCID = entity.AddComponent(mockComponentC);
|
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
|
||||||
|
|
||||||
var components = entity.GetComponents<MockComponent>();
|
|
||||||
components.Should().Contain(new ValueTuple<Guid, MockComponent>(componentAID, mockComponentA));
|
|
||||||
components.Should().Contain(new ValueTuple<Guid, MockComponent>(componentBID, mockComponentB));
|
|
||||||
components.Should().Contain(new ValueTuple<Guid, MockComponent>(componentCID, mockComponentC));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void GetComponent()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
|
||||||
|
|
||||||
MockComponent mockComponent;
|
|
||||||
mockComponent.myInt = 3;
|
|
||||||
mockComponent.myString = "hello";
|
|
||||||
|
|
||||||
var componentID = entity.AddComponent<MockComponent>(mockComponent);
|
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
|
||||||
|
|
||||||
Assert.AreEqual(new ValueTuple<Guid, MockComponent>(componentID, mockComponent), entity.GetComponent<MockComponent>());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void HasComponent()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
|
||||||
|
|
||||||
MockComponent mockComponent;
|
|
||||||
mockComponent.myInt = 3;
|
|
||||||
mockComponent.myString = "hello";
|
|
||||||
|
|
||||||
entity.AddComponent(mockComponent);
|
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
|
||||||
|
|
||||||
Assert.IsTrue(entity.HasComponent<MockComponent>());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void HasComponentWhenInactive()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
|
||||||
|
|
||||||
MockComponent mockComponent;
|
|
||||||
mockComponent.myInt = 3;
|
|
||||||
mockComponent.myString = "hello";
|
|
||||||
|
|
||||||
var componentID = entity.AddComponent(mockComponent);
|
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
|
||||||
|
|
||||||
entity.DeactivateComponent(componentID);
|
|
||||||
|
|
||||||
world.Update(0.01f);
|
|
||||||
|
|
||||||
Assert.IsFalse(entity.HasComponent<MockComponent>());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void RemoveComponent()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
|
||||||
|
|
||||||
MockComponent mockComponent;
|
|
||||||
mockComponent.myInt = 3;
|
|
||||||
mockComponent.myString = "hello";
|
|
||||||
|
|
||||||
var componentID = entity.AddComponent(mockComponent);
|
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
|
||||||
|
|
||||||
entity.RemoveComponent(componentID);
|
|
||||||
|
|
||||||
world.Update(0.01f);
|
|
||||||
|
|
||||||
Assert.IsFalse(entity.HasComponent<MockComponent>());
|
|
||||||
Assert.IsEmpty(entity.GetComponents<MockComponent>());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ReactivateComponent()
|
|
||||||
{
|
|
||||||
var worldBuilder = new WorldBuilder();
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
|
||||||
|
|
||||||
MockComponent mockComponent;
|
|
||||||
mockComponent.myInt = 3;
|
|
||||||
mockComponent.myString = "hello";
|
|
||||||
|
|
||||||
var componentID = entity.AddComponent(mockComponent);
|
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
|
||||||
|
|
||||||
entity.DeactivateComponent(componentID);
|
|
||||||
|
|
||||||
world.Update(0.01f);
|
|
||||||
|
|
||||||
Assert.IsFalse(entity.HasComponent<MockComponent>());
|
|
||||||
Assert.IsEmpty(entity.GetComponents<MockComponent>());
|
|
||||||
|
|
||||||
entity.ActivateComponent(componentID);
|
|
||||||
|
|
||||||
world.Update(0.01f);
|
|
||||||
|
|
||||||
Assert.IsTrue(entity.HasComponent<MockComponent>());
|
|
||||||
Assert.IsNotEmpty(entity.GetComponents<MockComponent>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -32,7 +32,7 @@ namespace Tests
|
||||||
AComponent aComponent;
|
AComponent aComponent;
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
var componentID = entity.AddComponent(aComponent);
|
var componentID = worldBuilder.AddComponent(entity, aComponent);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@ namespace Tests
|
||||||
AComponent aComponentTwo;
|
AComponent aComponentTwo;
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
var componentID = entity.AddComponent(aComponent);
|
var componentID = worldBuilder.AddComponent(entity, aComponent);
|
||||||
var componentTwoID = entity.AddComponent(aComponentTwo);
|
var componentTwoID = worldBuilder.AddComponent(entity, aComponentTwo);
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
world.Update(0.01f);
|
world.Update(0.01f);
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Tests
|
||||||
|
|
||||||
static Entity resultEntity;
|
static Entity resultEntity;
|
||||||
|
|
||||||
[Emits(typeof(SpawnMessageA))]
|
[Writes(typeof(SpawnMessageA))]
|
||||||
class MessageEmitter : Engine
|
class MessageEmitter : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -23,12 +23,14 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Writes(typeof(TestComponent))]
|
||||||
class TestSpawner : Spawner<SpawnMessageA>
|
class TestSpawner : Spawner<SpawnMessageA>
|
||||||
{
|
{
|
||||||
protected override void Spawn(SpawnMessageA message)
|
protected override void Spawn(SpawnMessageA message)
|
||||||
{
|
{
|
||||||
resultEntity = CreateEntity();
|
resultEntity = CreateEntity();
|
||||||
resultEntity.AddComponent(new TestComponent());
|
AddComponent(resultEntity, new TestComponent());
|
||||||
|
Assert.Pass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,14 +44,6 @@ namespace Tests
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
world.Update(0.01);
|
world.Update(0.01);
|
||||||
|
|
||||||
Assert.That(resultEntity.HasComponent<TestComponent>(), Is.True);
|
|
||||||
|
|
||||||
var id = resultEntity.id;
|
|
||||||
|
|
||||||
world.Update(0.01);
|
|
||||||
|
|
||||||
Assert.That(resultEntity.id, Is.Not.EqualTo(id));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Tests
|
||||||
struct BMessage : IMessage { }
|
struct BMessage : IMessage { }
|
||||||
|
|
||||||
[Reads(typeof(AMessage))]
|
[Reads(typeof(AMessage))]
|
||||||
[Emits(typeof(BMessage))]
|
[Writes(typeof(BMessage))]
|
||||||
class AEngine : Engine
|
class AEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -25,7 +25,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reads(typeof(BMessage))]
|
[Reads(typeof(BMessage))]
|
||||||
[Emits(typeof(AMessage))]
|
[Writes(typeof(AMessage))]
|
||||||
class BEngine : Engine
|
class BEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -54,7 +54,7 @@ namespace Tests
|
||||||
struct DMessage : IMessage { }
|
struct DMessage : IMessage { }
|
||||||
|
|
||||||
[Reads(typeof(AMessage))]
|
[Reads(typeof(AMessage))]
|
||||||
[Emits(typeof(BMessage))]
|
[Writes(typeof(BMessage))]
|
||||||
class AEngine : Engine
|
class AEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -65,7 +65,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reads(typeof(BMessage))]
|
[Reads(typeof(BMessage))]
|
||||||
[Emits(typeof(CMessage))]
|
[Writes(typeof(CMessage))]
|
||||||
class BEngine : Engine
|
class BEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -76,7 +76,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reads(typeof(CMessage))]
|
[Reads(typeof(CMessage))]
|
||||||
[Emits(typeof(DMessage))]
|
[Writes(typeof(DMessage))]
|
||||||
class CEngine : Engine
|
class CEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -87,7 +87,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reads(typeof(DMessage))]
|
[Reads(typeof(DMessage))]
|
||||||
[Emits(typeof(AMessage))]
|
[Writes(typeof(AMessage))]
|
||||||
class DEngine : Engine
|
class DEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -114,13 +114,13 @@ namespace Tests
|
||||||
{
|
{
|
||||||
struct AComponent : IComponent { }
|
struct AComponent : IComponent { }
|
||||||
|
|
||||||
[Mutates(typeof(AComponent))]
|
[Writes(typeof(AComponent))]
|
||||||
class AEngine : Engine
|
class AEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt) { }
|
public override void Update(double dt) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Mutates(typeof(AComponent))]
|
[Writes(typeof(AComponent))]
|
||||||
class BEngine : Engine
|
class BEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt) { }
|
public override void Update(double dt) { }
|
||||||
|
@ -133,7 +133,74 @@ namespace Tests
|
||||||
worldBuilder.AddEngine(new AEngine());
|
worldBuilder.AddEngine(new AEngine());
|
||||||
worldBuilder.AddEngine(new BEngine());
|
worldBuilder.AddEngine(new BEngine());
|
||||||
|
|
||||||
Assert.Throws<EngineMutationConflictException>(() => worldBuilder.Build());
|
Assert.Throws<EngineWriteConflictException>(() => worldBuilder.Build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EngineMessageSelfCycle
|
||||||
|
{
|
||||||
|
struct AMessage : IMessage { }
|
||||||
|
|
||||||
|
[Reads(typeof(AMessage))]
|
||||||
|
[Writes(typeof(AMessage))]
|
||||||
|
class AEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ThrowsError()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
|
||||||
|
Assert.Throws<EngineMessageSelfCycleException>(() => worldBuilder.AddEngine(new AEngine()), "Engine both reads and writes Message AMessage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IllegalReadType
|
||||||
|
{
|
||||||
|
struct ANonMessage { }
|
||||||
|
|
||||||
|
[Reads(typeof(ANonMessage))]
|
||||||
|
class MyEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ThrowsError()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
|
||||||
|
Assert.Throws<IllegalReadTypeException>(() => worldBuilder.AddEngine(new MyEngine()), "ANonMessage must be a Message or Component");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IllegalWriteType
|
||||||
|
{
|
||||||
|
struct ANonMessage { }
|
||||||
|
|
||||||
|
[Writes(typeof(ANonMessage))]
|
||||||
|
class MyEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ThrowsError()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
|
||||||
|
Assert.Throws<IllegalWriteTypeException>(() => worldBuilder.AddEngine(new MyEngine()), "ANonMessage must be a Message or Component");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,8 +216,7 @@ namespace Tests
|
||||||
struct CMessage : IMessage { }
|
struct CMessage : IMessage { }
|
||||||
struct DMessage : IMessage { }
|
struct DMessage : IMessage { }
|
||||||
|
|
||||||
[Mutates(typeof(AComponent))]
|
[Writes(typeof(AComponent), typeof(AMessage))]
|
||||||
[Emits(typeof(AMessage))]
|
|
||||||
class AEngine : Engine
|
class AEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -159,8 +225,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Mutates(typeof(BComponent))]
|
[Writes(typeof(BComponent), typeof(BMessage))]
|
||||||
[Emits(typeof(BMessage))]
|
|
||||||
class BEngine : Engine
|
class BEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -170,7 +235,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reads(typeof(AMessage), typeof(BMessage))]
|
[Reads(typeof(AMessage), typeof(BMessage))]
|
||||||
[Emits(typeof(DMessage))]
|
[Writes(typeof(DMessage))]
|
||||||
class CEngine : Engine
|
class CEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
|
|
@ -44,26 +44,26 @@ namespace Tests
|
||||||
TestDrawComponent testDrawComponent = default(TestDrawComponent);
|
TestDrawComponent testDrawComponent = default(TestDrawComponent);
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
entity.AddComponent(testComponent);
|
worldBuilder.AddComponent(entity, testComponent);
|
||||||
entity.AddDrawComponent(testDrawComponent, 3);
|
worldBuilder.AddDrawComponent(entity, testDrawComponent, 3);
|
||||||
|
|
||||||
TestDrawComponent testDrawComponentTwo = default(TestDrawComponent);
|
TestDrawComponent testDrawComponentTwo = default(TestDrawComponent);
|
||||||
|
|
||||||
var entityTwo = worldBuilder.CreateEntity();
|
var entityTwo = worldBuilder.CreateEntity();
|
||||||
entityTwo.AddComponent(testComponent);
|
worldBuilder.AddComponent(entityTwo, testComponent);
|
||||||
entityTwo.AddDrawComponent(testDrawComponentTwo, 1);
|
worldBuilder.AddDrawComponent(entityTwo, testDrawComponentTwo, 1);
|
||||||
|
|
||||||
TestDrawComponent testDrawComponentThree = default(TestDrawComponent);
|
TestDrawComponent testDrawComponentThree = default(TestDrawComponent);
|
||||||
|
|
||||||
var entityThree = worldBuilder.CreateEntity();
|
var entityThree = worldBuilder.CreateEntity();
|
||||||
entityThree.AddComponent(testComponent);
|
worldBuilder.AddComponent(entityThree, testComponent);
|
||||||
entityThree.AddDrawComponent(testDrawComponentThree, 5);
|
worldBuilder.AddDrawComponent(entityThree, testDrawComponentThree, 5);
|
||||||
|
|
||||||
TestDrawComponent testDrawComponentFour = default(TestDrawComponent);
|
TestDrawComponent testDrawComponentFour = default(TestDrawComponent);
|
||||||
|
|
||||||
var entityFour = worldBuilder.CreateEntity();
|
var entityFour = worldBuilder.CreateEntity();
|
||||||
entityFour.AddComponent(testComponent);
|
worldBuilder.AddComponent(entityFour, testComponent);
|
||||||
entityFour.AddDrawComponent(testDrawComponentFour, -5);
|
worldBuilder.AddDrawComponent(entityFour, testDrawComponentFour, -5);
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue