fix silent failure when performing singular reads #11
|
@ -1,4 +1,5 @@
|
||||||
using MoonTools.FastCollections;
|
using Encompass.Exceptions;
|
||||||
|
using MoonTools.FastCollections;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
@ -54,11 +55,15 @@ namespace Encompass
|
||||||
|
|
||||||
public ref readonly TComponent Singular<TComponent>() where TComponent : struct
|
public ref readonly TComponent Singular<TComponent>() where TComponent : struct
|
||||||
{
|
{
|
||||||
|
if (!Any<TComponent>()) { throw new NoComponentOfTypeException("No component of type {0} exists", typeof(TComponent).Name); }
|
||||||
|
|
||||||
return ref Lookup<TComponent>().Singular();
|
return ref Lookup<TComponent>().Singular();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref readonly Entity SingularEntity<TComponent>() where TComponent : struct
|
public ref readonly Entity SingularEntity<TComponent>() where TComponent : struct
|
||||||
{
|
{
|
||||||
|
if (!Any<TComponent>()) { throw new NoComponentOfTypeException("No component of type {0} exists", typeof(TComponent).Name); }
|
||||||
|
|
||||||
return ref Lookup<TComponent>().SingularEntity();
|
return ref Lookup<TComponent>().SingularEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Encompass.Exceptions;
|
||||||
|
|
||||||
namespace Encompass
|
namespace Encompass
|
||||||
{
|
{
|
||||||
|
@ -35,6 +36,8 @@ namespace Encompass
|
||||||
|
|
||||||
public ref readonly TMessage First<TMessage>() where TMessage : struct, IMessage
|
public ref readonly TMessage First<TMessage>() where TMessage : struct, IMessage
|
||||||
{
|
{
|
||||||
|
if (!Any<TMessage>()) { throw new NoMessageOfTypeException("No Message of type {0} exists", typeof(TMessage).Name); }
|
||||||
|
|
||||||
return ref Lookup<TMessage>().First();
|
return ref Lookup<TMessage>().First();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace Encompass.Exceptions
|
namespace Encompass.Exceptions
|
||||||
{
|
{
|
||||||
[Serializable]
|
public class NoComponentOfTypeException : Exception
|
||||||
internal class NoComponentOfTypeException : Exception
|
|
||||||
{
|
|
||||||
public NoComponentOfTypeException()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoComponentOfTypeException(string message) : base(message)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoComponentOfTypeException(string message, Exception innerException) : base(message, innerException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected NoComponentOfTypeException(SerializationInfo info, StreamingContext context) : base(info, context)
|
|
||||||
{
|
{
|
||||||
}
|
public NoComponentOfTypeException(
|
||||||
|
string format,
|
||||||
|
params object[] args
|
||||||
|
) : base(string.Format(format, args)) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Encompass.Exceptions
|
||||||
|
{
|
||||||
|
public class NoMessageOfTypeException : Exception
|
||||||
|
{
|
||||||
|
public NoMessageOfTypeException(
|
||||||
|
string format,
|
||||||
|
params object[] args
|
||||||
|
) : base(string.Format(format, args)) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,10 +17,11 @@ namespace Tests
|
||||||
|
|
||||||
public class EngineTest
|
public class EngineTest
|
||||||
{
|
{
|
||||||
static MockComponent[] resultComponents;
|
|
||||||
static MockComponent resultComponent;
|
static MockComponent resultComponent;
|
||||||
|
static MockComponent[] resultComponents = new MockComponent[1];
|
||||||
|
|
||||||
static MockMessage[] resultMessages;
|
static MockMessage resultMessage;
|
||||||
|
static MockMessage[] resultMessages = new MockMessage[1];
|
||||||
|
|
||||||
[Reads(typeof(MockComponent))]
|
[Reads(typeof(MockComponent))]
|
||||||
public class ReadComponentsTestEngine : Engine
|
public class ReadComponentsTestEngine : Engine
|
||||||
|
@ -149,6 +150,17 @@ namespace Tests
|
||||||
Assert.AreEqual(mockComponent, resultComponent);
|
Assert.AreEqual(mockComponent, resultComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ReadComponentThrowsWhenNoneExist()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new ReadComponentTestEngine());
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
Assert.Throws<NoComponentOfTypeException>(() => world.Update(0.01f), "No component of type MockComponent exists");
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ReadComponentWhenMultipleComponents()
|
public void ReadComponentWhenMultipleComponents()
|
||||||
{
|
{
|
||||||
|
@ -277,7 +289,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Receives(typeof(MockMessage))]
|
[Receives(typeof(MockMessage))]
|
||||||
public class MessageReadEngine : Engine
|
public class ReadMessagesEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
{
|
{
|
||||||
|
@ -285,18 +297,38 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Receives(typeof(MockMessage))]
|
||||||
|
public class ReadMessageEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
resultMessage = ReadMessage<MockMessage>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void EmitAndReadMessage()
|
public void EmitAndReadMessage()
|
||||||
{
|
{
|
||||||
var worldBuilder = new WorldBuilder();
|
var worldBuilder = new WorldBuilder();
|
||||||
worldBuilder.AddEngine(new MessageEmitEngine());
|
worldBuilder.AddEngine(new MessageEmitEngine());
|
||||||
worldBuilder.AddEngine(new MessageReadEngine());
|
worldBuilder.AddEngine(new ReadMessageEngine());
|
||||||
|
|
||||||
var world = worldBuilder.Build();
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
world.Update(0.01f);
|
world.Update(0.01f);
|
||||||
|
|
||||||
Assert.AreEqual(resultMessages.First().myString, "howdy");
|
Assert.AreEqual(resultMessage.myString, "howdy");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ReadMessageThrowsWhenNoneOfTypeExist()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new ReadMessageEngine());
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
Assert.Throws<NoMessageOfTypeException>(() => world.Update(0.01), "No Message of type MockMessage exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UndeclaredMessageEmitEngine : Engine
|
public class UndeclaredMessageEmitEngine : Engine
|
||||||
|
@ -810,7 +842,7 @@ namespace Tests
|
||||||
var worldBuilder = new WorldBuilder();
|
var worldBuilder = new WorldBuilder();
|
||||||
worldBuilder.AddEngine(new ActivateTimeDilationEngine());
|
worldBuilder.AddEngine(new ActivateTimeDilationEngine());
|
||||||
worldBuilder.AddEngine(new DelayedMessageEngine());
|
worldBuilder.AddEngine(new DelayedMessageEngine());
|
||||||
worldBuilder.AddEngine(new MessageReadEngine());
|
worldBuilder.AddEngine(new ReadMessagesEngine());
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
worldBuilder.SetComponent(entity, new MockComponent { });
|
worldBuilder.SetComponent(entity, new MockComponent { });
|
||||||
|
@ -857,7 +889,7 @@ namespace Tests
|
||||||
var worldBuilder = new WorldBuilder();
|
var worldBuilder = new WorldBuilder();
|
||||||
worldBuilder.AddEngine(new ActivateTimeDilationEngine());
|
worldBuilder.AddEngine(new ActivateTimeDilationEngine());
|
||||||
worldBuilder.AddEngine(new DelayedMessageIgnoringTimeDilationEngine());
|
worldBuilder.AddEngine(new DelayedMessageIgnoringTimeDilationEngine());
|
||||||
worldBuilder.AddEngine(new MessageReadEngine());
|
worldBuilder.AddEngine(new ReadMessagesEngine());
|
||||||
|
|
||||||
var entity = worldBuilder.CreateEntity();
|
var entity = worldBuilder.CreateEntity();
|
||||||
worldBuilder.SetComponent(entity, new MockComponent { });
|
worldBuilder.SetComponent(entity, new MockComponent { });
|
||||||
|
@ -950,7 +982,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void GetEntityByComponentType()
|
public void ReadEntity()
|
||||||
{
|
{
|
||||||
var worldBuilder = new WorldBuilder();
|
var worldBuilder = new WorldBuilder();
|
||||||
worldBuilder.AddEngine(new ReadEntityByComponentTypeEngine());
|
worldBuilder.AddEngine(new ReadEntityByComponentTypeEngine());
|
||||||
|
@ -964,6 +996,17 @@ namespace Tests
|
||||||
entity.Should().BeEquivalentTo(readEntity);
|
entity.Should().BeEquivalentTo(readEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ReadEntityThrowsWhenNoComponentOfTypeExists()
|
||||||
|
{
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new ReadEntityByComponentTypeEngine());
|
||||||
|
|
||||||
|
var world = worldBuilder.Build();
|
||||||
|
|
||||||
|
Assert.Throws<NoComponentOfTypeException>(() => world.Update(0.01), "No component of type MockComponent exists");
|
||||||
|
}
|
||||||
|
|
||||||
struct MockComponentB : IComponent
|
struct MockComponentB : IComponent
|
||||||
{
|
{
|
||||||
private int value;
|
private int value;
|
||||||
|
|
Loading…
Reference in New Issue