messages with time dilation system
parent
fc50bf9b81
commit
d45295ae87
|
@ -554,14 +554,23 @@ namespace Encompass
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends a message after the specified number of seconds.
|
/// Sends a message after the specified number of seconds, respecting time dilation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time">The time in seconds that will elapse before the message is sent.</param>
|
/// <param name="time">The time in seconds that will elapse before the message is sent.</param>
|
||||||
protected void SendMessageDelayed<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
|
protected void SendMessage<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
|
||||||
{
|
{
|
||||||
messageManager.AddMessageDelayed(message, time);
|
messageManager.AddMessageDelayed(message, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a message after the specified number of seconds, ignoring time dilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The time in seconds that will elapse before the message is sent.</param>
|
||||||
|
protected void SendMessageIgnoringTimeDilation<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
|
||||||
|
{
|
||||||
|
messageManager.AddMessageDelayedIgnoringTimeDilation(message, time);
|
||||||
|
}
|
||||||
|
|
||||||
// unparameterized version to enable dynamic dispatch
|
// unparameterized version to enable dynamic dispatch
|
||||||
protected void SendMessage(IMessage message)
|
protected void SendMessage(IMessage message)
|
||||||
{
|
{
|
||||||
|
@ -695,24 +704,64 @@ namespace Encompass
|
||||||
if (!timeDilationPriority.HasValue) { throw new TimeDilationPriorityUndefinedException("Engines that activate time dilation must use the TimeDilationPriority attribute."); }
|
if (!timeDilationPriority.HasValue) { throw new TimeDilationPriorityUndefinedException("Engines that activate time dilation must use the TimeDilationPriority attribute."); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Activates the Encompass time dilation system.
|
||||||
|
/// If activating time dilation, make sure the TimeDilationPriority attribute is set or an exception will be thrown.
|
||||||
|
/// Engines that have the IgnoresTimeDilation property will ignore all time dilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factor">The time dilation factor, which is multiplied by real delta time.</param>
|
||||||
|
/// <param name="easeInTime">The time that will elapse before time is fully dilated, in real time.</param>
|
||||||
|
/// <param name="activeTime">The length of real time that time will be fully dilated.</param>
|
||||||
|
/// <param name="easeOutTime">The time that will elapse before time is fully undilated.</param>
|
||||||
public void ActivateTimeDilation(double factor, double easeInTime, double activeTime, double easeOutTime)
|
public void ActivateTimeDilation(double factor, double easeInTime, double activeTime, double easeOutTime)
|
||||||
{
|
{
|
||||||
CheckTimeDilationPriorityExists();
|
CheckTimeDilationPriorityExists();
|
||||||
timeManager.ActivateTimeDilation(factor, easeInTime, activeTime, easeOutTime, timeDilationPriority.Value);
|
timeManager.ActivateTimeDilation(factor, easeInTime, activeTime, easeOutTime, timeDilationPriority.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Activates the Encompass time dilation system.
|
||||||
|
/// If activating time dilation, make sure the TimeDilationPriority attribute is set or an exception will be thrown.
|
||||||
|
/// Engines that have the IgnoresTimeDilation property will ignore all time dilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factor">The time dilation factor, which is multiplied by real delta time.</param>
|
||||||
|
/// <param name="easeInTime">The time that will elapse before time is fully dilated, in real time.</param>
|
||||||
|
/// <param name="easeInFunction">An easing function for the easing in of time dilation.</param>
|
||||||
|
/// <param name="activeTime">The length of real time that time will be fully dilated.</param>
|
||||||
|
/// <param name="easeOutTime">The time that will elapse before time is fully undilated.</param>
|
||||||
public void ActivateTimeDilation(double factor, double easeInTime, System.Func<double, double, double, double, double> easeInFunction, double activeTime, double easeOutTime)
|
public void ActivateTimeDilation(double factor, double easeInTime, System.Func<double, double, double, double, double> easeInFunction, double activeTime, double easeOutTime)
|
||||||
{
|
{
|
||||||
CheckTimeDilationPriorityExists();
|
CheckTimeDilationPriorityExists();
|
||||||
timeManager.ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, timeDilationPriority.Value);
|
timeManager.ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, timeDilationPriority.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Activates the Encompass time dilation system.
|
||||||
|
/// If activating time dilation, make sure the TimeDilationPriority attribute is set or an exception will be thrown.
|
||||||
|
/// Engines that have the IgnoresTimeDilation property will ignore all time dilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factor">The time dilation factor, which is multiplied by real delta time.</param>
|
||||||
|
/// <param name="easeInTime">The time that will elapse before time is fully dilated, in real time.</param>
|
||||||
|
/// <param name="activeTime">The length of real time that time will be fully dilated.</param>
|
||||||
|
/// <param name="easeOutTime">The time that will elapse before time is fully undilated.</param>
|
||||||
|
/// <param name="easeOutFunction">An easing function for the easing out of time dilation.</param>
|
||||||
public void ActivateTimeDilation(double factor, double easeInTime, double activeTime, double easeOutTime, System.Func<double, double, double, double, double> easeOutFunction)
|
public void ActivateTimeDilation(double factor, double easeInTime, double activeTime, double easeOutTime, System.Func<double, double, double, double, double> easeOutFunction)
|
||||||
{
|
{
|
||||||
CheckTimeDilationPriorityExists();
|
CheckTimeDilationPriorityExists();
|
||||||
timeManager.ActivateTimeDilation(factor, easeInTime, activeTime, easeOutTime, easeOutFunction, timeDilationPriority.Value);
|
timeManager.ActivateTimeDilation(factor, easeInTime, activeTime, easeOutTime, easeOutFunction, timeDilationPriority.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Activates the Encompass time dilation system.
|
||||||
|
/// If activating time dilation, make sure the TimeDilationPriority attribute is set or an exception will be thrown.
|
||||||
|
/// Engines that have the IgnoresTimeDilation property will ignore all time dilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factor">The time dilation factor, which is multiplied by real delta time.</param>
|
||||||
|
/// <param name="easeInTime">The time that will elapse before time is fully dilated, in real time.</param>
|
||||||
|
/// <param name="easeInFunction">An easing function for the easing in of time dilation.</param>
|
||||||
|
/// <param name="activeTime">The length of real time that time will be fully dilated.</param>
|
||||||
|
/// <param name="easeOutTime">The time that will elapse before time is fully undilated.</param>
|
||||||
|
/// <param name="easeOutFunction">An easing function for the easing out of time dilation.</param>
|
||||||
public void ActivateTimeDilation(double factor, double easeInTime, System.Func<double, double, double, double, double> easeInFunction, double activeTime, double easeOutTime, System.Func<double, double, double, double, double> easeOutFunction)
|
public void ActivateTimeDilation(double factor, double easeInTime, System.Func<double, double, double, double, double> easeInFunction, double activeTime, double easeOutTime, System.Func<double, double, double, double, double> easeOutFunction)
|
||||||
{
|
{
|
||||||
CheckTimeDilationPriorityExists();
|
CheckTimeDilationPriorityExists();
|
||||||
|
|
|
@ -6,13 +6,22 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
internal class MessageManager
|
internal class MessageManager
|
||||||
{
|
{
|
||||||
|
private TimeManager timeManager;
|
||||||
|
|
||||||
private readonly Dictionary<Type, List<IMessage>> messageTypeToMessages = new Dictionary<Type, List<IMessage>>();
|
private readonly Dictionary<Type, List<IMessage>> messageTypeToMessages = new Dictionary<Type, List<IMessage>>();
|
||||||
|
|
||||||
private readonly List<(IMessage, double)> delayedMessages = new List<(IMessage, double)>();
|
private readonly List<(IMessage, double)> delayedMessages = new List<(IMessage, double)>();
|
||||||
|
private readonly List<(IMessage, double)> delayedMessagesIgnoringTimeDilation = new List<(IMessage, double)>();
|
||||||
|
|
||||||
|
public MessageManager(TimeManager timeManager)
|
||||||
|
{
|
||||||
|
this.timeManager = timeManager;
|
||||||
|
}
|
||||||
|
|
||||||
internal void RegisterMessageType(Type messageType)
|
internal void RegisterMessageType(Type messageType)
|
||||||
{
|
{
|
||||||
if (!messageTypeToMessages.ContainsKey(messageType)) {
|
if (!messageTypeToMessages.ContainsKey(messageType))
|
||||||
|
{
|
||||||
messageTypeToMessages.Add(messageType, new List<IMessage>());
|
messageTypeToMessages.Add(messageType, new List<IMessage>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,9 +40,11 @@ namespace Encompass
|
||||||
delayedMessages.Add((message, time));
|
delayedMessages.Add((message, time));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddMessage<TMessage>(IMessage message) where TMessage : struct, IMessage
|
internal void AddMessageDelayedIgnoringTimeDilation(IMessage message, double time)
|
||||||
{
|
{
|
||||||
messageTypeToMessages[typeof(TMessage)].Add(message);
|
if (!messageTypeToMessages.ContainsKey(message.GetType())) { messageTypeToMessages.Add(message.GetType(), new List<IMessage>()); }
|
||||||
|
|
||||||
|
delayedMessagesIgnoringTimeDilation.Add((message, time));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ClearMessages()
|
internal void ClearMessages()
|
||||||
|
@ -50,7 +61,7 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
var (message, time) = delayedMessages[i];
|
var (message, time) = delayedMessages[i];
|
||||||
|
|
||||||
var updatedTime = time - dt;
|
var updatedTime = time - (dt * timeManager.TimeDilationFactor);
|
||||||
|
|
||||||
if (updatedTime <= 0)
|
if (updatedTime <= 0)
|
||||||
{
|
{
|
||||||
|
@ -62,6 +73,23 @@ namespace Encompass
|
||||||
delayedMessages[i] = (message, updatedTime);
|
delayedMessages[i] = (message, updatedTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = delayedMessagesIgnoringTimeDilation.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var (message, time) = delayedMessagesIgnoringTimeDilation[i];
|
||||||
|
|
||||||
|
var updatedTime = time - dt;
|
||||||
|
|
||||||
|
if (updatedTime <= 0)
|
||||||
|
{
|
||||||
|
AddMessage(message);
|
||||||
|
delayedMessagesIgnoringTimeDilation.RemoveAt(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delayedMessagesIgnoringTimeDilation[i] = (message, updatedTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IEnumerable<TMessage> GetMessagesByType<TMessage>() where TMessage : struct, IMessage
|
internal IEnumerable<TMessage> GetMessagesByType<TMessage>() where TMessage : struct, IMessage
|
||||||
|
|
|
@ -38,11 +38,11 @@ namespace Encompass
|
||||||
public WorldBuilder()
|
public WorldBuilder()
|
||||||
{
|
{
|
||||||
drawLayerManager = new DrawLayerManager();
|
drawLayerManager = new DrawLayerManager();
|
||||||
|
timeManager = new TimeManager();
|
||||||
componentManager = new ComponentManager(drawLayerManager);
|
componentManager = new ComponentManager(drawLayerManager);
|
||||||
messageManager = new MessageManager();
|
messageManager = new MessageManager(timeManager);
|
||||||
componentMessageManager = new ComponentMessageManager();
|
componentMessageManager = new ComponentMessageManager();
|
||||||
entityManager = new EntityManager(componentManager, componentMessageManager);
|
entityManager = new EntityManager(componentManager, componentMessageManager);
|
||||||
timeManager = new TimeManager();
|
|
||||||
renderManager = new RenderManager(componentManager, drawLayerManager, entityManager);
|
renderManager = new RenderManager(componentManager, drawLayerManager, entityManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -672,7 +672,7 @@ namespace Tests
|
||||||
foreach (var (component, entity) in ReadComponentsIncludingEntity<MockComponent>())
|
foreach (var (component, entity) in ReadComponentsIncludingEntity<MockComponent>())
|
||||||
{
|
{
|
||||||
RemoveComponent<MockComponent>(entity);
|
RemoveComponent<MockComponent>(entity);
|
||||||
SendMessageDelayed(new MockMessage { }, 1);
|
SendMessage(new MockMessage { }, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -683,6 +683,7 @@ namespace Tests
|
||||||
resultMessages.Clear();
|
resultMessages.Clear();
|
||||||
|
|
||||||
var worldBuilder = new WorldBuilder();
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new ActivateTimeDilationEngine());
|
||||||
worldBuilder.AddEngine(new DelayedMessageEngine());
|
worldBuilder.AddEngine(new DelayedMessageEngine());
|
||||||
worldBuilder.AddEngine(new MessageReadEngine());
|
worldBuilder.AddEngine(new MessageReadEngine());
|
||||||
|
|
||||||
|
@ -701,6 +702,52 @@ namespace Tests
|
||||||
|
|
||||||
world.Update(0.5);
|
world.Update(0.5);
|
||||||
|
|
||||||
|
resultMessages.Should().BeEmpty();
|
||||||
|
|
||||||
|
world.Update(2);
|
||||||
|
|
||||||
|
resultMessages.Should().NotBeEmpty();
|
||||||
|
resultMessages.First().Should().BeOfType<MockMessage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Reads(typeof(MockComponent))]
|
||||||
|
class DelayedMessageIgnoringTimeDilationEngine : Engine
|
||||||
|
{
|
||||||
|
public override void Update(double dt)
|
||||||
|
{
|
||||||
|
foreach (var (component, entity) in ReadComponentsIncludingEntity<MockComponent>())
|
||||||
|
{
|
||||||
|
RemoveComponent<MockComponent>(entity);
|
||||||
|
SendMessageIgnoringTimeDilation(new MockMessage { }, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void EngineSendMessageDelayedIgnoringTimeDilation()
|
||||||
|
{
|
||||||
|
resultMessages.Clear();
|
||||||
|
|
||||||
|
var worldBuilder = new WorldBuilder();
|
||||||
|
worldBuilder.AddEngine(new ActivateTimeDilationEngine());
|
||||||
|
worldBuilder.AddEngine(new DelayedMessageIgnoringTimeDilationEngine());
|
||||||
|
worldBuilder.AddEngine(new MessageReadEngine());
|
||||||
|
|
||||||
|
var entity = worldBuilder.CreateEntity();
|
||||||
|
worldBuilder.SetComponent(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.Should().NotBeEmpty();
|
||||||
resultMessages.First().Should().BeOfType<MockMessage>();
|
resultMessages.First().Should().BeOfType<MockMessage>();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue