/ Framework / OverwatchTranscript / MomentReader.cs
MomentReader.cs
  1  using Newtonsoft.Json;
  2  
  3  namespace OverwatchTranscript
  4  {
  5      public class MomentReader
  6      {
  7          private readonly OverwatchTranscript model;
  8          private readonly string workingDir;
  9          private int referenceIndex = 0;
 10          private int momentsRead = 0;
 11          private OpenReference currentRef;
 12  
 13          public MomentReader(OverwatchTranscript model, string workingDir)
 14          {
 15              this.model = model;
 16              this.workingDir = workingDir;
 17  
 18              currentRef = CreateOpenReference();
 19          }
 20  
 21          public OverwatchMoment? Next()
 22          {
 23              if (referenceIndex >= model.MomentReferences.Length) return null;
 24  
 25              var moment = currentRef.ReadNext();
 26              if (moment == null)
 27              {
 28                  Close();
 29  
 30                  // This reference file ran out.
 31                  // The number of moments read should match exactly the number of moments
 32                  // describe in the reference. If not, error:
 33                  var expected = model.MomentReferences[referenceIndex].NumberOfMoments;
 34                  if (momentsRead != expected)
 35                  {
 36                      throw new Exception("Number of moments read from referenced file does not match number of moments value in model. " +
 37                          $"Reads: { momentsRead} - model.MomentReferences[{referenceIndex}].NumberOfMoment: {expected}"); 
 38                  }
 39  
 40                  referenceIndex++;
 41                  if (referenceIndex < model.MomentReferences.Length)
 42                  {
 43                      // Proceed to next reference file.
 44                      currentRef = CreateOpenReference();
 45                      momentsRead = 0;
 46                      return Next();
 47                  }
 48                  else
 49                  {
 50                      // That was the last one.
 51                      return null;
 52                  }
 53              }
 54              else
 55              {
 56                  momentsRead++;
 57                  return moment;
 58              }
 59          }
 60  
 61          public void Close()
 62          {
 63              if (currentRef != null)
 64              {
 65                  currentRef.Close();
 66                  currentRef = null!;
 67              }
 68          }
 69  
 70          private OpenReference CreateOpenReference()
 71          {
 72              var filepath = Path.Combine(workingDir, model.MomentReferences[referenceIndex].MomentsFile);
 73              return new OpenReference(filepath);
 74          }
 75  
 76          private class OpenReference
 77          {
 78              private readonly FileStream file;
 79              private readonly StreamReader reader;
 80  
 81              public OpenReference(string filePath)
 82              {
 83                  file = File.OpenRead(filePath);
 84                  reader = new StreamReader(file);
 85              }
 86  
 87              public OverwatchMoment? ReadNext()
 88              {
 89                  var line = reader.ReadLine();
 90                  if (string.IsNullOrEmpty(line)) return null;
 91                  return JsonConvert.DeserializeObject<OverwatchMoment>(line);
 92              }
 93  
 94              public void Close()
 95              {
 96                  reader.Close();
 97                  file.Close();
 98  
 99                  reader.Dispose();
100                  file.Dispose();
101              }
102          }
103      }
104  }