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 }