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 (var 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 (var 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(); } } } }