messages with time dilation system
parent
fc50bf9b81
commit
d45295ae87
|
@ -554,14 +554,23 @@ namespace Encompass
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a message after the specified number of seconds.
|
||||
/// Sends a message after the specified number of seconds, respecting time dilation.
|
||||
/// </summary>
|
||||
/// <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);
|
||||
}
|
||||
|
||||
/// <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
|
||||
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."); }
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
CheckTimeDilationPriorityExists();
|
||||
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)
|
||||
{
|
||||
CheckTimeDilationPriorityExists();
|
||||
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)
|
||||
{
|
||||
CheckTimeDilationPriorityExists();
|
||||
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)
|
||||
{
|
||||
CheckTimeDilationPriorityExists();
|
||||
|
|
|
@ -6,13 +6,22 @@ namespace Encompass
|
|||
{
|
||||
internal class MessageManager
|
||||
{
|
||||
private TimeManager timeManager;
|
||||
|
||||
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)> delayedMessagesIgnoringTimeDilation = new List<(IMessage, double)>();
|
||||
|
||||
public MessageManager(TimeManager timeManager)
|
||||
{
|
||||
this.timeManager = timeManager;
|
||||
}
|
||||
|
||||
internal void RegisterMessageType(Type messageType)
|
||||
{
|
||||
if (!messageTypeToMessages.ContainsKey(messageType)) {
|
||||
if (!messageTypeToMessages.ContainsKey(messageType))
|
||||
{
|
||||
messageTypeToMessages.Add(messageType, new List<IMessage>());
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +40,11 @@ namespace Encompass
|
|||
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()
|
||||
|
@ -50,7 +61,7 @@ namespace Encompass
|
|||
{
|
||||
var (message, time) = delayedMessages[i];
|
||||
|
||||
var updatedTime = time - dt;
|
||||
var updatedTime = time - (dt * timeManager.TimeDilationFactor);
|
||||
|
||||
if (updatedTime <= 0)
|
||||
{
|
||||
|
@ -62,6 +73,23 @@ namespace Encompass
|
|||
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
|
||||
|
|
|
@ -38,11 +38,11 @@ namespace Encompass
|
|||
public WorldBuilder()
|
||||
{
|
||||
drawLayerManager = new DrawLayerManager();
|
||||
timeManager = new TimeManager();
|
||||
componentManager = new ComponentManager(drawLayerManager);
|
||||
messageManager = new MessageManager();
|
||||
messageManager = new MessageManager(timeManager);
|
||||
componentMessageManager = new ComponentMessageManager();
|
||||
entityManager = new EntityManager(componentManager, componentMessageManager);
|
||||
timeManager = new TimeManager();
|
||||
renderManager = new RenderManager(componentManager, drawLayerManager, entityManager);
|
||||
}
|
||||
|
||||
|
|
|
@ -672,7 +672,7 @@ namespace Tests
|
|||
foreach (var (component, entity) in ReadComponentsIncludingEntity<MockComponent>())
|
||||
{
|
||||
RemoveComponent<MockComponent>(entity);
|
||||
SendMessageDelayed(new MockMessage { }, 1);
|
||||
SendMessage(new MockMessage { }, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -683,6 +683,7 @@ namespace Tests
|
|||
resultMessages.Clear();
|
||||
|
||||
var worldBuilder = new WorldBuilder();
|
||||
worldBuilder.AddEngine(new ActivateTimeDilationEngine());
|
||||
worldBuilder.AddEngine(new DelayedMessageEngine());
|
||||
worldBuilder.AddEngine(new MessageReadEngine());
|
||||
|
||||
|
@ -701,6 +702,52 @@ namespace Tests
|
|||
|
||||
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.First().Should().BeOfType<MockMessage>();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue