DefaultWritePriority attribute for engines
parent
5872e916ac
commit
5f72bef256
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -192,16 +192,26 @@ namespace Encompass
|
||||||
|
|
||||||
foreach (var engine in engines)
|
foreach (var engine in engines)
|
||||||
{
|
{
|
||||||
|
var defaultWritePriorityAttribute = engine.GetType().GetCustomAttribute<DefaultWritePriority>(false);
|
||||||
|
|
||||||
var writeTypes = engine.sendTypes.Where((type) => type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ComponentWriteMessage<>));
|
var writeTypes = engine.sendTypes.Where((type) => type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ComponentWriteMessage<>));
|
||||||
|
|
||||||
foreach (var writeType in writeTypes)
|
foreach (var writeType in writeTypes)
|
||||||
{
|
{
|
||||||
var componentType = writeType.GetGenericArguments()[0];
|
var componentType = writeType.GetGenericArguments()[0];
|
||||||
|
|
||||||
|
int? priority = null;
|
||||||
if (engine.writePriorities.ContainsKey(componentType))
|
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);
|
writtenComponentTypesWithPriority.Add(componentType);
|
||||||
|
|
||||||
if (!writePriorities.ContainsKey(componentType))
|
if (!writePriorities.ContainsKey(componentType))
|
||||||
|
@ -209,7 +219,7 @@ namespace Encompass
|
||||||
writePriorities[componentType] = new HashSet<int>();
|
writePriorities[componentType] = new HashSet<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writePriorities[componentType].Contains(priority))
|
if (writePriorities[componentType].Contains(priority.Value))
|
||||||
{
|
{
|
||||||
duplicateWritesWithSamePriority.Add(componentType);
|
duplicateWritesWithSamePriority.Add(componentType);
|
||||||
}
|
}
|
||||||
|
@ -219,7 +229,7 @@ namespace Encompass
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writePriorities[componentType].Add(priority);
|
writePriorities[componentType].Add(priority.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -252,7 +262,7 @@ namespace Encompass
|
||||||
componentType.Name + " written by: " +
|
componentType.Name + " written by: " +
|
||||||
string.Join(", ", writeMessageToEngines[componentType].Select((engine) => engine.GetType().Name));
|
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);
|
throw new EngineWriteConflictException(errorString);
|
||||||
}
|
}
|
||||||
|
@ -266,7 +276,7 @@ namespace Encompass
|
||||||
componentType.Name + " written by: " +
|
componentType.Name + " written by: " +
|
||||||
string.Join(", ", writeMessageToEngines[componentType].Select(engine => engine.GetType().Name));
|
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);
|
throw new EngineWriteConflictException(errorString);
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,6 +208,77 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
[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 EngineMessageSelfCycle
|
public class EngineMessageSelfCycle
|
||||||
{
|
{
|
||||||
struct AMessage : IMessage { }
|
struct AMessage : IMessage { }
|
||||||
|
|
Loading…
Reference in New Issue