public Run(int splitCount) { if (splitCount < 1) throw new ArgumentOutOfRangeException("Runs must contain at least one split."); Splits = new Split[splitCount]; CurrentSplit = 0; IsStarted = false; }
public static bool IsGoldSplit(Split currentSplit, Split referenceSplit) { if (currentSplit == null || referenceSplit == null) return false; return currentSplit.IsWellBounded && currentSplit.Time < referenceSplit.Time; }
public static bool? IsFasterTotalTime(Split currentSplit, Split referenceSplit) { if (currentSplit == null || referenceSplit == null) return null; if (!currentSplit.IsPrecise || !referenceSplit.IsPrecise) return null; return currentSplit.TimeFromRunStart < referenceSplit.TimeFromRunStart; }
public SplitRowDisplay(string name, Split pbSplit, Split goldSplit) { Name = name; GoldSplit = goldSplit; this.PropertyChanged += (sender, e) => { //Only adjust display based on changing splits if (e.PropertyName == "PersonalBestSplit" || e.PropertyName == "GoldSplit" || e.PropertyName == "CurrentRunSplit") { IsNewGoldSplit = Split.IsGoldSplit(CurrentRunSplit, GoldSplit); IsAheadOfPb = Split.IsFasterTotalTime(CurrentRunSplit, PersonalBestSplit); var displaySetter = "[??]"; var goldDisplaySetter = "[??]"; var pbOffsetSetter = "[??]"; var goldOffsetSetter = "[??]"; //If splits have changed, set Display accordingly if (CurrentRunSplit == null) { //When current split is null, only the default pb times can be displayed if (PersonalBestSplit.IsPrecise) { displaySetter = Timer.FormatElapsedTimeSpan(PersonalBestSplit.TimeFromRunStart); } if (GoldSplit.IsWellBounded) { goldDisplaySetter = Timer.FormatElapsedTimeSpan(GoldSplit.TimeFromRunStart); } } else { if (CurrentRunSplit.IsPrecise && PersonalBestSplit.IsPrecise) { //If both splits are precise, we can display a time differential var pbTime = PersonalBestSplit.TimeFromRunStart; var curTime = CurrentRunSplit.TimeFromRunStart; displaySetter = Timer.FormatTimeDifferential(curTime.Subtract(pbTime)); } else if (CurrentRunSplit.IsPrecise) { //If only the current display is precise, we can at least show the current run time displaySetter = Timer.FormatElapsedTimeSpan(CurrentRunSplit.TimeFromRunStart); } if (CurrentRunSplit.IsWellBounded && GoldSplit.SplitInfo != SplitTimeSpan.Unknown) { //If both current split and gold split are well bounded, we can show gold split differential goldOffsetSetter = Timer.FormatTimeDifferential(CurrentRunSplit.Time.Subtract(GoldSplit.Time)); } if (CurrentRunSplit.IsWellBounded && PersonalBestSplit.IsWellBounded) { //If both current split and pb split are well bounded, we can show pb split differential pbOffsetSetter = Timer.FormatTimeDifferential(CurrentRunSplit.Time.Subtract(PersonalBestSplit.Time)); } } Display = displaySetter; GoldDisplay = goldDisplaySetter; PbOffsetDisplay = pbOffsetSetter; GoldOffsetDisplay = goldOffsetSetter; } }; //Write pbSplit after setting up PropertyChanged handler in order to trigger it once PersonalBestSplit = pbSplit; }
public SplitChange(ActionEnum action, Split item, int index) { Action = action; Item = item; Index = index; }
public void Split() { if (!IsStarted) { //If run has not yet started - start it now stopwatch.Start(); StartTime = DateTime.Now; IsStarted = true; OnRunStatusChanged(); } else if (!IsCompleted) { //If first split already exists, add this split to the end var timeSinceStart = TimeSinceStart; //fetch the time for this split before doing any other computing var timeToLastSplit = Splits.Take(CurrentSplit).Aggregate(new TimeSpan(), (accu, s) => accu.Add(s.Time)); var timeSinceLastSplit = timeSinceStart.Subtract(timeToLastSplit); var split = new Split(timeSinceLastSplit, this); Splits[CurrentSplit] = split; CurrentSplit++; OnSplitChanged(new SplitChange(SplitChange.ActionEnum.Added, split, CurrentSplit - 1)); if (IsCompleted) OnRunStatusChanged(); } }
public void SkipSplit() { //A skip split request will not start the run //A skip split request will not work when trying to end the run if (IsStarted && CurrentSplit < (Splits.Length - 1)) { var timeSinceStart = TimeSinceStart; //fetch the time before doing any other computing var timeToLastSplit = Splits.Take(CurrentSplit).Aggregate(new TimeSpan(), (accu, s) => accu.Add(s.Time)); var timeSinceLastSplit = timeSinceStart.Subtract(timeToLastSplit); var split = new Split(timeSinceLastSplit, this, false); Splits[CurrentSplit] = split; CurrentSplit++; OnSplitChanged(new SplitChange(SplitChange.ActionEnum.Added, split, CurrentSplit - 1)); if (IsCompleted) OnRunStatusChanged(); } }