rework ReadMessages to return a Span
	
		
			
	
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
					Details
				
			
		
	
				
					
				
			
				
	
				continuous-integration/drone/push Build is passing
				
					Details
				
			
		
	
							parent
							
								
									67bc55e780
								
							
						
					
					
						commit
						cdc68e46e5
					
				| 
						 | 
				
			
			@ -18,17 +18,17 @@ namespace Encompass
 | 
			
		|||
            return _stores[typeof(TMessage)] as TypedMessageStore<TMessage>;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddMessage<TMessage>(TMessage message) where TMessage : struct, IMessage
 | 
			
		||||
        public void AddMessage<TMessage>(in TMessage message) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            Lookup<TMessage>().Add(message);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddMessage<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        public void AddMessage<TMessage>(in TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            Lookup<TMessage>().Add(message, time);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddMessageIgnoringTimeDilation<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        public void AddMessageIgnoringTimeDilation<TMessage>(in TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            Lookup<TMessage>().AddIgnoringTimeDilation(message, time);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ namespace Encompass
 | 
			
		|||
            return Lookup<TMessage>().First();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TMessage> All<TMessage>() where TMessage : struct, IMessage
 | 
			
		||||
        public Span<TMessage> All<TMessage>() where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            return Lookup<TMessage>().All();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Encompass
 | 
			
		||||
| 
						 | 
				
			
			@ -10,12 +11,13 @@ namespace Encompass
 | 
			
		|||
 | 
			
		||||
    internal class TypedMessageStore<TMessage> : TypedMessageStore where TMessage : struct, IMessage
 | 
			
		||||
    {
 | 
			
		||||
        private readonly List<int> _indices = new List<int>();
 | 
			
		||||
        // messages are placed in a contiguous region
 | 
			
		||||
        // so we can return the collection as a Span
 | 
			
		||||
        private int _nextIndex = 0;
 | 
			
		||||
        private readonly TMessage[] _store = new TMessage[128];
 | 
			
		||||
        private readonly List<(TMessage, double)> _delayedStore = new List<(TMessage, double)>(128);
 | 
			
		||||
        private readonly List<(TMessage, double)> _delayedStoreIgnoringTimeDilation = new List<(TMessage, double)>(128);
 | 
			
		||||
        private readonly Dictionary<int, HashSet<int>> _entityToIndices = new Dictionary<int, HashSet<int>>();
 | 
			
		||||
        private readonly IDManager _idManager = new IDManager();
 | 
			
		||||
 | 
			
		||||
        public override void ProcessDelayedMessages(double dilatedDelta, double realtimeDelta)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -56,8 +58,7 @@ namespace Encompass
 | 
			
		|||
 | 
			
		||||
        public void Add(in TMessage message)
 | 
			
		||||
        {
 | 
			
		||||
            var index = _idManager.NextID();
 | 
			
		||||
            _indices.Add(index);
 | 
			
		||||
            var index = _nextIndex++;
 | 
			
		||||
            _store[index] = message;
 | 
			
		||||
            if (message is IHasEntity entityMessage)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -79,20 +80,17 @@ namespace Encompass
 | 
			
		|||
 | 
			
		||||
        public TMessage First()
 | 
			
		||||
        {
 | 
			
		||||
            return _store[_indices[0]];
 | 
			
		||||
            return _store[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Any()
 | 
			
		||||
        {
 | 
			
		||||
            return _indices.Count > 0;
 | 
			
		||||
            return _nextIndex != 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TMessage> All()
 | 
			
		||||
        public Span<TMessage> All()
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var index in _indices)
 | 
			
		||||
            {
 | 
			
		||||
                yield return _store[index];
 | 
			
		||||
            }
 | 
			
		||||
            return new Span<TMessage>(_store, 0, _nextIndex);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TMessage> WithEntity(int entityID)
 | 
			
		||||
| 
						 | 
				
			
			@ -113,11 +111,7 @@ namespace Encompass
 | 
			
		|||
 | 
			
		||||
        public override void Clear()
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var index in _indices)
 | 
			
		||||
            {
 | 
			
		||||
                _idManager.Free(index);
 | 
			
		||||
            }
 | 
			
		||||
            _indices.Clear();
 | 
			
		||||
            _nextIndex = 0;
 | 
			
		||||
            foreach (var set in _entityToIndices.Values)
 | 
			
		||||
            {
 | 
			
		||||
                set.Clear();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -529,7 +529,7 @@ namespace Encompass
 | 
			
		|||
        /// <exception cref="Encompass.Exceptions.IllegalSendException">
 | 
			
		||||
        /// Thrown when the Engine does not declare that it Sends the Message Type.
 | 
			
		||||
        /// </exception>
 | 
			
		||||
        protected void SendMessage<TMessage>(TMessage message) where TMessage : struct, IMessage
 | 
			
		||||
        protected void SendMessage<TMessage>(in TMessage message) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            if (!SendTypes.Contains(typeof(TMessage)))
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -543,7 +543,7 @@ namespace Encompass
 | 
			
		|||
        /// 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 SendMessage<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        protected void SendMessage<TMessage>(in TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            _messageManager.AddMessage(message, time);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -552,7 +552,7 @@ namespace Encompass
 | 
			
		|||
        /// 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
 | 
			
		||||
        protected void SendMessageIgnoringTimeDilation<TMessage>(in TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            _messageManager.AddMessageIgnoringTimeDilation(message, time);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -563,7 +563,7 @@ namespace Encompass
 | 
			
		|||
        /// <exception cref="Encompass.Exceptions.IllegalReadException">
 | 
			
		||||
        /// Thrown when the Engine does not declare that it Receives the specified Message Type.
 | 
			
		||||
        /// </exception>
 | 
			
		||||
        protected IEnumerable<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage
 | 
			
		||||
        protected Span<TMessage> ReadMessages<TMessage>() where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            CheckMessageRead<TMessage>();
 | 
			
		||||
            return _messageManager.GetMessagesByType<TMessage>();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Encompass
 | 
			
		||||
| 
						 | 
				
			
			@ -12,17 +13,17 @@ namespace Encompass
 | 
			
		|||
            _timeManager = timeManager;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal void AddMessage<TMessage>(TMessage message) where TMessage : struct, IMessage
 | 
			
		||||
        internal void AddMessage<TMessage>(in TMessage message) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            _messageStore.AddMessage(message);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal void AddMessage<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        internal void AddMessage<TMessage>(in TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            _messageStore.AddMessage(message, time);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal void AddMessageIgnoringTimeDilation<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        internal void AddMessageIgnoringTimeDilation<TMessage>(in TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            _messageStore.AddMessageIgnoringTimeDilation(message, time);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +38,7 @@ namespace Encompass
 | 
			
		|||
            _messageStore.ProcessDelayedMessages(dt * _timeManager.TimeDilationFactor, dt);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal IEnumerable<TMessage> GetMessagesByType<TMessage>() where TMessage : struct, IMessage
 | 
			
		||||
        internal Span<TMessage> GetMessagesByType<TMessage>() where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            return _messageStore.All<TMessage>();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,7 +58,9 @@ namespace Encompass
 | 
			
		|||
                CallGenericMethod(type, "SendMessage", 1, new object[] { Activator.CreateInstance(type) });
 | 
			
		||||
                CallGenericMethod(type, "SendMessage", 2, new object[] { Activator.CreateInstance(type), 1 });
 | 
			
		||||
                CallGenericMethod(type, "ReadMessage", null);
 | 
			
		||||
                CallGenericMethod(type, "ReadMessages", null);
 | 
			
		||||
 | 
			
		||||
                // can't reflect on methods that return a span...
 | 
			
		||||
                //CallGenericMethod(type, "ReadMessages", null);
 | 
			
		||||
                CallGenericMethod(type, "SomeMessage", null);
 | 
			
		||||
                if (typeof(IHasEntity).IsAssignableFrom(type))
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,7 +68,7 @@ namespace Encompass
 | 
			
		|||
        /// <summary>
 | 
			
		||||
        /// Specifies that the given Message should be sent immediately on the first World Update.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void SendMessage<TMessage>(TMessage message) where TMessage : struct, IMessage
 | 
			
		||||
        public void SendMessage<TMessage>(in TMessage message) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            _messageManager.AddMessage(message);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ namespace Encompass
 | 
			
		|||
        /// <summary>
 | 
			
		||||
        /// Specifies that the given Message should be sent after the specified number of seconds after the first World Update.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void SendMessage<TMessage>(TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        public void SendMessage<TMessage>(in TMessage message, double time) where TMessage : struct, IMessage
 | 
			
		||||
        {
 | 
			
		||||
            _messageManager.AddMessage<TMessage>(message, time);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ namespace Tests
 | 
			
		|||
        {
 | 
			
		||||
            public override void Update(double dt)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var addComponentTestMessage in ReadMessages<AddComponentTestMessage>())
 | 
			
		||||
                foreach (ref readonly var addComponentTestMessage in ReadMessages<AddComponentTestMessage>())
 | 
			
		||||
                {
 | 
			
		||||
                    Assert.IsTrue(HasComponent<MockComponent>(addComponentTestMessage.entity));
 | 
			
		||||
                    ref readonly var gottenComponent = ref GetComponent<MockComponent>(addComponentTestMessage.entity);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ namespace Tests
 | 
			
		|||
        static List<MockComponent> resultComponents;
 | 
			
		||||
        static MockComponent resultComponent;
 | 
			
		||||
 | 
			
		||||
        static List<MockMessage> resultMessages = new List<MockMessage>();
 | 
			
		||||
        static MockMessage[] resultMessages;
 | 
			
		||||
 | 
			
		||||
        [Reads(typeof(MockComponent))]
 | 
			
		||||
        public class ReadComponentsTestEngine : Engine
 | 
			
		||||
| 
						 | 
				
			
			@ -279,7 +279,7 @@ namespace Tests
 | 
			
		|||
        {
 | 
			
		||||
            public override void Update(double dt)
 | 
			
		||||
            {
 | 
			
		||||
                resultMessages = this.ReadMessages<MockMessage>().ToList();
 | 
			
		||||
                resultMessages = ReadMessages<MockMessage>().ToArray();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -308,14 +308,14 @@ namespace Tests
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static IEnumerable<MockMessage> emptyReadMessagesResult;
 | 
			
		||||
        static MockMessage[] emptyReadMessagesResult;
 | 
			
		||||
 | 
			
		||||
        [Receives(typeof(MockMessage))]
 | 
			
		||||
        class ReadMessagesWhenNoneExistEngine : Engine
 | 
			
		||||
        {
 | 
			
		||||
            public override void Update(double dt)
 | 
			
		||||
            {
 | 
			
		||||
                emptyReadMessagesResult = ReadMessages<MockMessage>();
 | 
			
		||||
                emptyReadMessagesResult = ReadMessages<MockMessage>().ToArray();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -799,7 +799,7 @@ namespace Tests
 | 
			
		|||
        [Test]
 | 
			
		||||
        public void EngineSendMessageDelayed()
 | 
			
		||||
        {
 | 
			
		||||
            resultMessages.Clear();
 | 
			
		||||
            Array.Clear(resultMessages, 0, resultMessages.Length);
 | 
			
		||||
 | 
			
		||||
            var worldBuilder = new WorldBuilder();
 | 
			
		||||
            worldBuilder.AddEngine(new ActivateTimeDilationEngine());
 | 
			
		||||
| 
						 | 
				
			
			@ -846,7 +846,7 @@ namespace Tests
 | 
			
		|||
        [Test]
 | 
			
		||||
        public void EngineSendMessageDelayedIgnoringTimeDilation()
 | 
			
		||||
        {
 | 
			
		||||
            resultMessages.Clear();
 | 
			
		||||
            Array.Clear(resultMessages, 0, resultMessages.Length);
 | 
			
		||||
 | 
			
		||||
            var worldBuilder = new WorldBuilder();
 | 
			
		||||
            worldBuilder.AddEngine(new ActivateTimeDilationEngine());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ using System.Collections.Generic;
 | 
			
		|||
using Encompass.Exceptions;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using FluentAssertions;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Tests
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -479,20 +480,22 @@ namespace Tests
 | 
			
		|||
                Assert.That(order.IndexOf(engineC), Is.LessThan(order.IndexOf(engineD)));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            static List<AMessage> resultMessages = new List<AMessage>();
 | 
			
		||||
            static AMessage[] resultMessages;
 | 
			
		||||
 | 
			
		||||
            [Receives(typeof(AMessage))]
 | 
			
		||||
            class ReadMessageEngine : Engine
 | 
			
		||||
            {
 | 
			
		||||
                public override void Update(double dt)
 | 
			
		||||
                {
 | 
			
		||||
                    resultMessages = ReadMessages<AMessage>().ToList();
 | 
			
		||||
                    resultMessages = ReadMessages<AMessage>().ToArray();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Test]
 | 
			
		||||
            public void SendMessageDelayed()
 | 
			
		||||
            {
 | 
			
		||||
                resultMessages = Array.Empty<AMessage>();
 | 
			
		||||
 | 
			
		||||
                var worldBuilder = new WorldBuilder();
 | 
			
		||||
                worldBuilder.AddEngine(new ReadMessageEngine());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue