diff --git a/encompass-cs/ComponentManager.cs b/encompass-cs/ComponentManager.cs index 53cdbf0..95d3423 100644 --- a/encompass-cs/ComponentManager.cs +++ b/encompass-cs/ComponentManager.cs @@ -105,7 +105,7 @@ namespace Encompass var (entity, type) = keyValuePair.Key; var (componentID, component) = keyValuePair.Value; - if (!entityIDToComponentTypeToComponentID.ContainsKey(entity.ID)) { continue; } + if (!componentIDsMarkedForWrite.Contains(componentID) || !entityIDToComponentTypeToComponentID.ContainsKey(entity.ID)) { continue; } if (entityIDToComponentTypeToComponentID[entity.ID].ContainsKey(type)) { @@ -218,7 +218,7 @@ namespace Encompass { foreach (var componentID in componentsMarkedForRemoval) { - if (componentIDsMarkedForWrite.Contains(componentID)) + if (componentIDsMarkedForWrite.Contains(componentID) && !IDToComponent.ContainsKey(componentID)) { componentIDsMarkedForWrite.Remove(componentID); } diff --git a/test/EngineTest.cs b/test/EngineTest.cs index 6fb829a..9f313d2 100644 --- a/test/EngineTest.cs +++ b/test/EngineTest.cs @@ -847,5 +847,49 @@ namespace Tests Assert.DoesNotThrow(() => world.Update(0.01)); } + + struct DestroyComponentMessage : IMessage { public Entity entity; } + + [Reads(typeof(MockComponent))] + [Writes(typeof(MockComponent))] + class AddComponentEngine : Engine + { + public override void Update(double dt) + { + foreach (var (componentID, component) in ReadComponents()) + { + SetComponent(componentID, new MockComponent {}); + } + } + } + + [Receives(typeof(DestroyComponentMessage))] + class DestroyEntityEngine : Engine + { + public override void Update(double dt) + { + foreach (var message in ReadMessages()) + { + Destroy(message.entity.ID); + } + } + } + + [Test] + public void EngineSetComponentAndDestroyEntitySameFrame() + { + var worldBuilder = new WorldBuilder(); + worldBuilder.AddEngine(new AddComponentEngine()); + worldBuilder.AddEngine(new DestroyEntityEngine()); + + var entity = worldBuilder.CreateEntity(); + worldBuilder.SetComponent(entity, new MockComponent {}); + worldBuilder.SendMessage(new DestroyComponentMessage { entity = entity }); + + var world = worldBuilder.Build(); + world.Update(0.01); + + Assert.DoesNotThrow(() => world.Update(0.01)); + } } }