using System.Collections.Generic; namespace Encompass { internal abstract class TypedMessageStore { public abstract void ProcessDelayedMessages(double dilatedDelta, double realtimeDelta); public abstract void Clear(); } internal class TypedMessageStore : TypedMessageStore where TMessage : struct, IMessage { 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) { for (int i = delayedStore.Count - 1; i >= 0; i--) { var (message, time) = delayedStore[i]; var updatedTime = time - dilatedDelta; if (updatedTime <= 0) { Add(message); delayedStore.RemoveAt(i); } else { delayedStore[i] = (message, updatedTime); } } for (int i = delayedStoreIgnoringTimeDilation.Count - 1; i >= 0; i--) { var (message, time) = delayedStoreIgnoringTimeDilation[i]; var updatedTime = time - realtimeDelta; if (updatedTime <= 0) { Add(message); delayedStoreIgnoringTimeDilation.RemoveAt(i); } else { delayedStoreIgnoringTimeDilation[i] = (message, updatedTime); } } } 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) { delayedStore.Add((message, time)); } public void AddIgnoringTimeDilation(TMessage message, double time) { delayedStoreIgnoringTimeDilation.Add((message, time)); } public TMessage First() { return store[0]; } public bool Any() { return store.Count > 0; } public IEnumerable All() { return store; } public IEnumerable WithEntity(int entityID) { return entityToMessage.ContainsKey(entityID) ? entityToMessage[entityID] : System.Linq.Enumerable.Empty(); } public bool SomeWithEntity(int entityID) { return entityToMessage.ContainsKey(entityID) && entityToMessage[entityID].Count > 0; } public override void Clear() { store.Clear(); foreach (var set in entityToMessage.Values) { set.Clear(); } } } }