delayed message system
parent
6a51ceb590
commit
d084286c83
|
@ -308,6 +308,11 @@ namespace Encompass
|
|||
messageManager.AddMessage(message);
|
||||
}
|
||||
|
||||
protected void SendMessageDelayed<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
|
||||
{
|
||||
messageManager.AddMessageDelayed(message, time);
|
||||
}
|
||||
|
||||
// unparameterized version to enable dynamic dispatch
|
||||
protected void SendMessage(IMessage message)
|
||||
{
|
||||
|
|
|
@ -8,6 +8,8 @@ namespace Encompass
|
|||
{
|
||||
private readonly Dictionary<Type, List<IMessage>> messageTypeToMessages = new Dictionary<Type, List<IMessage>>();
|
||||
|
||||
private readonly List<(IMessage, double)> delayedMessages = new List<(IMessage, double)>();
|
||||
|
||||
internal void RegisterMessageType(Type messageType)
|
||||
{
|
||||
if (!messageTypeToMessages.ContainsKey(messageType)) {
|
||||
|
@ -22,6 +24,13 @@ namespace Encompass
|
|||
messageTypeToMessages[type].Add(message);
|
||||
}
|
||||
|
||||
internal void AddMessageDelayed(IMessage message, double time)
|
||||
{
|
||||
if (!messageTypeToMessages.ContainsKey(message.GetType())) { messageTypeToMessages.Add(message.GetType(), new List<IMessage>()); }
|
||||
|
||||
delayedMessages.Add((message, time));
|
||||
}
|
||||
|
||||
internal void AddMessage<TMessage>(IMessage message) where TMessage : struct, IMessage
|
||||
{
|
||||
messageTypeToMessages[typeof(TMessage)].Add(message);
|
||||
|
@ -35,6 +44,26 @@ namespace Encompass
|
|||
}
|
||||
}
|
||||
|
||||
internal void ProcessDelayedMessages(double dt)
|
||||
{
|
||||
for (int i = delayedMessages.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var (message, time) = delayedMessages[i];
|
||||
|
||||
var updatedTime = time - dt;
|
||||
|
||||
if (updatedTime <= 0)
|
||||
{
|
||||
AddMessage(message);
|
||||
delayedMessages.RemoveAt(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
delayedMessages[i] = (message, updatedTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<TMessage> GetMessagesByType<TMessage>() where TMessage : struct, IMessage
|
||||
{
|
||||
return messageTypeToMessages.ContainsKey(typeof(TMessage)) ?
|
||||
|
|
|
@ -30,6 +30,8 @@ namespace Encompass
|
|||
|
||||
public void Update(double dt)
|
||||
{
|
||||
messageManager.ProcessDelayedMessages(dt);
|
||||
|
||||
foreach (var engine in enginesInOrder)
|
||||
{
|
||||
engine.Update(dt);
|
||||
|
|
|
@ -45,6 +45,11 @@ namespace Encompass
|
|||
messageManager.AddMessage(message);
|
||||
}
|
||||
|
||||
public void SendMessageDelayed<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
|
||||
{
|
||||
messageManager.AddMessageDelayed(message, time);
|
||||
}
|
||||
|
||||
public Guid AddComponent<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
|
||||
{
|
||||
return componentManager.MarkComponentForAdd(entity, component);
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Tests
|
|||
static List<ValueTuple<Guid, MockComponent>> resultComponents;
|
||||
static MockComponent resultComponent;
|
||||
|
||||
static List<MockMessage> resultMessages;
|
||||
static List<MockMessage> resultMessages = new List<MockMessage>();
|
||||
|
||||
[Reads(typeof(MockComponent))]
|
||||
public class ReadComponentsTestEngine : Engine
|
||||
|
@ -763,5 +763,46 @@ namespace Tests
|
|||
var world = worldBuilder.Build();
|
||||
Assert.Throws<RepeatUpdateComponentException>(() => world.Update(0.01));
|
||||
}
|
||||
|
||||
[Reads(typeof(MockComponent))]
|
||||
class DelayedMessageEngine : Engine
|
||||
{
|
||||
public override void Update(double dt)
|
||||
{
|
||||
foreach (var (componentID, component) in ReadComponents<MockComponent>())
|
||||
{
|
||||
RemoveComponent(componentID);
|
||||
SendMessageDelayed(new MockMessage {}, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EngineSendMessageDelayed()
|
||||
{
|
||||
resultMessages.Clear();
|
||||
|
||||
var worldBuilder = new WorldBuilder();
|
||||
worldBuilder.AddEngine(new DelayedMessageEngine());
|
||||
worldBuilder.AddEngine(new MessageReadEngine());
|
||||
|
||||
var entity = worldBuilder.CreateEntity();
|
||||
worldBuilder.AddComponent(entity, new MockComponent {});
|
||||
|
||||
var world = worldBuilder.Build();
|
||||
|
||||
world.Update(0.01);
|
||||
|
||||
resultMessages.Should().BeEmpty();
|
||||
|
||||
world.Update(0.5);
|
||||
|
||||
resultMessages.Should().BeEmpty();
|
||||
|
||||
world.Update(0.5);
|
||||
|
||||
resultMessages.Should().NotBeEmpty();
|
||||
resultMessages.First().Should().BeOfType<MockMessage>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ using NUnit.Framework;
|
|||
using Encompass;
|
||||
using System.Collections.Generic;
|
||||
using Encompass.Exceptions;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
|
@ -273,6 +275,39 @@ namespace Tests
|
|||
Assert.That(order.IndexOf(engineB), Is.LessThan(order.IndexOf(engineC)));
|
||||
Assert.That(order.IndexOf(engineC), Is.LessThan(order.IndexOf(engineD)));
|
||||
}
|
||||
|
||||
static List<AMessage> resultMessages = new List<AMessage>();
|
||||
|
||||
[Receives(typeof(AMessage))]
|
||||
class ReadMessageEngine : Engine
|
||||
{
|
||||
public override void Update(double dt)
|
||||
{
|
||||
resultMessages = ReadMessages<AMessage>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SendMessageDelayed()
|
||||
{
|
||||
var worldBuilder = new WorldBuilder();
|
||||
worldBuilder.AddEngine(new ReadMessageEngine());
|
||||
|
||||
worldBuilder.SendMessageDelayed(new AMessage {}, 0.5);
|
||||
|
||||
var world = worldBuilder.Build();
|
||||
|
||||
resultMessages.Should().BeEmpty();
|
||||
|
||||
world.Update(0.25);
|
||||
|
||||
resultMessages.Should().BeEmpty();
|
||||
|
||||
world.Update(0.25);
|
||||
|
||||
resultMessages.Should().NotBeEmpty();
|
||||
resultMessages.First().Should().BeOfType<AMessage>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue