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