From df7abf4cf30ee2aa83fa3129fce1d5fac7b39619 Mon Sep 17 00:00:00 2001 From: Evan Hemsley <2342303+ehemsley@users.noreply.github.com> Date: Sun, 29 Dec 2019 20:36:23 -0800 Subject: [PATCH] adds ability to retrieve messages by entity --- encompass-cs/Collections/MessageStore.cs | 5 ++ encompass-cs/Collections/TypedMessageStore.cs | 16 +++++ encompass-cs/Engine.cs | 5 ++ encompass-cs/Interfaces/IHasEntity.cs | 7 ++ encompass-cs/MessageManager.cs | 7 +- test/EngineTest.cs | 68 +++++++++++++++++++ 6 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 encompass-cs/Interfaces/IHasEntity.cs diff --git a/encompass-cs/Collections/MessageStore.cs b/encompass-cs/Collections/MessageStore.cs index 12aef7b..9fb586a 100644 --- a/encompass-cs/Collections/MessageStore.cs +++ b/encompass-cs/Collections/MessageStore.cs @@ -48,6 +48,11 @@ namespace Encompass return Lookup().Any(); } + public IEnumerable WithEntity(int entityID) where TMessage : struct, IMessage, IHasEntity + { + return Lookup().WithEntity(entityID); + } + public void ProcessDelayedMessages(double dilatedDelta, double realtimeDelta) { foreach (var store in Stores.Values) diff --git a/encompass-cs/Collections/TypedMessageStore.cs b/encompass-cs/Collections/TypedMessageStore.cs index 06fc648..aef3a5c 100644 --- a/encompass-cs/Collections/TypedMessageStore.cs +++ b/encompass-cs/Collections/TypedMessageStore.cs @@ -13,6 +13,7 @@ namespace Encompass private readonly List store = new List(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> entityToMessage = new Dictionary>(); public override void ProcessDelayedMessages(double dilatedDelta, double realtimeDelta) { @@ -54,6 +55,12 @@ namespace Encompass public void Add(TMessage message) { store.Add(message); + if (message is IHasEntity entityMessage) + { + var entityID = entityMessage.Entity.ID; + if (!entityToMessage.ContainsKey(entityID)) { entityToMessage.Add(entityID, new List()); } + entityToMessage[entityID].Add(message); + } } public void Add(TMessage message, double time) @@ -81,9 +88,18 @@ namespace Encompass return store; } + public IEnumerable WithEntity(int entityID) + { + return entityToMessage[entityID]; + } + public override void Clear() { store.Clear(); + foreach (var set in entityToMessage.Values) + { + set.Clear(); + } } } } diff --git a/encompass-cs/Engine.cs b/encompass-cs/Engine.cs index 9b2b2b0..9520561 100644 --- a/encompass-cs/Engine.cs +++ b/encompass-cs/Engine.cs @@ -647,6 +647,11 @@ namespace Encompass timeManager.ActivateTimeDilation(factor, easeInTime, easeInFunction, activeTime, easeOutTime, easeOutFunction); } + protected IEnumerable MessagesWithEntity(Entity entity) where TMessage : struct, IMessage, IHasEntity + { + return messageManager.WithEntity(entity.ID); + } + internal void CheckAndUpdateTracking(int entityID) { if (_trackedEntities.Contains(entityID) && !entityQuery.CheckEntity(entityID, componentManager.ExistingBits)) diff --git a/encompass-cs/Interfaces/IHasEntity.cs b/encompass-cs/Interfaces/IHasEntity.cs new file mode 100644 index 0000000..9d3493e --- /dev/null +++ b/encompass-cs/Interfaces/IHasEntity.cs @@ -0,0 +1,7 @@ +namespace Encompass +{ + public interface IHasEntity + { + Entity Entity { get; } + } +} diff --git a/encompass-cs/MessageManager.cs b/encompass-cs/MessageManager.cs index 7da56bf..1256946 100644 --- a/encompass-cs/MessageManager.cs +++ b/encompass-cs/MessageManager.cs @@ -14,7 +14,7 @@ namespace Encompass internal void AddMessage(TMessage message) where TMessage : struct, IMessage { - messageStore.AddMessage(message); + messageStore.AddMessage(message); } internal void AddMessage(TMessage message, double time) where TMessage : struct, IMessage @@ -51,5 +51,10 @@ namespace Encompass { return messageStore.First(); } + + internal IEnumerable WithEntity(int entityID) where TMessage : struct, IMessage, IHasEntity + { + return messageStore.WithEntity(entityID); + } } } diff --git a/test/EngineTest.cs b/test/EngineTest.cs index e9068d9..7e095dd 100644 --- a/test/EngineTest.cs +++ b/test/EngineTest.cs @@ -415,6 +415,74 @@ namespace Tests Assert.Throws(() => world.Update(0.01f)); } + struct EntityMessage : IMessage, IHasEntity + { + public EntityMessage(Entity entity, int myInt) + { + Entity = entity; + MyInt = myInt; + } + + public Entity Entity { get; } + public int MyInt { get; } + } + + [Sends(typeof(EntityMessage), typeof(MockMessage))] + class EntityMessageEmitterEngine : Engine + { + private Entity _entity; + + public EntityMessageEmitterEngine(Entity entity) + { + _entity = entity; + } + + public override void Update(double dt) + { + SendMessage(new EntityMessage(_entity, 2)); + SendMessage(new EntityMessage(_entity, 4)); + SendMessage(new EntityMessage(_entity, 5)); + SendMessage(new MockMessage()); + } + } + + static List entityMessageResults; + + [Receives(typeof(EntityMessage))] + class EntityMessageReceiverEngine : Engine + { + private Entity _entity; + + public EntityMessageReceiverEngine(Entity entity) + { + _entity = entity; + } + + public override void Update(double dt) + { + entityMessageResults = MessagesWithEntity(_entity).ToList(); + } + } + + [Test] + public void MessagesWithEntity() + { + var worldBuilder = new WorldBuilder(); + + var entity = worldBuilder.CreateEntity(); + worldBuilder.AddEngine(new EntityMessageEmitterEngine(entity)); + worldBuilder.AddEngine(new EntityMessageReceiverEngine(entity)); + + var world = worldBuilder.Build(); + + world.Update(0.01); + + entityMessageResults.Should().HaveCount(3); + entityMessageResults.Should().ContainEquivalentOf(new EntityMessage(entity, 2)); + entityMessageResults.Should().ContainEquivalentOf(new EntityMessage(entity, 4)); + entityMessageResults.Should().ContainEquivalentOf(new EntityMessage(entity, 5)); + } + class SomeComponentTestEngine : Engine { public override void Update(double dt)