public void lap_time_column_values_are_translated_into_set_status_messages_if_the_status_has_changed(SessionType session) { In(session).Assert(translator => { SetGridColumnValueMessage message; LiveDriver driver = translator.GetDriver(1); // On track. Note that OUT is displayed when a driver exits the pit and is on thier OUT lap. message = new SetGridColumnValueMessage(1, GridColumn.LapTime, GridColumnColour.White, "OUT"); Assert.MessagesAreEqual( new SetDriverStatusMessage(1, DriverStatus.OnTrack), translator.Translate(message) ); Assert.Equal(DriverStatus.OnTrack, driver.Status); Assert.Null(translator.Translate(message)); // In pit. message = new SetGridColumnValueMessage(1, GridColumn.LapTime, GridColumnColour.White, "IN PIT"); Assert.MessagesAreEqual( new SetDriverStatusMessage(1, DriverStatus.InPits), translator.Translate(message) ); Assert.Equal(DriverStatus.InPits, driver.Status); Assert.Null(translator.Translate(message)); // Retired. message = new SetGridColumnValueMessage(1, GridColumn.LapTime, GridColumnColour.White, "RETIRED"); Assert.MessagesAreEqual( new SetDriverStatusMessage(1, DriverStatus.Retired), translator.Translate(message) ); Assert.Equal(DriverStatus.Retired, driver.Status); Assert.Null(translator.Translate(message)); }); }
public void when_a_driver_is_not_on_the_track_lap_time_column_values_are_not_translated_into_set_lap_time_messages(SessionType session) { In(session).OnLap(5).Assert(translator => { var driver = translator.GetDriver(1); var message = new SetGridColumnValueMessage(1, GridColumn.LapTime, GridColumnColour.White, "1:35.571"); // In pits. driver.ChangeStatus(DriverStatus.InPits); Assert.Null(translator.Translate(message)); // Out. driver.ChangeStatus(DriverStatus.Out); Assert.Null(translator.Translate(message)); // Retired. driver.ChangeStatus(DriverStatus.Retired); Assert.Null(translator.Translate(message)); // Stopped. driver.ChangeStatus(DriverStatus.Stopped); Assert.Null(translator.Translate(message)); }); }
public void when_a_driver_is_not_pitted_and_the_pit_count_column_is_updated_we_do_not_expect_pit_time_updates() { In(SessionType.Race).Assert(translator => { var driver = translator.GetDriver(1); var message = new SetGridColumnValueMessage(1, GridColumn.PitCount, GridColumnColour.White, "2"); // On track. driver.ChangeStatus(DriverStatus.OnTrack); translator.Translate(message); Assert.False(driver.IsExpectingPitTimes); // Out. driver.ChangeStatus(DriverStatus.Out); translator.Translate(message); Assert.False(driver.IsExpectingPitTimes); // Retired. driver.ChangeStatus(DriverStatus.Retired); translator.Translate(message); Assert.False(driver.IsExpectingPitTimes); // Stopped. driver.ChangeStatus(DriverStatus.Stopped); translator.Translate(message); Assert.False(driver.IsExpectingPitTimes); }); }
public void sector_column_values_are_translated_into_set_status_messages_if_the_status_has_changed(GridColumn sector, SessionType session) { In(session).Assert(translator => { SetGridColumnValueMessage message; LiveDriver driver = translator.GetDriver(1); // Out. message = new SetGridColumnValueMessage(1, sector, GridColumnColour.White, "OUT"); Assert.MessagesAreEqual( new SetDriverStatusMessage(1, DriverStatus.Out), translator.Translate(message) ); Assert.Equal(DriverStatus.Out, driver.Status); Assert.Null(translator.Translate(message)); // Stopped. message = new SetGridColumnValueMessage(1, sector, GridColumnColour.White, "STOP"); Assert.MessagesAreEqual( new SetDriverStatusMessage(1, DriverStatus.Stopped), translator.Translate(message) ); Assert.Equal(DriverStatus.Stopped, driver.Status); Assert.Null(translator.Translate(message)); }); }
private Message TranslateSetIntervalTimeValue(SetGridColumnValueMessage message) { if(GetDriver(message).IsRaceLeader) { // The interval column for the lead driver displays the current lap number. return new CompositeMessage( new SetRaceLapNumberMessage(LiveData.ParseInt32(message.Value)), new SetDriverIntervalMessage(message.DriverId, TimeGap.Zero)); } if(message.Value.OrdinalEndsWith("L")) { // An L suffix indicates a lap interval, e.g. 1L return new SetDriverIntervalMessage(message.DriverId, new LapGap(LiveData.ParseInt32(message.Value.Substring(0, message.Value.Length - 1)))); } return new SetDriverIntervalMessage(message.DriverId, new TimeGap(LiveData.ParseTime(message.Value))); }
private Message TranslateSetSectorTimeValue(SetGridColumnValueMessage message, int sectorNumber) { var driver = GetDriver(message); if(message.Value.OrdinalEquals("OUT")) { return CreateStatusMessageIfChanged(driver, DriverStatus.Out); } if(message.Value.OrdinalEquals("STOP")) { return CreateStatusMessageIfChanged(driver, DriverStatus.Stopped); } if(driver.IsExpectingPitTimes) { return TranslateSetPitTimeValue(message, sectorNumber); } if(!driver.IsOnTrack) { return null; } var newTime = LiveData.ParseTime(message.Value); var newTimeType = LiveData.ToPostedTimeType(message.Colour); // As of China-2010 the feed sends value updates to previous columns with completely different // times and types. We can detect this when we receive an update for the previously completed // sector. If the sector number is not the one previously completed we process the message // normally. if(driver.IsPreviousSectorNumber(sectorNumber)) { if(driver.GetLastSector(sectorNumber) == null) { Log.WarnFormat("received value update to a previous sector but we have no" + " previous sector times for the driver, cannot translate this message: {0}", message); return null; } return new ReplaceDriverSectorTimeMessage(driver.Id, sectorNumber, new PostedTime(newTime, newTimeType, driver.GetLastSector(sectorNumber).LapNumber)); } return TranslateSetDriverSectorTimeMessage( new SetDriverSectorTimeMessage(driver.Id, sectorNumber, new PostedTime(newTime, newTimeType, driver.LapNumber))); }
void IMessageVisitor.Visit(SetGridColumnValueMessage message) { Dispatch(message); }
private Message TranslateSetQuallyTimeValue(SetGridColumnValueMessage message, int quallyNumber) { var driver = GetDriver(message); if(!(IsQuallySession && driver.IsOnTrack)) { return null; } var time = LiveData.ParseTime(message.Value); // We do not receive lap times during a qually session so we simulate them using the qually times. // Note that this is not a complete solution as we only receive qually times when the driver // improves upon thier time (hence the use of PostedTimeType.PersonalBest). // TODO we could keep track of the best time and promote the time to session best. return new CompositeMessage( new SetDriverQuallyTimeMessage(message.DriverId, quallyNumber, time), new SetDriverLapTimeMessage(message.DriverId, new PostedTime(time, PostedTimeType.PersonalBest, driver.LapNumber))); }
private Message TranslateSetSectorClear(SetGridColumnValueMessage message, int sectorNumber) { var driver = GetDriver(message); var lastSectorTime = driver.GetLastSector(1); // The feed will only send a value / colour update for S1 if the value has changed. We // can detect this when the S2 time is cleared and we are expecting an S1 update. // Note that we do not translate the message when the S1 column is currently cleared, // this usually occurs during practice as the driver exits the pits and the previous // times are cleared. // Also, note that an S2 clear can be received when we do not have a previous S1 time, // usually at the start of a session. if(driver.IsOnTrack && driver.IsCurrentSectorNumber(1) && sectorNumber == 2 && driver.ColumnHasValue(GridColumn.S1) && lastSectorTime != null) { return TranslateSetDriverSectorTimeMessage( new SetDriverSectorTimeMessage(driver.Id, 1, new PostedTime(lastSectorTime.Time, lastSectorTime.Type, driver.LapNumber))); } return null; }
/// <inheritdoc/> public override void Visit(SetGridColumnValueMessage message) { Translated = TranslateSetGridColumnValueMessage(message); }
private Message TranslateSetPitTimeValue(SetGridColumnValueMessage message, int sectorNumber) { if(sectorNumber != 3) { return null; } var driver = GetDriver(message); // After a driver pits, the pit times are displayed and the S3 column displays the length of the last pit // stop. Note: we subtract one as the lap number will have been incremented when the driver pitted. return new SetDriverPitTimeMessage(driver.Id, new PostedTime(LiveData.ParseTime(message.Value), PostedTimeType.Normal, Math.Max(driver.LapNumber - 1, 0))); }
private Message TranslateSetGridColumnValueMessage(SetGridColumnValueMessage message) { if(message.ClearColumn) { switch(message.Column) { case GridColumn.S1: return TranslateSetSectorClear(message, 1); case GridColumn.S2: return TranslateSetSectorClear(message, 2); case GridColumn.S3: return TranslateSetSectorClear(message, 3); default: return null; } } switch(message.Column) { case GridColumn.CarNumber: return TranslateSetCarNumberValue(message); case GridColumn.DriverName: return TranslateSetNameValue(message); case GridColumn.LapTime: return TranslateSetLapTimeValue(message); case GridColumn.Gap: return TranslateSetGapTimeValue(message); case GridColumn.S1: return TranslateSetSectorTimeValue(message, 1); case GridColumn.S2: return TranslateSetSectorTimeValue(message, 2); case GridColumn.S3: return TranslateSetSectorTimeValue(message, 3); case GridColumn.Laps: return TranslateSetCompletedLapsValue(message); case GridColumn.Interval: return TranslateSetIntervalTimeValue(message); case GridColumn.Q1: return TranslateSetQuallyTimeValue(message, 1); case GridColumn.Q2: return TranslateSetQuallyTimeValue(message, 2); case GridColumn.Q3: return TranslateSetQuallyTimeValue(message, 3); case GridColumn.PitCount: return TranslateSetPitCountValue(message); default: return null; } }
/// <inheritdoc/> public virtual void Visit(SetGridColumnValueMessage message) { }
private Message TranslateSetCarNumberValue(SetGridColumnValueMessage message) { Message translated = null; LiveDriver driver = GetDriver(message); int carNumber = LiveData.ParseInt32(message.Value); DriverStatus status = LiveData.ToDriverStatus(message.Colour); if(driver.CarNumber != carNumber) { translated = new SetDriverCarNumberMessage(driver.Id, carNumber); } if(driver.Status != status) { Message temp = new SetDriverStatusMessage(driver.Id, status); translated = translated == null ? temp : new CompositeMessage(translated, temp); } return translated; }
private static Message TranslateSetPitCountValue(SetGridColumnValueMessage message) { return new SetDriverPitCountMessage(message.DriverId, LiveData.ParseInt32(message.Value)); }
private static Message TranslateSetNameValue(SetGridColumnValueMessage message) { return new SetDriverNameMessage(message.DriverId, message.Value); }
private static Message TranslateSetGapTimeValue(SetGridColumnValueMessage message) { if(message.Value.OrdinalEquals("LAP")) { // LAP is displayed in the gap column of the lead driver. return new SetDriverGapMessage(message.DriverId, TimeGap.Zero); } if(message.Value.OrdinalEndsWith("L")) { // An L suffix indicates a lap gap, e.g. 4L return new SetDriverGapMessage(message.DriverId, new LapGap(LiveData.ParseInt32(message.Value.Substring(0, message.Value.Length - 1)))); } return new SetDriverGapMessage(message.DriverId, new TimeGap(LiveData.ParseTime(message.Value))); }
private static Message TranslateSetCompletedLapsValue(SetGridColumnValueMessage message) { return new SetDriverLapNumberMessage(message.DriverId, LiveData.ParseInt32(message.Value)); }
private Message TranslateSetLapTimeValue(SetGridColumnValueMessage message) { var driver = GetDriver(message); if(message.Value.OrdinalEquals("OUT")) { return CreateStatusMessageIfChanged(driver, DriverStatus.OnTrack); } if(message.Value.OrdinalEquals("IN PIT")) { return CreateStatusMessageIfChanged(driver, DriverStatus.InPits); } if(message.Value.OrdinalEquals("RETIRED")) { return CreateStatusMessageIfChanged(driver, DriverStatus.Retired); } if(driver.IsOnTrack && IsSessionStarted) { return new SetDriverLapTimeMessage(driver.Id, new PostedTime(LiveData.ParseTime(message.Value), LiveData.ToPostedTimeType(message.Colour), driver.LapNumber)); } return null; }
/// <inheritdoc/> public override void Visit(SetGridColumnValueMessage message) { GetDriver(message).SetColumnHasValue(message.Column, !message.ClearColumn); }