public ClassSetupForm() { InitializeComponent(); allChildControls = new Lazy<IEnumerable<Control>>(() => this.GetAllChildControlsRecursive().ToList()); originalVersion = CacheManager.DefaultInstance.ActiveModel; }
public int?GetBestNextCompetitorNumberOrNull(int?currentCompetitorNumber) { if (currentCompetitorNumber != null) { CompetitionClassModel snapshotSorted = GetSortedAscendingByCompetitorNumber(); // @formatter:keep_existing_linebreaks true CompetitionRunResult?firstUncompletedCompetitorAfterCurrent = snapshotSorted.Results .SkipWhile(r => r.Competitor.Number != currentCompetitorNumber.Value) .Skip(1) .SkipWhile(r => r.HasCompleted) .FirstOrDefault(); // @formatter:keep_existing_linebreaks restore if (firstUncompletedCompetitorAfterCurrent != null) { return(firstUncompletedCompetitorAfterCurrent.Competitor.Number); } CompetitionRunResult?firstUncompletedCompetitor = snapshotSorted.Results.FirstOrDefault(r => !r.HasCompleted && r.Competitor.Number != currentCompetitorNumber.Value); return(firstUncompletedCompetitor?.Competitor.Number); } return(null); }
public int GetBestStartingCompetitorNumber() { AssertCompetitorsExist(); CompetitionClassModel snapshotSorted = GetSortedAscendingByCompetitorNumber(); CompetitionRunResult?lastCompleted = snapshotSorted.GetLastCompletedOrNull(); if (lastCompleted != null) { // @formatter:keep_existing_linebreaks true CompetitionRunResult?nextUncompletedCompetitor = snapshotSorted.Results .SkipWhile(r => r.Competitor.Number != lastCompleted.Competitor.Number) .Skip(1) .SkipWhile(r => r.HasCompleted) .FirstOrDefault(); // @formatter:keep_existing_linebreaks restore if (nextUncompletedCompetitor != null) { return(nextUncompletedCompetitor.Competitor.Number); } } CompetitionRunResult?firstUncompletedCompetitor = snapshotSorted.Results.FirstOrDefault(r => !r.HasCompleted); return(firstUncompletedCompetitor?.Competitor.Number ?? snapshotSorted.Results.First().Competitor.Number); }
public void RunExploded() { // Arrange var runCompletionScenarios = new List<OrderingScenario> { // Bits: X HasFinished, X IsEliminated, Y HasFinished, Y IsEliminated new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 0, 0), OrderExpect.IsEven), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 0, 1), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 1, 0), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 1, 1), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 0, 0), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 0, 1), OrderExpect.IsEven), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 1, 0), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 1, 1), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 0, 0), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 0, 1), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 1, 0), OrderExpect.IsEven), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 1, 1), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 0, 0), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 0, 1), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 1, 0), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 1, 1), OrderExpect.IsEven) }; var penaltyOverrunScenarios = new List<OrderingScenario> { // Bits: PenaltyTime X > Y, OverrunTime X > Y, PenaltyTime Y > X, OverrunTime Y > X new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 0, 0), OrderExpect.IsEven), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 0, 1), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 1, 0), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 1, 1), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 0, 0), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 0, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 1, 0), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 1, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 0, 0), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 0, 1), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 1, 0), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 1, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 0, 0), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 0, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 1, 0), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 1, 1), OrderExpect.DoNotCare) }; var finishNumberScenarios = new List<OrderingScenario> { // Bits: FinishTime X > Y, CompetitorNumber X > Y, FinishTime Y > X, CompetitorNumber Y > X new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 0, 0), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 0, 1), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 1, 0), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 1, 1), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 0, 0), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 0, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 1, 0), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 1, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 0, 0), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 0, 1), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 1, 0), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 1, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 0, 0), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 0, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 1, 0), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 1, 1), OrderExpect.DoNotCare) }; IEnumerable<OrderingScenario> exploded = ExplodeCombinations(runCompletionScenarios, penaltyOverrunScenarios, finishNumberScenarios); CompetitionClassModel model = new CompetitionClassModel() .ChangeClassInfo(new CompetitionClassInfo() .ChangeStandardCourseTime(StandardCourseTime)); var comparer = new CompetitionRunResultRankingComparer(model, RankingComparisonMode.Regular); foreach (OrderingScenario scenario in exploded) { bool xHasFinished = scenario[0]; bool xIsEliminated = scenario[1]; bool yHasFinished = scenario[2]; bool yIsEliminated = scenario[3]; bool xPenaltyTimeIsGreater = scenario[4]; bool xOverrunTimeIsGreater = scenario[5]; bool yPenaltyTimeIsGreater = scenario[6]; bool yOverrunTimeIsGreater = scenario[7]; bool xFinishTimeIsGreater = scenario[8]; bool xCompetitorNumberIsGreater = scenario[9]; bool yFinishTimeIsGreater = scenario[10]; bool yCompetitorNumberIsGreater = scenario[11]; CompetitionRunResult xCompetitor = CreateCompetitorFor("X", xHasFinished, xIsEliminated, yHasFinished, xPenaltyTimeIsGreater, xOverrunTimeIsGreater, yPenaltyTimeIsGreater, yOverrunTimeIsGreater, xFinishTimeIsGreater, xCompetitorNumberIsGreater, yFinishTimeIsGreater, yCompetitorNumberIsGreater); CompetitionRunResult yCompetitor = CreateCompetitorFor("Y", yHasFinished, yIsEliminated, xHasFinished, yPenaltyTimeIsGreater, yOverrunTimeIsGreater, xPenaltyTimeIsGreater, xOverrunTimeIsGreater, yFinishTimeIsGreater, yCompetitorNumberIsGreater, xFinishTimeIsGreater, xCompetitorNumberIsGreater); AssertCompetitorsAreCompatibleWithProposedScenario(xCompetitor, yCompetitor, scenario, model); // Act int result = comparer.Compare(xCompetitor, yCompetitor); // Assert OrderExpect actual = TranslateComparerResult(result); actual.Should().Be(scenario.Result, scenario.ToString()); } }
private void PersistRunResultToCache() { try { if (currentCompetitorNumber != null) { Competitor existingCompetitor = modelSnapshot.GetRunResultFor(currentCompetitorNumber.Value).Competitor; CompetitionRunResult newRunResult = runData.ToRunResultFor(existingCompetitor); CompetitionClassModel newSnapshot = modelSnapshot.ChangeRunResult(newRunResult) .SafeChangeLastCompletedCompetitorNumber(existingCompetitor.Number) .RecalculatePlacements(); modelSnapshot = CacheManager.DefaultInstance.ReplaceModel(newSnapshot, modelSnapshot); AutoExportRunResults(); } } catch (Exception ex) { int competitorNumber = AssertCurrentCompetitorNumberNotNull(); string message = "Failed to save run results. Please write these down manually, " + $"or press Ctrl+C to copy to clipboard.\n\n{runData.GetMessageFor(competitorNumber)}\n"; Log.Error(message, ex); var exception = new Exception(message, ex); UnknownErrorDuringSave?.Invoke(this, new EventArgs<Exception>(exception)); } }
public void StartClass([NotNull] CompetitionClassRequirements requirements) { Guard.NotNull(requirements, nameof(requirements)); Log.Debug("Entering StartClass."); ExecuteExclusiveIfStateIn(CompetitionClassState.Offline, () => { modelSnapshot = CacheManager.DefaultInstance.ActiveModel; currentCompetitorNumber = modelSnapshot.GetBestStartingCompetitorNumber(); nextCompetitorNumberTyped = null; nextCompetitorNumberGenerated = modelSnapshot.GetBestNextCompetitorNumberOrNull(currentCompetitorNumber); classRequirements = requirements; runData.Reset(false); SetState(CompetitionClassState.SetupCompleted); using (var collector = new VisualizationUpdateCollector(visualizer)) { collector.Include(VisualizationChangeFactory.ClearAll()); collector.Include(new ClassInfoUpdate(modelSnapshot.ClassInfo)); UpdateCurrentCompetitorVisualization(collector); UpdateNextCompetitorVisualization(collector); CompetitionRunResult previousCompetitorOrNull = modelSnapshot.GetLastCompletedOrNull(); collector.Include(new PreviousCompetitorRunUpdate(previousCompetitorOrNull)); IReadOnlyCollection<CompetitionRunResult> rankings = modelSnapshot.FilterCompletedAndSortedAscendingByPlacement().Results; collector.Include(new RankingsUpdate(rankings)); } }); }
public string TryUpdateRunResult([NotNull] CompetitionRunResult originalRunVersion, [NotNull] CompetitionRunResult newRunVersion) { Guard.NotNull(originalRunVersion, nameof(originalRunVersion)); Guard.NotNull(newRunVersion, nameof(newRunVersion)); string result = null; ExecuteExclusiveIfStateIn(AllStates, () => { // Assumptions: // 1] When class is started, underlying cache can never be changed from the outside. // 2] When no run active (state Offline), we are not in control of underlying cache // (so snapshot field should not be read because it is likely outdated). CompetitionClassModel activeModelVersion = classState == CompetitionClassState.Offline ? CacheManager.DefaultInstance.ActiveModel : modelSnapshot; CompetitionRunResult activeRunVersion = activeModelVersion.GetRunResultOrNull(originalRunVersion.Competitor.Number); if (activeRunVersion == null) { result = "Competitor not found"; return; } if (!CompetitionRunResult.AreEquivalent(activeRunVersion, originalRunVersion)) { result = "Competitor changed in-between"; return; } if (classState != CompetitionClassState.Offline && currentCompetitorNumber == newRunVersion.Competitor.Number) { result = "Competitor is running"; return; } CompetitionClassModel newSnapshot = activeModelVersion.ChangeRunResult(newRunVersion).RecalculatePlacements(); modelSnapshot = CacheManager.DefaultInstance.ReplaceModel(newSnapshot, activeModelVersion); AutoExportRunResults(); if (classState != CompetitionClassState.Offline) { using (var collector = new VisualizationUpdateCollector(visualizer)) { IReadOnlyCollection<CompetitionRunResult> rankings = modelSnapshot.FilterCompletedAndSortedAscendingByPlacement().Results; collector.Include(new RankingsUpdate(rankings)); if (newRunVersion.Competitor.Number == modelSnapshot.LastCompletedCompetitorNumber) { CompetitionRunResult previousCompetitorOrNull = modelSnapshot.GetLastCompletedOrNull(); collector.Include(new PreviousCompetitorRunUpdate(previousCompetitorOrNull)); } } } }); return result; }
public CompetitionClassController([NotNull] Func<NetworkHealthReport> healthNeededCallback, [NotNull] ClockSynchronizationMonitor clockSynchronizationMonitor, [NotNull] ICompetitionRunVisualizer runVisualizer) { Guard.NotNull(healthNeededCallback, nameof(healthNeededCallback)); Guard.NotNull(clockSynchronizationMonitor, nameof(clockSynchronizationMonitor)); Guard.NotNull(runVisualizer, nameof(runVisualizer)); networkHealthNeededCallback = healthNeededCallback; synchronizationMonitor = clockSynchronizationMonitor; visualizer = runVisualizer; clockSynchronizationMonitor.SyncRecommended += ClockSynchronizationMonitorOnSyncRecommended; clockSynchronizationMonitor.SyncRequired += ClockSynchronizationMonitorOnSyncRequired; clockSynchronizationMonitor.SyncCompleted += ClockSynchronizationMonitorOnSyncCompleted; runData.EliminationTracker.EliminationChanged += EliminationTrackerOnEliminationChanged; runData.EliminationTracker.RefusalCountChanged += EliminationTrackerOnRefusalCountChanged; modelSnapshot = CacheManager.DefaultInstance.ActiveModel; }
private void ApplyModelChange([NotNull] CompetitionClassModel newVersion) { originalVersion = CacheManager.DefaultInstance.ReplaceModel(newVersion, originalVersion); }
public CompetitorAssessmentCalculator([NotNull] CompetitionRunResult competitor, [NotNull] CompetitionClassModel modelSnapshot) { Guard.NotNull(competitor, nameof(competitor)); Guard.NotNull(modelSnapshot, nameof(modelSnapshot)); this.competitor = competitor; this.modelSnapshot = modelSnapshot; }
public void PenaltyOverrun2() { // Arrange var scenarios = new List<OrderingScenario> { // Bits: PenaltyTime X > Y, OverrunTime X > Y, PenaltyTime Y > X, OverrunTime Y > X new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 0, 0), OrderExpect.IsEven), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 0, 1), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 1, 0), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 0, 1, 1), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 0, 0), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 0, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 1, 0), OrderExpect.WinnerIsX), new OrderingScenario(4, OrderingScenario.FromBits(0, 1, 1, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 0, 0), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 0, 1), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 1, 0), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 0, 1, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 0, 0), OrderExpect.WinnerIsY), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 0, 1), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 1, 0), OrderExpect.DoNotCare), new OrderingScenario(4, OrderingScenario.FromBits(1, 1, 1, 1), OrderExpect.DoNotCare) }; CompetitionClassModel model = new CompetitionClassModel() .ChangeClassInfo(new CompetitionClassInfo() .ChangeStandardCourseTime(StandardCourseTime)); var comparer = new CompetitionRunResultRankingComparer(model, RankingComparisonMode.OnlyPhasePenaltyOverrun); foreach (OrderingScenario scenario in scenarios.Where(s => s.Result != OrderExpect.DoNotCare)) { CompetitionRunResult xCompetitor = CreateCompetitorForPenaltyOverrun(scenario[0], scenario[1]); CompetitionRunResult yCompetitor = CreateCompetitorForPenaltyOverrun(scenario[2], scenario[3]); AssertCompetitorsAreCompatibleWithProposedScenario(xCompetitor, yCompetitor, scenario, model); // Act int result = comparer.Compare(xCompetitor, yCompetitor); // Assert OrderExpect actual = TranslateComparerResult(result); actual.Should().Be(scenario.Result, scenario.ToString()); } }
private void OkButton_Click([CanBeNull] object sender, [NotNull] EventArgs e) { CompetitionClassModel newVersion = originalVersion.ChangeRunResults(runResultsGrid.DataSource).RecalculatePlacements(); originalVersion = CacheManager.DefaultInstance.ReplaceModel(newVersion, originalVersion); DialogResult = DialogResult.OK; }
public ClassResultsForm() { InitializeComponent(); originalVersion = CacheManager.DefaultInstance.ActiveModel; }