using CodexPlugin.OverwatchSupport; using Logging; using OverwatchTranscript; using TranscriptAnalysis.Receivers; namespace TranscriptAnalysis { public interface IEventReceiver { void Init(ILog log, OverwatchCodexHeader header); void Finish(); } public interface IEventReceiver : IEventReceiver { void Receive(ActivateEvent @event); } public class ReceiverSet { private readonly ILog log; private readonly ITranscriptReader reader; private readonly OverwatchCodexHeader header; private readonly List receivers = new List(); public ReceiverSet(ILog log, ITranscriptReader reader, OverwatchCodexHeader header) { this.log = log; this.reader = reader; this.header = header; } public void InitAll() { Add(new LogReplaceReceiver()); Add(new DuplicateBlocksReceived()); Add(new NodesDegree()); } public void FinishAll() { foreach (var r in receivers) { r.Finish(); } receivers.Clear(); } private void Add(IEventReceiver receiver) { var mux = GetMux(); mux.Add(receiver); receivers.Add(receiver); receiver.Init(log, header); } // We use a mux here because, for each time we call reader.AddEventHandler, // The reader will perform one separate round of JSON deserialization. // TODO: Move the mux into the reader. private readonly Dictionary muxes = new Dictionary(); private IEventMux GetMux() { var typeName = typeof(T).FullName; if (string.IsNullOrEmpty(typeName)) throw new Exception("A!"); if (!muxes.ContainsKey(typeName)) { muxes.Add(typeName, new EventMux(reader)); } return muxes[typeName]; } } public interface IEventMux { void Add(IEventReceiver receiver); } public class EventMux : IEventMux { private readonly List> receivers = new List>(); public EventMux(ITranscriptReader reader) { reader.AddEventHandler(Handle); } public void Add(IEventReceiver receiver) { if (receiver is IEventReceiver r) { receivers.Add(r); } } public void Handle(ActivateEvent @event) { foreach (var r in receivers) r.Receive(@event); } } }