diff --git a/encompass-cs/Collections/TypedComponentStore.cs b/encompass-cs/Collections/TypedComponentStore.cs index 9e02b46..2b47f63 100644 --- a/encompass-cs/Collections/TypedComponentStore.cs +++ b/encompass-cs/Collections/TypedComponentStore.cs @@ -34,6 +34,7 @@ namespace Encompass { if (!priorities.ContainsKey(entity) || priority < priorities[entity]) { store[entity] = component; + priorities[entity] = priority; return true; } diff --git a/encompass-cs/ComponentUpdateManager.cs b/encompass-cs/ComponentUpdateManager.cs index 3f27029..c61955c 100644 --- a/encompass-cs/ComponentUpdateManager.cs +++ b/encompass-cs/ComponentUpdateManager.cs @@ -38,12 +38,15 @@ namespace Encompass existingComponentStore.Set(entity, component); } - internal void AddPendingComponent(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent + internal bool AddPendingComponent(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent { if (pendingComponentStore.Set(entity, component, priority)) { RegisterExistingOrPendingComponentMessage(entity, component); + return true; } + + return false; } private void RegisterExistingOrPendingComponentMessage(Entity entity, TComponent component) where TComponent : struct, IComponent @@ -52,9 +55,9 @@ namespace Encompass UpToDateComponentStore.Set(entity, component); } - public void UpdateComponent(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent + public bool UpdateComponent(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent { - UpToDateComponentStore.Set(entity, component, priority); + return UpToDateComponentStore.Set(entity, component, priority); } // general component reads by type @@ -90,7 +93,7 @@ namespace Encompass internal (Entity, TComponent) ReadFirstPendingComponentByType() where TComponent : struct, IComponent { - if (!SomeExistingComponent()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } + if (!SomePendingComponent()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } return ReadPendingComponentsByType().First(); } diff --git a/encompass-cs/Engine.cs b/encompass-cs/Engine.cs index 268be45..3c359dd 100644 --- a/encompass-cs/Engine.cs +++ b/encompass-cs/Engine.cs @@ -22,6 +22,7 @@ namespace Encompass internal readonly HashSet writeTypes = new HashSet(); internal readonly HashSet writePendingTypes = new HashSet(); internal readonly Dictionary writePriorities = new Dictionary(); + internal readonly int defaultWritePriority = 0; /// /// If false, the Engine will ignore time dilation. @@ -51,6 +52,13 @@ namespace Encompass writePendingTypes = activatesAttribute.writePendingTypes; } + var defaultWritePriorityAttribute = GetType().GetCustomAttribute(false); + + if (defaultWritePriorityAttribute != null) + { + defaultWritePriority = defaultWritePriorityAttribute.writePriority; + } + foreach (var writesAttribute in GetType().GetCustomAttributes(false)) { writeTypes.UnionWith(writesAttribute.writeTypes); @@ -397,23 +405,24 @@ namespace Encompass /// protected void SetComponent(Entity entity, TComponent component) where TComponent : struct, IComponent { - var priority = writePriorities.ContainsKey(typeof(TComponent)) ? writePriorities[typeof(TComponent)] : 0; + var priority = writePriorities.ContainsKey(typeof(TComponent)) ? writePriorities[typeof(TComponent)] : defaultWritePriority; if (!writeTypes.Contains(typeof(TComponent))) { throw new IllegalWriteException("Engine {0} tried to update undeclared Component {1}", GetType().Name, typeof(TComponent).Name); } + bool written; if (writePendingTypes.Contains(typeof(TComponent))) { - AddPendingComponent(entity, component, priority); + written = AddPendingComponent(entity, component, priority); } else { - componentUpdateManager.UpdateComponent(entity, component, priority); + written = componentUpdateManager.UpdateComponent(entity, component, priority); } - if (component is IDrawableComponent drawableComponent) + if (written && component is IDrawableComponent drawableComponent) { componentManager.RegisterDrawableComponent(entity, component, drawableComponent.Layer); } @@ -471,9 +480,9 @@ namespace Encompass componentUpdateManager.AddExistingComponent(entity, component); } - internal void AddPendingComponent(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent + internal bool AddPendingComponent(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent { - componentUpdateManager.AddPendingComponent(entity, component, priority); + return componentUpdateManager.AddPendingComponent(entity, component, priority); } /// diff --git a/encompass-cs/WorldBuilder.cs b/encompass-cs/WorldBuilder.cs index 09ed567..925dbf4 100644 --- a/encompass-cs/WorldBuilder.cs +++ b/encompass-cs/WorldBuilder.cs @@ -131,7 +131,7 @@ namespace Encompass senders.Add(engine); } - foreach (var componentType in engine.readTypes.Union(engine.writeTypes)) + foreach (var componentType in engine.readTypes.Union(engine.writeTypes).Union(engine.readPendingTypes)) { RegisterComponent(componentType); } diff --git a/test/WorldBuilderTest.cs b/test/WorldBuilderTest.cs index da93315..8e75f8a 100644 --- a/test/WorldBuilderTest.cs +++ b/test/WorldBuilderTest.cs @@ -223,14 +223,14 @@ namespace Tests [Receives(typeof(SetMessage))] [Writes(typeof(AComponent))] [WritesPending(typeof(AComponent))] - [Encompass.DefaultWritePriority(1)] + [Encompass.DefaultWritePriority(4)] class AEngine : Engine { public override void Update(double dt) { foreach (var setMessage in ReadMessages()) { - SetComponent(setMessage.entity, new AComponent { myInt = 0 }); + SetComponent(setMessage.entity, new AComponent { myInt = 5 }); } } } @@ -250,6 +250,20 @@ namespace Tests } } + [Receives(typeof(SetMessage))] + [Writes(typeof(AComponent), 2)] + [WritesPending(typeof(AComponent))] + class CEngine : Engine + { + public override void Update(double dt) + { + foreach (var setMessage in ReadMessages()) + { + SetComponent(setMessage.entity, new AComponent { myInt = 3 }); + } + } + } + static AComponent resultComponent; [ReadsPending(typeof(AComponent))] @@ -267,6 +281,8 @@ namespace Tests var worldBuilder = new WorldBuilder(); worldBuilder.AddEngine(new AEngine()); worldBuilder.AddEngine(new BEngine()); + worldBuilder.AddEngine(new CEngine()); + worldBuilder.AddEngine(new ReadComponentEngine()); var entity = worldBuilder.CreateEntity(); worldBuilder.SendMessage(new SetMessage { entity = entity }); @@ -275,7 +291,7 @@ namespace Tests world.Update(0.01); - Assert.That(resultComponent.myInt, Is.EqualTo(0)); + Assert.That(resultComponent.myInt, Is.EqualTo(3)); } }