misc backend fixes + more tests
parent
116f424262
commit
dd75a94d18
|
@ -161,8 +161,6 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
MarkForRemoval(componentID);
|
MarkForRemoval(componentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityIDToComponentIDs.Remove(entityID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void MarkForActivation(Guid componentID)
|
internal void MarkForActivation(Guid componentID)
|
||||||
|
@ -217,7 +215,7 @@ namespace Encompass
|
||||||
componentsToDeactivate.Clear();
|
componentsToDeactivate.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RemoveMarkedComponents()
|
public void RemoveMarkedComponents()
|
||||||
{
|
{
|
||||||
foreach (var componentID in componentsToRemove)
|
foreach (var componentID in componentsToRemove)
|
||||||
{
|
{
|
||||||
|
@ -228,7 +226,10 @@ namespace Encompass
|
||||||
inactiveComponents.Remove(componentID);
|
inactiveComponents.Remove(componentID);
|
||||||
|
|
||||||
var entityID = componentIDToEntityID[componentID];
|
var entityID = componentIDToEntityID[componentID];
|
||||||
entityIDToComponentIDs[entityID].Remove(componentID);
|
if (entityIDToComponentIDs.ContainsKey(entityID))
|
||||||
|
{
|
||||||
|
entityIDToComponentIDs[entityID].Remove(componentID);
|
||||||
|
}
|
||||||
|
|
||||||
IDToComponent.Remove(componentID);
|
IDToComponent.Remove(componentID);
|
||||||
componentIDToType.Remove(componentID);
|
componentIDToType.Remove(componentID);
|
||||||
|
@ -243,5 +244,10 @@ namespace Encompass
|
||||||
|
|
||||||
componentsToRemove.Clear();
|
componentsToRemove.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RegisterDestroyedEntity(Guid entityID)
|
||||||
|
{
|
||||||
|
entityIDToComponentIDs.Remove(entityID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,19 +17,19 @@ namespace Encompass
|
||||||
|
|
||||||
public Engine()
|
public Engine()
|
||||||
{
|
{
|
||||||
var mutatesAttribute = this.GetType().GetCustomAttribute<Mutates>(false);
|
var mutatesAttribute = GetType().GetCustomAttribute<Mutates>(false);
|
||||||
if (mutatesAttribute != null)
|
if (mutatesAttribute != null)
|
||||||
{
|
{
|
||||||
mutateComponentTypes = mutatesAttribute.mutateComponentTypes;
|
mutateComponentTypes = mutatesAttribute.mutateComponentTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
var emitsAttribute = this.GetType().GetCustomAttribute<Emits>(false);
|
var emitsAttribute = GetType().GetCustomAttribute<Emits>(false);
|
||||||
if (emitsAttribute != null)
|
if (emitsAttribute != null)
|
||||||
{
|
{
|
||||||
emitMessageTypes = emitsAttribute.emitMessageTypes;
|
emitMessageTypes = emitsAttribute.emitMessageTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
var readsAttribute = this.GetType().GetCustomAttribute<Reads>(false);
|
var readsAttribute = GetType().GetCustomAttribute<Reads>(false);
|
||||||
if (readsAttribute != null)
|
if (readsAttribute != null)
|
||||||
{
|
{
|
||||||
readMessageTypes = readsAttribute.readMessageTypes;
|
readMessageTypes = readsAttribute.readMessageTypes;
|
||||||
|
@ -55,24 +55,34 @@ namespace Encompass
|
||||||
|
|
||||||
protected Entity CreateEntity()
|
protected Entity CreateEntity()
|
||||||
{
|
{
|
||||||
return this.entityManager.CreateEntity();
|
return entityManager.CreateEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Entity GetEntity(Guid entityID)
|
||||||
|
{
|
||||||
|
return entityManager.GetEntity(entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Guid GetEntityIDFromComponentID(Guid componentID)
|
||||||
|
{
|
||||||
|
return componentManager.GetEntityIDFromComponentID(componentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<KeyValuePair<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent
|
protected IEnumerable<KeyValuePair<Guid, TComponent>> ReadComponents<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return this.componentManager.GetActiveComponentsByType<TComponent>();
|
return componentManager.GetActiveComponentsByType<TComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected KeyValuePair<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent
|
protected KeyValuePair<Guid, TComponent> ReadComponent<TComponent>() where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
return this.componentManager.GetActiveComponentByType<TComponent>();
|
return componentManager.GetActiveComponentByType<TComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (mutateComponentTypes.Contains(typeof(TComponent)))
|
||||||
{
|
{
|
||||||
this.componentManager.UpdateComponent(componentID, newComponent);
|
componentManager.UpdateComponent(componentID, newComponent);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -82,14 +92,14 @@ namespace Encompass
|
||||||
|
|
||||||
protected void UpdateComponent<TComponent>(Guid componentID, TComponent newComponentValue) where TComponent : struct, IComponent
|
protected void UpdateComponent<TComponent>(Guid componentID, TComponent newComponentValue) where TComponent : struct, IComponent
|
||||||
{
|
{
|
||||||
this.UpdateComponentInWorld(componentID, newComponentValue);
|
UpdateComponentInWorld(componentID, newComponentValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (emitMessageTypes.Contains(typeof(TMessage)))
|
||||||
{
|
{
|
||||||
this.messageManager.AddMessage(message);
|
messageManager.AddMessage(message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -101,7 +111,7 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
if (readMessageTypes.Contains(typeof(TMessage)))
|
if (readMessageTypes.Contains(typeof(TMessage)))
|
||||||
{
|
{
|
||||||
return this.messageManager.GetMessagesByType<TMessage>();
|
return messageManager.GetMessagesByType<TMessage>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -120,5 +130,10 @@ namespace Encompass
|
||||||
throw new IllegalMessageReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
|
throw new IllegalMessageReadException("Engine {0} tried to read undeclared Message {1}", this.GetType().Name, typeof(TMessage).Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void Destroy(Guid entityID)
|
||||||
|
{
|
||||||
|
entityManager.MarkForDestroy(entityID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace Encompass
|
||||||
entity.RemoveAllComponents();
|
entity.RemoveAllComponents();
|
||||||
IDToEntity.Remove(entityID);
|
IDToEntity.Remove(entityID);
|
||||||
entityToEntityTrackers.Remove(entityID);
|
entityToEntityTrackers.Remove(entityID);
|
||||||
|
componentManager.RegisterDestroyedEntity(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
entitiesMarkedForDestroy.Clear();
|
entitiesMarkedForDestroy.Clear();
|
||||||
|
|
|
@ -357,5 +357,60 @@ namespace Tests
|
||||||
|
|
||||||
Assert.That(emptyComponentReadResult, Is.Empty);
|
Assert.That(emptyComponentReadResult, Is.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DestroyerComponent : IComponent { }
|
||||||
|
|
||||||
|
class DestroyerEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(float dt)
|
||||||
|
{
|
||||||
|
var componentPairs = ReadComponents<DestroyerComponent>();
|
||||||
|
|
||||||
|
foreach (var componentPair in componentPairs)
|
||||||
|
{
|
||||||
|
var componentID = componentPair.Key;
|
||||||
|
var entityID = GetEntityIDFromComponentID(componentID);
|
||||||
|
Destroy(entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static IEnumerable<KeyValuePair<Guid, MockComponent>> results;
|
||||||
|
class ReaderEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(float dt)
|
||||||
|
{
|
||||||
|
results = ReadComponents<MockComponent>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DestroyEntity()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine<DestroyerEngine>();
|
||||||
|
worldBuilder.AddEngine<ReaderEngine>();
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
var entityB = worldBuilder.CreateEntity();
|
||||||
|
|
||||||
|
DestroyerComponent destroyerComponent;
|
||||||
|
MockComponent mockComponent;
|
||||||
|
mockComponent.myInt = 2;
|
||||||
|
mockComponent.myString = "blah";
|
||||||
|
|
||||||
|
entity.AddComponent(destroyerComponent);
|
||||||
|
var componentID = entity.AddComponent(mockComponent);
|
||||||
|
|
||||||
|
entityB.AddComponent(destroyerComponent);
|
||||||
|
var componentBID = entityB.AddComponent(mockComponent);
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
world.Update(0.01f);
|
||||||
|
|
||||||
|
Assert.That(results, Does.Not.Contain(new KeyValuePair<Guid, MockComponent>(componentID, mockComponent)));
|
||||||
|
Assert.That(results, Does.Not.Contain(new KeyValuePair<Guid, MockComponent>(componentBID, mockComponent)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
using NUnit.Framework;
|
||||||
|
using FluentAssertions;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using Encompass;
|
||||||
|
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
public class WorldTest
|
||||||
|
{
|
||||||
|
struct TestComponent : IComponent { }
|
||||||
|
struct TestDrawComponent : IDrawComponent
|
||||||
|
{
|
||||||
|
public int Layer { get ; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<object> drawOrder = new List<object>();
|
||||||
|
|
||||||
|
[Renders(typeof(TestDrawComponent), typeof(TestComponent))]
|
||||||
|
class TestEntityRenderer : EntityRenderer
|
||||||
|
{
|
||||||
|
public override void Render(Entity entity)
|
||||||
|
{
|
||||||
|
drawOrder.Add(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestGeneralRenderer : GeneralRenderer
|
||||||
|
{
|
||||||
|
public new int Layer { get { return 9; } }
|
||||||
|
|
||||||
|
public override void Render()
|
||||||
|
{
|
||||||
|
drawOrder.Add(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DrawOrder()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddRenderer<TestEntityRenderer>();
|
||||||
|
var testGeneralRenderer = worldBuilder.AddRenderer<TestGeneralRenderer>();
|
||||||
|
|
||||||
|
TestComponent testComponent;
|
||||||
|
TestDrawComponent testDrawComponent = default(TestDrawComponent);
|
||||||
|
testDrawComponent.Layer = 3;
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
entity.AddComponent(testComponent);
|
||||||
|
entity.AddComponent(testDrawComponent);
|
||||||
|
|
||||||
|
TestDrawComponent testDrawComponentTwo = default(TestDrawComponent);
|
||||||
|
testDrawComponentTwo.Layer = 1;
|
||||||
|
|
||||||
|
var entityTwo = worldBuilder.CreateEntity();
|
||||||
|
entityTwo.AddComponent(testComponent);
|
||||||
|
entityTwo.AddComponent(testDrawComponentTwo);
|
||||||
|
|
||||||
|
TestDrawComponent testDrawComponentThree = default(TestDrawComponent);
|
||||||
|
testDrawComponentThree.Layer = 5;
|
||||||
|
|
||||||
|
var entityThree = worldBuilder.CreateEntity();
|
||||||
|
entityThree.AddComponent(testComponent);
|
||||||
|
entityThree.AddComponent(testDrawComponentThree);
|
||||||
|
|
||||||
|
TestDrawComponent testDrawComponentFour = default(TestDrawComponent);
|
||||||
|
testDrawComponentFour.Layer = -5;
|
||||||
|
|
||||||
|
var entityFour = worldBuilder.CreateEntity();
|
||||||
|
entityFour.AddComponent(testComponent);
|
||||||
|
entityFour.AddComponent(testDrawComponentFour);
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
world.Update(0.01f);
|
||||||
|
world.Draw();
|
||||||
|
|
||||||
|
drawOrder.Should().BeEquivalentTo(entityFour, entityTwo, entity, entityThree, testGeneralRenderer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue