public CompetitionClassModel ChangeRunResult(CompetitionRunResult runResult) { Guard.NotNull(runResult, nameof(runResult)); var newResults = new List <CompetitionRunResult>(); bool found = false; foreach (CompetitionRunResult result in Results) { if (result.Competitor.Number == runResult.Competitor.Number) { newResults.Add(runResult); found = true; } else { newResults.Add(result); } } if (!found) { throw new KeyNotFoundException($"No competitor found with number {runResult.Competitor.Number}"); } var newResultList = new ReadOnlyCollection <CompetitionRunResult>(newResults); return(new CompetitionClassModel(newResultList, ClassInfo, LastCompletedCompetitorNumber, IntermediateTimerCount, StartFinishMinDelayForSingleSensor, Alerts)); }
private static Dictionary <int, CompetitionRunResult> ImportRunResultsFrom(string path) { DateTime currentTimeUtc = SystemContext.UtcNow(); var imported = new Dictionary <int, CompetitionRunResult>(); using var textReader = new StreamReader(path); var settings = new DelimitedValuesReaderSettings { Culture = Settings.Default.ImportExportCulture }; using var valuesReader = new DelimitedValuesReader(textReader, settings); AssertRequiredColumnsExist(valuesReader); bool hasOptionalColumns = ContainsOptionalColumnNames(valuesReader); foreach (IDelimitedValuesReaderRow row in valuesReader) { try { CompetitionRunResult runResult = GetRunResultFrom(row, hasOptionalColumns, currentTimeUtc); imported[runResult.Competitor.Number] = runResult; } catch (Exception ex) { throw new Exception($"Failed to read import file at row {valuesReader.LineNumber}: {ex.Message}", ex); } } return(imported); }
public RankingChangeEventArgs([NotNull] [ItemNotNull] IReadOnlyCollection<CompetitionRunResult> rankings, [CanBeNull] CompetitionRunResult previousRunResult) { Guard.NotNull(rankings, nameof(rankings)); Rankings = rankings; PreviousRunResult = previousRunResult; }
private static CompetitionRunResult CreateCompetitorForCompletion(bool hasFinished, bool isEliminated) { var result = new CompetitionRunResult(new Competitor(1, "A", "A")); if (isEliminated) { result = result.ChangeIsEliminated(true); } if (hasFinished) { result = result.ChangeTimings(new CompetitionRunTimings( new RecordedTimeBuilder() .At(TimeSpan.FromSeconds(10)).Build()) .ChangeFinishTime(new RecordedTimeBuilder() .At(TimeSpan.FromSeconds(25)).Build())); } return result; }
public IEnumerable <CompetitionRunResult> ImportFrom(string path, bool mergeDeletes, bool skipTimings) { Guard.NotNullNorEmpty(path, nameof(path)); var mergeRunResults = new List <CompetitionRunResult>(); Dictionary <int, CompetitionRunResult> importRunResults = ImportRunResultsFrom(path); foreach (CompetitionRunResult existingRunResult in existingRunResults) { if (importRunResults.ContainsKey(existingRunResult.Competitor.Number)) { // Merge action: Content merge CompetitionRunResult importRunResult = importRunResults[existingRunResult.Competitor.Number]; CompetitionRunResult mergeRunResult = Merge(existingRunResult, importRunResult, skipTimings); mergeRunResults.Add(mergeRunResult); importRunResults.Remove(existingRunResult.Competitor.Number); } else { if (mergeDeletes) { // Merge action: Delete } else { // Merge action: None mergeRunResults.Add(existingRunResult); } } } // Merge action: Add mergeRunResults.AddRange(importRunResults.Select(importRunResult => importRunResult.Value)); return(mergeRunResults); }
private static CompetitionRunResult CreateCompetitorForPenaltyOverrun(bool penaltyTimeIsGreater, bool overrunTimeIsGreater) { TimeSpan overrunTime = overrunTimeIsGreater ? HighOverrunTime : LowOverrunTime; TimeSpan penaltyTime = penaltyTimeIsGreater ? HighPenaltyTime : LowPenaltyTime; var result = new CompetitionRunResult(new Competitor(1, "A", "A")); TimeSpan startTime = TimeSpan.FromSeconds(10); result = result.ChangeTimings(new CompetitionRunTimings( new RecordedTimeBuilder() .At(startTime).Build()) .ChangeFinishTime(new RecordedTimeBuilder() .At(startTime + overrunTime + StandardCourseTime).Build())); int fr = (int) (penaltyTime - overrunTime).TotalSeconds; result = result.ChangeFaultCount(fr); return result; }
private static bool RunResultsAreEqual(CompetitionRunResult first, CompetitionRunResult second) { return(EqualitySupport.EqualsWithNulls(first.Timings, second.Timings, FinishTimesAreEqual) && first.FaultCount == second.FaultCount && first.RefusalCount == second.RefusalCount && first.IsEliminated == second.IsEliminated); }
private static bool CompetitorsAreEqual(CompetitionRunResult first, CompetitionRunResult second) { return(first.Competitor == second.Competitor); }
private static bool CompetitorRunResultsAreEqual(CompetitionRunResult first, CompetitionRunResult second) { return(CompetitorsAreEqual(first, second) && RunResultsAreEqual(first, second)); }
private static CompetitionRunResult Merge(CompetitionRunResult existing, CompetitionRunResult imported, bool skipTimings) { return(skipTimings ? existing.ChangeCompetitor(imported.Competitor) : MergeWithTimings()); }
public CompetitorAssessmentCalculator([NotNull] CompetitionRunResult competitor, [NotNull] CompetitionClassModel modelSnapshot) { Guard.NotNull(competitor, nameof(competitor)); Guard.NotNull(modelSnapshot, nameof(modelSnapshot)); this.competitor = competitor; this.modelSnapshot = modelSnapshot; }
private void AcceptButton_Click([CanBeNull] object sender, [NotNull] EventArgs e) { if (ParentForm == null || HasValidationErrors) { return; } CompetitionRunResult originalRunVersionNotNull = AssertOriginalRunVersionNotNull(); CompetitionRunResult newRunVersion = originalRunVersionNotNull.ChangeTimings(ConvertFinishTimeFromScreen(true)) .ChangeFaultCount(ConvertFaultCountFromScreen()) .ChangeRefusalCount(ConvertRefusalCountFromScreen()) .ChangeIsEliminated(ConvertEliminatedFromScreen()); var changingEventArgs = new RunResultChangingEventArgs(originalRunVersionNotNull, newRunVersion); RunResultChanging?.Invoke(this, changingEventArgs); if (changingEventArgs.ErrorMessage == null) { ShowAnimatedSuccess("Competitor updated."); originalRunVersion = CacheManager.DefaultInstance.ActiveModel.GetRunResultFor(newRunVersion.Competitor.Number); RunResultChanged?.Invoke(this, EventArgs.Empty); } else { ShowAnimatedFailure(changingEventArgs.ErrorMessage); } }
public void OverwriteWith([CanBeNull] CompetitionRunResult runResult) { originalRunVersion = runResult; CopyValuesFrom(runResult); }
void IVisualizationActor.SetOrClearPreviousCompetitorRun(CompetitionRunResult competitorRunResult) { builder.WithPreviousPlacement(competitorRunResult?.Placement ?? CirceHiddenPlacement); }
private static CompetitionRunResult CreateCompetitorForFinishWithNumber(bool finishTimeIsGreater, bool competitorNumberIsGreater) { int competitorNumber = competitorNumberIsGreater ? HighCompetitorNumber : LowCompetitorNumber; TimeSpan finishTime = TimeSpan.FromSeconds(finishTimeIsGreater ? 50 : 25); var result = new CompetitionRunResult(new Competitor(competitorNumber, "A", "A")); TimeSpan startTime = TimeSpan.FromSeconds(10); result = result.ChangeTimings(new CompetitionRunTimings( new RecordedTimeBuilder() .At(startTime).Build()) .ChangeFinishTime(new RecordedTimeBuilder() .At(startTime + finishTime).Build())); return result; }
private static void SetTimeElapsedSinceStart(IDelimitedValuesWriterRow row, string columnName, CompetitionRunResult runResult, RecordedTime?time) { TimeSpanWithAccuracy?elapsed = GetElapsedSinceStart(runResult.Timings, time); if (elapsed != null) { row.SetCell(columnName, elapsed.Value); } }
private static CompetitionRunResult GetRunResultFrom([NotNull] IDelimitedValuesReaderRow row, bool hasOptionalColumns, DateTime startTimeUtc) { Competitor competitor = GetCompetitorFrom(row); var runResult = new CompetitionRunResult(competitor); if (hasOptionalColumns) { var faultCount = row.GetCell<int?>(ImportExportColumns.FaultCount); var refusalCount = row.GetCell<int?>(ImportExportColumns.RefusalCount); var isEliminated = row.GetCell<bool?>(ImportExportColumns.IsEliminated); // Note: We cannot reconstruct whether start time was high precision, because it does not roundtrip // through import/export. However, we do not need to know. A low-precision elapsed time is caused by // either one or both times to be low precision. So although we lost some information, the nett effect // when the precision of an elapsed time is recalculated will be the same as long as we assume that the start // time was high precision. var startTime = new RecordedTime(TimeSpan.Zero, startTimeUtc); RecordedTime intermediateTime1 = GetTimeElapsedSinceStart(row, ImportExportColumns.IntermediateTime1, startTime); RecordedTime intermediateTime2 = GetTimeElapsedSinceStart(row, ImportExportColumns.IntermediateTime2, startTime); RecordedTime intermediateTime3 = GetTimeElapsedSinceStart(row, ImportExportColumns.IntermediateTime3, startTime); RecordedTime finishTime = GetTimeElapsedSinceStart(row, ImportExportColumns.FinishTime, startTime); if (intermediateTime1 == null && intermediateTime2 == null && intermediateTime3 == null && finishTime == null) { startTime = null; } bool runCompleted = finishTime != null || (isEliminated != null && isEliminated.Value); if (runCompleted) { if (faultCount != null) { runResult = runResult.ChangeFaultCount(faultCount.Value); } if (refusalCount != null) { runResult = runResult.ChangeRefusalCount(refusalCount.Value); } if (isEliminated != null) { runResult = runResult.ChangeIsEliminated(isEliminated.Value); } if (startTime != null) { runResult = runResult.ChangeTimings( new CompetitionRunTimings(startTime).ChangeIntermediateTime1(intermediateTime1) .ChangeIntermediateTime2(intermediateTime2) .ChangeIntermediateTime3(intermediateTime3) .ChangeFinishTime(finishTime)); } } } return runResult; }
private CompetitionRunResultRowInGrid([NotNull] CompetitionRunResult original, [NotNull] string handlerName, [NotNull] string dogName) { Guard.NotNull(original, nameof(original)); Guard.NotNullNorEmpty(handlerName, nameof(handlerName)); Guard.NotNullNorEmpty(dogName, nameof(dogName)); this.original = original; HandlerName = handlerName; DogName = dogName; PlacementText = string.Empty; }
void IVisualizationActor.SetOrClearPreviousCompetitorRun(CompetitionRunResult competitorRunResult) { if (competitorRunResult != null) { prevCompetitorNumberLabel.Text = TextFormatting.FormatCompetitorNumber(competitorRunResult.Competitor.Number); prevTimeLabel.Text = TextFormatting.FormatTime( competitorRunResult.Timings?.FinishTime?.ElapsedSince(competitorRunResult.Timings.StartTime) .TimeValue); prevFaultsValueLabel.Text = TextFormatting.FormatNumber(competitorRunResult.FaultCount, 2); prevRefusalsValueLabel.Text = TextFormatting.FormatNumber(competitorRunResult.RefusalCount, 2); Color foreColor = competitorRunResult.IsEliminated ? RunHistoryLine.EliminationColor : SystemColors.ControlText; prevTimeLabel.ForeColor = foreColor; prevPlacementLabel.ForeColor = foreColor; prevPlacementLabel.Text = competitorRunResult.IsEliminated ? @"X" : TextFormatting.FormatPlacement(competitorRunResult.Placement); } else { prevCompetitorNumberLabel.Text = string.Empty; prevTimeLabel.Text = string.Empty; prevFaultsValueLabel.Text = string.Empty; prevRefusalsValueLabel.Text = string.Empty; prevPlacementLabel.Text = string.Empty; } }
private static CompetitionRunResult CreateCompetitorFor([NotNull] string name, bool hasFinished, bool isEliminated, bool otherHasFinished, bool penaltyTimeIsGreater, bool overrunTimeIsGreater, bool otherPenaltyTimeIsGreater, bool otherOverrunTimeIsGreater, bool finishTimeIsGreater, bool competitorNumberIsGreater, bool otherFinishTimeIsGreater, bool otherCompetitorNumberIsGreater) { int competitorNumber = !competitorNumberIsGreater && !otherCompetitorNumberIsGreater ? LowOrSameCompetitorNumber : (competitorNumberIsGreater ? HighCompetitorNumber : LowOrSameCompetitorNumber); var result = new CompetitionRunResult(new Competitor(competitorNumber, name, name)); if (isEliminated) { result = result.ChangeIsEliminated(true); } if (hasFinished) { bool requireSameOverrunTime = !overrunTimeIsGreater && !otherOverrunTimeIsGreater; TimeSpan overrunTime = requireSameOverrunTime ? (!otherHasFinished ? TimeSpan.Zero : LowOrSameOverrunTime) : overrunTimeIsGreater ? HighOverrunTime : LowOrSameOverrunTime; bool requireSamePenaltyTime = !penaltyTimeIsGreater && !otherPenaltyTimeIsGreater; TimeSpan penaltyTime = requireSamePenaltyTime ? (!otherHasFinished ? TimeSpan.Zero : LowOrSamePenaltyTime) : penaltyTimeIsGreater ? HighPenaltyTime : LowOrSamePenaltyTime; bool requireSameFinishTime = !finishTimeIsGreater && !otherFinishTimeIsGreater; TimeSpan extraFinishTime = requireSameFinishTime ? (!otherHasFinished ? TimeSpan.Zero : LowOrSameExtraFinishTime) : finishTimeIsGreater ? HighExtraFinishTime : LowOrSameExtraFinishTime; TimeSpan startTime = TimeSpan.FromSeconds(10); TimeSpan finishTimeAbsolute = startTime + overrunTime + extraFinishTime; if (!otherHasFinished && (requireSameFinishTime || requireSameOverrunTime) && !overrunTimeIsGreater) { // Other has not finished, but finish times must be the same. } else if (otherHasFinished && (finishTimeIsGreater || otherFinishTimeIsGreater) && requireSameOverrunTime) { // Both finished, but overrun times must be the same. } else { finishTimeAbsolute += StandardCourseTime; } result = result.ChangeTimings(new CompetitionRunTimings( new RecordedTimeBuilder() .At(startTime).Build()) .ChangeFinishTime(new RecordedTimeBuilder() .At(finishTimeAbsolute).Build())); TimeSpan finishTimeElapsed = finishTimeAbsolute - startTime; TimeSpan actualOverrunTime = finishTimeElapsed > StandardCourseTime ? finishTimeElapsed - StandardCourseTime : TimeSpan.Zero; int fr = (int) (penaltyTime - actualOverrunTime).TotalSeconds; int refusals = GetRefusalsFor(fr, isEliminated); result = result.ChangeRefusalCount(refusals); int faults = fr - refusals; result = new FakeCompetitionRunResult(result, faults); } return result; }
private static CompetitionRunResult GetRunResultFrom(IDelimitedValuesReaderRow row, bool hasOptionalColumns, DateTime startTimeUtc) { Competitor competitor = GetCompetitorFrom(row); var runResult = new CompetitionRunResult(competitor); if (hasOptionalColumns) { int? faultCount = row.GetCell <int?>(ImportExportColumns.FaultCount); int? refusalCount = row.GetCell <int?>(ImportExportColumns.RefusalCount); bool?isEliminated = row.GetCell <bool?>(ImportExportColumns.IsEliminated); // Note: We cannot reconstruct whether start time was high precision, because it does not roundtrip // through import/export. However, we do not need to know. A low-precision elapsed time is caused by // either one or both times to be low precision. So although we lost some information, the nett effect // when the precision of an elapsed time is recalculated will be the same as long as we assume that the start // time was high precision. var startTime = new RecordedTime(TimeSpan.Zero, startTimeUtc); RecordedTime?intermediateTime1 = GetTimeElapsedSinceStart(row, ImportExportColumns.IntermediateTime1, startTime); RecordedTime?intermediateTime2 = GetTimeElapsedSinceStart(row, ImportExportColumns.IntermediateTime2, startTime); RecordedTime?intermediateTime3 = GetTimeElapsedSinceStart(row, ImportExportColumns.IntermediateTime3, startTime); RecordedTime?finishTime = GetTimeElapsedSinceStart(row, ImportExportColumns.FinishTime, startTime); if (intermediateTime1 == null && intermediateTime2 == null && intermediateTime3 == null && finishTime == null) { startTime = null; } bool runCompleted = finishTime != null || (isEliminated != null && isEliminated.Value); if (runCompleted) { if (faultCount != null) { runResult = runResult.ChangeFaultCount(faultCount.Value); } if (refusalCount != null) { runResult = runResult.ChangeRefusalCount(refusalCount.Value); } if (isEliminated != null) { runResult = runResult.ChangeIsEliminated(isEliminated.Value); } if (startTime != null) { // @formatter:keep_existing_linebreaks true runResult = runResult .ChangeTimings(new CompetitionRunTimings(startTime) .ChangeIntermediateTime1(intermediateTime1) .ChangeIntermediateTime2(intermediateTime2) .ChangeIntermediateTime3(intermediateTime3) .ChangeFinishTime(finishTime)); // @formatter:keep_existing_linebreaks restore } } } return(runResult); }