/ Tools / TranscriptAnalysis / ReceiverSet.cs
ReceiverSet.cs
  1  using CodexPlugin.OverwatchSupport;
  2  using Logging;
  3  using OverwatchTranscript;
  4  using TranscriptAnalysis.Receivers;
  5  
  6  namespace TranscriptAnalysis
  7  {
  8      public interface IEventReceiver
  9      {
 10          void Init(string sourceFilename, ILog log, OverwatchCodexHeader header);
 11          void Finish();
 12      }
 13  
 14      public interface IEventReceiver<T> : IEventReceiver
 15      {
 16          void Receive(ActivateEvent<T> @event);
 17      }
 18  
 19      public class ReceiverSet
 20      {
 21          private readonly string sourceFilename;
 22          private readonly ILog log;
 23          private readonly ITranscriptReader reader;
 24          private readonly OverwatchCodexHeader header;
 25          private readonly List<IEventReceiver> receivers = new List<IEventReceiver>();
 26  
 27          public ReceiverSet(string sourceFilename, ILog log, ITranscriptReader reader, OverwatchCodexHeader header)
 28          {
 29              this.sourceFilename = sourceFilename;
 30              this.log = log;
 31              this.reader = reader;
 32              this.header = header;
 33          }
 34  
 35          public void InitAll()
 36          {
 37              Add(new LogReplaceReceiver());
 38              Add(new DuplicateBlocksReceived());
 39              Add(new NodesDegree());
 40          }
 41  
 42          public void FinishAll()
 43          {
 44              foreach (var r in receivers)
 45              {
 46                  r.Finish();
 47              }
 48              receivers.Clear();
 49          }
 50  
 51  
 52          private void Add<T>(IEventReceiver<T> receiver)
 53          {
 54              var mux = GetMux<T>();
 55              mux.Add(receiver);
 56  
 57              receivers.Add(receiver);
 58              receiver.Init(sourceFilename, log, header);
 59          }
 60  
 61          // We use a mux here because, for each time we call reader.AddEventHandler,
 62          // The reader will perform one separate round of JSON deserialization.
 63          // TODO: Move the mux into the reader.
 64          private readonly Dictionary<string, IEventMux> muxes = new Dictionary<string, IEventMux>();
 65          private IEventMux GetMux<T>()
 66          {
 67              var typeName = typeof(T).FullName;
 68              if (string.IsNullOrEmpty(typeName)) throw new Exception("A!");
 69  
 70              if (!muxes.ContainsKey(typeName))
 71              {
 72                  muxes.Add(typeName, new EventMux<T>(reader));
 73              }
 74              return muxes[typeName];
 75          }
 76      }
 77  
 78      public interface IEventMux
 79      {
 80          void Add(IEventReceiver receiver);
 81      }
 82  
 83      public class EventMux<T> : IEventMux
 84      {
 85          private readonly List<IEventReceiver<T>> receivers = new List<IEventReceiver<T>>();
 86  
 87          public EventMux(ITranscriptReader reader)
 88          {
 89              reader.AddEventHandler<T>(Handle);
 90          }
 91  
 92          public void Add(IEventReceiver receiver)
 93          {
 94              if (receiver is IEventReceiver<T> r)
 95              {
 96                  receivers.Add(r);
 97              }
 98          }
 99  
100          public void Handle(ActivateEvent<T> @event)
101          {
102              foreach (var r in receivers) r.Receive(@event);
103          }
104      }
105  }