more write conflict checks

pull/5/head
Evan Hemsley 2019-08-21 17:54:43 -07:00
parent 46d742fe49
commit 4a7f65f2f5
3 changed files with 104 additions and 6 deletions

2
TODO
View File

@ -1,4 +1,4 @@
- look at test coverage - look at test coverage
- docs - docs
- WritesPending and writes redundant? - make sure two different engines that Write the same component cannot have same priority

View File

@ -186,6 +186,8 @@ namespace Encompass
var writtenComponentTypesWithoutPriority = new HashSet<Type>(); var writtenComponentTypesWithoutPriority = new HashSet<Type>();
var writtenComponentTypesWithPriority = new HashSet<Type>(); var writtenComponentTypesWithPriority = new HashSet<Type>();
var duplicateWritesWithoutPriority = new List<Type>(); var duplicateWritesWithoutPriority = new List<Type>();
var duplicateWritesWithSamePriority = new List<Type>();
var writePriorities = new Dictionary<Type, HashSet<int>>();
var writeMessageToEngines = new Dictionary<Type, List<Engine>>(); var writeMessageToEngines = new Dictionary<Type, List<Engine>>();
foreach (var engine in engines) foreach (var engine in engines)
@ -196,7 +198,31 @@ namespace Encompass
{ {
var componentType = writeType.GetGenericArguments()[0]; var componentType = writeType.GetGenericArguments()[0];
if (!engine.writePriorities.ContainsKey(componentType)) if (engine.writePriorities.ContainsKey(componentType))
{
var priority = engine.writePriorities[componentType];
writtenComponentTypesWithPriority.Add(componentType);
if (!writePriorities.ContainsKey(componentType))
{
writePriorities[componentType] = new HashSet<int>();
}
if (writePriorities[componentType].Contains(priority))
{
duplicateWritesWithSamePriority.Add(componentType);
}
else if (writtenComponentTypesWithoutPriority.Contains(componentType))
{
duplicateWritesWithoutPriority.Add(componentType);
}
else
{
writePriorities[componentType].Add(priority);
}
}
else
{ {
if (writtenComponentTypesWithoutPriority.Contains(componentType) || writtenComponentTypesWithPriority.Contains(componentType)) if (writtenComponentTypesWithoutPriority.Contains(componentType) || writtenComponentTypesWithPriority.Contains(componentType))
{ {
@ -207,10 +233,6 @@ namespace Encompass
writtenComponentTypesWithoutPriority.Add(componentType); writtenComponentTypesWithoutPriority.Add(componentType);
} }
} }
else
{
writtenComponentTypesWithPriority.Add(componentType);
}
if (!writeMessageToEngines.ContainsKey(componentType)) if (!writeMessageToEngines.ContainsKey(componentType))
{ {
@ -235,6 +257,20 @@ namespace Encompass
throw new EngineWriteConflictException(errorString); throw new EngineWriteConflictException(errorString);
} }
if (duplicateWritesWithSamePriority.Count > 0)
{
var errorString = "Multiple Engines write the same Component with the same priority: ";
foreach (var componentType in duplicateWritesWithSamePriority)
{
errorString += "\n" +
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.";
throw new EngineWriteConflictException(errorString);
}
var engineOrder = new List<Engine>(); var engineOrder = new List<Engine>();
foreach (var engine in engineGraph.TopologicalSort()) foreach (var engine in engineGraph.TopologicalSort())
{ {

View File

@ -275,6 +275,68 @@ namespace Tests
} }
} }
public class PriorityConflict
{
[Writes(typeof(MockComponent), 2)]
class AEngine : Engine
{
public override void Update(double dt)
{
}
}
[Writes(typeof(MockComponent), 2)]
class BEngine : Engine
{
public override void Update(double dt)
{
}
}
[Test]
public void PriorityConflictTest()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AEngine());
worldBuilder.AddEngine(new BEngine());
Assert.Throws<EngineWriteConflictException>(() => worldBuilder.Build());
}
}
public class EngineWriteConflict
{
[Writes(typeof(MockComponent))]
class AEngine : Engine
{
public override void Update(double dt)
{
}
}
[Writes(typeof(MockComponent), 2)]
class BEngine : Engine
{
public override void Update(double dt)
{
}
}
[Test]
public void EngineWriteConflictPriorityAndNoPriorityTest()
{
var worldBuilder = new WorldBuilder();
worldBuilder.AddEngine(new AEngine());
worldBuilder.AddEngine(new BEngine());
Assert.Throws<EngineWriteConflictException>(() => worldBuilder.Build());
}
}
public class LegalEngines public class LegalEngines
{ {
static List<Engine> order = new List<Engine>(); static List<Engine> order = new List<Engine>();