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 }