DefaultWritePriority attribute for engines

pull/5/head
Evan Hemsley 2019-09-26 13:26:48 -07:00
parent 5872e916ac
commit 5f72bef256
4 changed files with 109 additions and 13 deletions

View File

@ -0,0 +1,15 @@
using System;
namespace Encompass
{
[AttributeUsage(AttributeTargets.Class)]
public class DefaultWritePriority : Attribute
{
public int writePriority;
public DefaultWritePriority(int writePriority)
{
this.writePriority = writePriority;
}
}
}

View File

@ -37,4 +37,4 @@ namespace Encompass
this.priorities.Add(writeType, priority);
}
}
}
}

View File

@ -192,16 +192,26 @@ namespace Encompass
foreach (var engine in engines)
{
var defaultWritePriorityAttribute = engine.GetType().GetCustomAttribute<DefaultWritePriority>(false);
var writeTypes = engine.sendTypes.Where((type) => type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ComponentWriteMessage<>));
foreach (var writeType in writeTypes)
{
var componentType = writeType.GetGenericArguments()[0];
int? priority = null;
if (engine.writePriorities.ContainsKey(componentType))
{
var priority = engine.writePriorities[componentType];
priority = engine.writePriorities[componentType];
}
else if (defaultWritePriorityAttribute != null)
{
priority = defaultWritePriorityAttribute.writePriority;
}
if (priority.HasValue)
{
writtenComponentTypesWithPriority.Add(componentType);
if (!writePriorities.ContainsKey(componentType))
@ -209,7 +219,7 @@ namespace Encompass
writePriorities[componentType] = new HashSet<int>();
}
if (writePriorities[componentType].Contains(priority))
if (writePriorities[componentType].Contains(priority.Value))
{
duplicateWritesWithSamePriority.Add(componentType);
}
@ -219,7 +229,7 @@ namespace Encompass
}
else
{
writePriorities[componentType].Add(priority);
writePriorities[componentType].Add(priority.Value);
}
}
else
@ -252,7 +262,7 @@ namespace Encompass
componentType.Name + " written by: " +
string.Join(", ", writeMessageToEngines[componentType].Select((engine) => engine.GetType().Name));
}
errorString += "\nTo resolve the conflict, add priority arguments to the Writes declarations.";
errorString += "\nTo resolve the conflict, add priority arguments to the Writes declarations or use a DefaultWritePriority attribute.";
throw new EngineWriteConflictException(errorString);
}
@ -266,7 +276,7 @@ namespace Encompass
componentType.Name + " written by: " +
string.Join(", ", writeMessageToEngines[componentType].Select(engine => engine.GetType().Name));
}
errorString += "\nTo resolve the conflict, add priority arguments to the Writes declarations.";
errorString += "\nTo resolve the conflict, add priority arguments to the Writes declarations or use a DefaultWritePriority attribute.";
throw new EngineWriteConflictException(errorString);
}

View File

@ -141,12 +141,12 @@ namespace Tests
public class MultipleEngineWriteWithPriority
{
struct SetMessage : IMessage
struct SetMessage : IMessage
{
public Entity entity;
}
struct AComponent : IComponent
struct AComponent : IComponent
{
public int myInt;
}
@ -156,7 +156,7 @@ namespace Tests
[WritesPending(typeof(AComponent))]
class AEngine : Engine
{
public override void Update(double dt)
public override void Update(double dt)
{
foreach (var setMessage in ReadMessages<SetMessage>())
{
@ -170,13 +170,84 @@ namespace Tests
[WritesPending(typeof(AComponent))]
class BEngine : Engine
{
public override void Update(double dt)
public override void Update(double dt)
{
foreach (var setMessage in ReadMessages<SetMessage>())
{
SetComponent(setMessage.entity, new AComponent { myInt = 1 });
}
}
}
}
static AComponent resultComponent;
[ReadsPending(typeof(AComponent))]
class ReadComponentEngine : Engine
{
public override void Update(double dt)
{
resultComponent = ReadComponent<AComponent>().Item2;
}
}
[Test]
public void LowerPriorityWrites()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AEngine());
worldBuilder.AddEngine(new BEngine());
var entity = worldBuilder.CreateEntity();
worldBuilder.SendMessage(new SetMessage { entity = entity });
var world = worldBuilder.Build();
world.Update(0.01);
Assert.That(resultComponent.myInt, Is.EqualTo(0));
}
}
public class DefaultWritePriority
{
struct SetMessage : IMessage
{
public Entity entity;
}
struct AComponent : IComponent
{
public int myInt;
}
[Receives(typeof(SetMessage))]
[Writes(typeof(AComponent))]
[WritesPending(typeof(AComponent))]
[Encompass.DefaultWritePriority(1)]
class AEngine : Engine
{
public override void Update(double dt)
{
foreach (var setMessage in ReadMessages<SetMessage>())
{
SetComponent(setMessage.entity, new AComponent { myInt = 0 });
}
}
}
[Receives(typeof(SetMessage))]
[Writes(typeof(AComponent), 3)]
[WritesPending(typeof(AComponent))]
class BEngine : Engine
{
public override void Update(double dt)
{
foreach (var setMessage in ReadMessages<SetMessage>())
{
SetComponent(setMessage.entity, new AComponent { myInt = 1 });
}
}
}
static AComponent resultComponent;
@ -218,7 +289,7 @@ namespace Tests
{
public override void Update(double dt)
{
}
}
@ -435,7 +506,7 @@ namespace Tests
resultMessages.Should().BeEmpty();
world.Update(0.25);
resultMessages.Should().NotBeEmpty();
resultMessages.First().Should().BeOfType<AMessage>();
}