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