component updates at end of frame
parent
ca82fa82cf
commit
a62153730f
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Encompass.Exceptions;
|
||||
|
||||
namespace Encompass
|
||||
{
|
||||
|
@ -22,6 +23,8 @@ namespace Encompass
|
|||
private readonly HashSet<Guid> componentsMarkedForDeactivation = new HashSet<Guid>();
|
||||
private readonly HashSet<Guid> componentsMarkedForRemoval = new HashSet<Guid>();
|
||||
|
||||
private readonly Dictionary<Guid, IComponent> pendingUpdates = new Dictionary<Guid, IComponent>();
|
||||
|
||||
//shared references with EntityManager
|
||||
private readonly HashSet<Guid> entitiesWithAddedComponents;
|
||||
private readonly HashSet<Guid> entitiesWithRemovedComponents;
|
||||
|
@ -149,9 +152,24 @@ namespace Encompass
|
|||
return componentIDToEntityID[componentID];
|
||||
}
|
||||
|
||||
internal void UpdateComponent<TComponent>(Guid componentID, TComponent newComponentValue) where TComponent : struct, IComponent
|
||||
internal void AddUpdateComponentOperation<TComponent>(Guid componentID, TComponent newComponentValue) where TComponent : struct, IComponent
|
||||
{
|
||||
IDToComponent[componentID] = newComponentValue;
|
||||
if (pendingUpdates.ContainsKey(componentID))
|
||||
{
|
||||
throw new RepeatUpdateComponentException("Component with ID {0} was updated multiple times this frame", componentID);
|
||||
}
|
||||
|
||||
pendingUpdates.Add(componentID, newComponentValue);
|
||||
}
|
||||
|
||||
internal void PerformComponentUpdates()
|
||||
{
|
||||
foreach (var idPair in pendingUpdates)
|
||||
{
|
||||
IDToComponent[idPair.Key] = idPair.Value;
|
||||
}
|
||||
|
||||
pendingUpdates.Clear();
|
||||
}
|
||||
|
||||
internal void MarkAllComponentsOnEntityForRemoval(Guid entityID)
|
||||
|
|
|
@ -134,7 +134,7 @@ namespace Encompass
|
|||
throw new IllegalWriteException("Engine {0} tried to write undeclared Component {1}", this.GetType().Name, typeof(TComponent).Name);
|
||||
}
|
||||
|
||||
componentManager.UpdateComponent(componentID, newComponent);
|
||||
componentManager.AddUpdateComponentOperation(componentID, newComponent);
|
||||
}
|
||||
|
||||
protected void UpdateComponent<TComponent>(Guid componentID, TComponent newComponentValue) where TComponent : struct, IComponent
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace Encompass.Exceptions
|
||||
{
|
||||
public class RepeatUpdateComponentException : Exception
|
||||
{
|
||||
public RepeatUpdateComponentException(
|
||||
string format,
|
||||
params object[] args
|
||||
) : base(string.Format(format, args)) { }
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ namespace Encompass
|
|||
messageManager.ClearMessages();
|
||||
entityManager.DestroyMarkedEntities();
|
||||
|
||||
componentManager.PerformComponentUpdates();
|
||||
componentManager.ActivateMarkedComponents();
|
||||
componentManager.DeactivateMarkedComponents();
|
||||
componentManager.RemoveMarkedComponents();
|
||||
|
|
|
@ -224,6 +224,7 @@ namespace Encompass
|
|||
renderManager
|
||||
);
|
||||
|
||||
componentManager.PerformComponentUpdates();
|
||||
componentManager.ActivateMarkedComponents();
|
||||
componentManager.DeactivateMarkedComponents();
|
||||
componentManager.RemoveMarkedComponents();
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace Tests
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public class ReadComponentTestEngine : Engine
|
||||
{
|
||||
public override void Update(double dt)
|
||||
|
@ -126,16 +127,17 @@ namespace Tests
|
|||
component.myInt = 420;
|
||||
component.myString = "blaze it";
|
||||
UpdateComponent(componentID, component);
|
||||
}
|
||||
}
|
||||
|
||||
resultComponent = ReadComponent<MockComponent>().Item2;
|
||||
}
|
||||
}
|
||||
// this test needs to be improved...
|
||||
|
||||
[Test]
|
||||
public void UpdateComponent()
|
||||
{
|
||||
var worldBuilder = new WorldBuilder();
|
||||
worldBuilder.AddEngine(new UpdateComponentTestEngine());
|
||||
worldBuilder.AddEngine(new ReadComponentTestEngine());
|
||||
|
||||
var entity = worldBuilder.CreateEntity();
|
||||
|
||||
|
@ -147,7 +149,8 @@ namespace Tests
|
|||
|
||||
var world = worldBuilder.Build();
|
||||
|
||||
world.Update(0.01f);
|
||||
world.Update(0.01);
|
||||
world.Update(0.01);
|
||||
|
||||
Assert.AreEqual(420, resultComponent.myInt);
|
||||
Assert.AreEqual("blaze it", resultComponent.myString);
|
||||
|
@ -642,5 +645,48 @@ namespace Tests
|
|||
|
||||
Assert.Throws<ComponentAndMessageWriteException>(() => worldBuilder.AddEngine(new EngineThatWritesComponentAndMessage()));
|
||||
}
|
||||
|
||||
struct MockComponentUpdateMessage : IMessage
|
||||
{
|
||||
public Guid componentID;
|
||||
public MockComponent mockComponent;
|
||||
}
|
||||
|
||||
[Reads(typeof(MockComponentUpdateMessage))]
|
||||
[Writes(typeof(MockComponent))]
|
||||
class RepeatUpdateEngine : Engine
|
||||
{
|
||||
public override void Update(double dt)
|
||||
{
|
||||
foreach (var mockComponentUpdateMessage in ReadMessages<MockComponentUpdateMessage>())
|
||||
{
|
||||
UpdateComponent(mockComponentUpdateMessage.componentID, mockComponentUpdateMessage.mockComponent);
|
||||
UpdateComponent(mockComponentUpdateMessage.componentID, mockComponentUpdateMessage.mockComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EngineUpdatesComponentMultipleTimes()
|
||||
{
|
||||
var worldBuilder = new WorldBuilder();
|
||||
worldBuilder.AddEngine(new RepeatUpdateEngine());
|
||||
|
||||
var entity = worldBuilder.CreateEntity();
|
||||
|
||||
MockComponent mockComponent;
|
||||
mockComponent.myInt = 1;
|
||||
mockComponent.myString = "5";
|
||||
|
||||
var mockComponentID = worldBuilder.AddComponent(entity, mockComponent);
|
||||
|
||||
MockComponentUpdateMessage mockComponentUpdateMessage;
|
||||
mockComponentUpdateMessage.componentID = mockComponentID;
|
||||
mockComponentUpdateMessage.mockComponent = mockComponent;
|
||||
worldBuilder.EmitMessage(mockComponentUpdateMessage);
|
||||
|
||||
var world = worldBuilder.Build();
|
||||
Assert.Throws<RepeatUpdateComponentException>(() => world.Update(0.01));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue