/* * Advance all active timers */ public bool Tick() { bool Invalidate = false; foreach (Progression MachineProgression in MachineProgressions.Values) { List <ProgressionSample> Samples = MachineProgression.ProgressionSamples; ProgressionSample Sample = Samples[Samples.Count - 1]; if (Sample.State < EProgressionState.RemoteDisconnected) { Sample.AddTimestamp(DateTime.UtcNow); Invalidate = true; } } return(Invalidate); }
/* * Process a state change timing event */ public bool ProcessEvent(ProgressionEvent Event) { // Overall progress info if (Event.State < EProgressionState.Idle) { switch (Event.State) { case EProgressionState.TaskTotal: NumTasks = Event.ThreadNum; break; case EProgressionState.TasksCompleted: NumRetiredTasks = Event.ThreadNum; break; case EProgressionState.TasksInProgress: NumRunningTasks = Event.ThreadNum; break; } return(true); } // Handle per machine stats Progression MachineProgression = null; if (!MachineProgressions.TryGetValue(Event.Machine, out MachineProgression)) { MachineProgressions.Add(Event.Machine, new Progression()); MachineProgressions.TryGetValue(Event.Machine, out MachineProgression); } List <ProgressionSample> Samples = MachineProgression.ProgressionSamples; ProgressionSample LastSample = Samples[Samples.Count - 1]; // If this machine has disconnected, ignore any further messages if (LastSample.State >= EProgressionState.RemoteDisconnected) { return(true); } // Coarse tracking on a per machine basis bool bCreateNewSample = (LastSample.State != Event.State) || (Event.ThreadNum >= 0 && LastSample.ThreadSamples == null) || (Event.ThreadNum < 0 && LastSample.ThreadSamples != null); if (bCreateNewSample == false) { // Just updating the same event, add timestamp LastSample.AddTimestamp(Event.Time); } else { // If the previous sample have proper Start and End timestamps, add one if (LastSample.NumTimestamps <= 1) { LastSample.AddTimestamp(Event.Time); } // If the previous sample has individual thread samples, make sure they're all ended if ((LastSample.ThreadSamples != null) && (LastSample.ThreadSamples.Count > 0)) { foreach (ProgressionThreadSample NextThreadSample in LastSample.ThreadSamples) { if (NextThreadSample.NumTimestamps <= 1) { NextThreadSample.AddTimestamp(Event.Time); } } } } if (Event.ThreadNum < 0) { if (bCreateNewSample) { Samples.Add(new ProgressionSample(Event.State, Event.Time)); } } else if (Event.ThreadNum >= 0) { if (bCreateNewSample) { // Previous sample was of a different kind, so create a new per-thread instance. LastSample = new ProgressionSample(Event.State, Event.Time); LastSample.ThreadSamples = new List <ProgressionThreadSample>(); Samples.Add(LastSample); } // Optional more detailed per thread tracking while (LastSample.ThreadSamples.Count <= Event.ThreadNum) { List <ProgressionThreadSample> ThreadSamples = new List <ProgressionThreadSample>(); ProgressionThreadSample ThreadSample = new ProgressionThreadSample(Event.State); LastSample.ThreadSamples.Add(ThreadSample); } LastSample.ThreadSamples[Event.ThreadNum].AddTimestamp(Event.Time); } // If we've had a disconnect message, make sure all progressions are terminated if (Event.State == EProgressionState.InstigatorDisconnected) { Samples.Add(new ProgressionSample(Event.State, Event.Time)); // Make sure all progress bars stop as there will be no more messages foreach (Progression ProgressionMachine in MachineProgressions.Values) { List <ProgressionSample> ProgressionSamples = ProgressionMachine.ProgressionSamples; LastSample = ProgressionSamples[ProgressionSamples.Count - 1]; if (LastSample.State < EProgressionState.RemoteDisconnected) { ProgressionSamples.Add(new ProgressionSample(EProgressionState.RemoteDisconnected, Event.Time)); } } return(true); } return(bCreateNewSample); }