Skip to content

Commit

Permalink
Merge pull request #76 from dennis/more-incidents
Browse files Browse the repository at this point in the history
IRacing: Provide all Incident values (My, Driver, Team)
  • Loading branch information
dennis authored Mar 4, 2021
2 parents df9e712 + 10e9cab commit 03ce5a3
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 29 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
- IRacingPlugin: Adds BestLap to IRacingCompletedLap.
- IRacingPlugin: Rename IRacingCompletedLap.Time to IRacingCompletedLap.LapTime.
- IRacingPlugin: Add IRacingCompletedLap.EstimatedLapTime - to show if this was a laptime as recorded by IRacing or by Slipstream in case IRacing doesn't provide a laptime
- IRacingPlugin: Change IRacingDriverIncident: Rename Incident(Count|Delta) to DriverIncident(Count|Delta). Added fields: TeamIncident(Count|Delta) and MyIncident(Count|Delta)

## [0.4.0](https://github.com/dennis/slipstream/releases/tag/v0.3.0) (2020-01-10)
[Full Changelog](https://github.com/dennis/slipstream/compare/v0.3.0...v0.4.0)
Expand Down
10 changes: 7 additions & 3 deletions Components/IRacing/EventFactory/IRacingEventFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -328,12 +328,16 @@ public IRacingCommandSendRaceFlags CreateIRacingCommandSendRaceFlags()
return new IRacingCommandSendRaceFlags();
}

public IRacingDriverIncident CreateIRacingDriverIncident(int totalIncidents, int incidentDelta)
public IRacingDriverIncident CreateIRacingDriverIncident(int driverIncidents, int driverIncidentsDelta, int teamIncidents, int teamIncidentsDelta, int myIncidents, int myIncidentsDelta)
{
return new IRacingDriverIncident
{
IncidentCount = totalIncidents,
IncidentDelta = incidentDelta
DriverIncidentCount = driverIncidents,
DriverIncidentDelta = driverIncidentsDelta,
TeamIncidentCount = teamIncidents,
TeamIncidentDelta = teamIncidentsDelta,
MyIncidentCount = myIncidents,
MyIncidentDelta = myIncidentsDelta,
};
}

Expand Down
24 changes: 18 additions & 6 deletions Components/IRacing/Events/IRacingDriverIncident.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,37 @@ public class IRacingDriverIncident : IEvent
public string EventType => "IRacingDriverIncident";
public bool ExcludeFromTxrx => false;
public ulong Uptime { get; set; }
public int IncidentCount { get; set; }
public int IncidentDelta { get; set; }
public int DriverIncidentCount { get; set; }
public int DriverIncidentDelta { get; set; }
public int TeamIncidentCount { get; set; }
public int TeamIncidentDelta { get; set; }
public int MyIncidentCount { get; set; }
public int MyIncidentDelta { get; set; }

public override bool Equals(object? obj)
{
return obj is IRacingDriverIncident incident &&
EventType == incident.EventType &&
ExcludeFromTxrx == incident.ExcludeFromTxrx &&
IncidentCount == incident.IncidentCount &&
IncidentDelta == incident.IncidentDelta;
DriverIncidentCount == incident.DriverIncidentCount &&
DriverIncidentDelta == incident.DriverIncidentDelta &&
TeamIncidentCount == incident.TeamIncidentCount &&
TeamIncidentDelta == incident.TeamIncidentDelta &&
MyIncidentCount == incident.MyIncidentCount &&
MyIncidentDelta == incident.MyIncidentDelta;
}

public override int GetHashCode()
{
int hashCode = 1200671587;
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(EventType);
hashCode = hashCode * -1521134295 + ExcludeFromTxrx.GetHashCode();
hashCode = hashCode * -1521134295 + IncidentCount.GetHashCode();
hashCode = hashCode * -1521134295 + IncidentDelta.GetHashCode();
hashCode = hashCode * -1521134295 + DriverIncidentCount.GetHashCode();
hashCode = hashCode * -1521134295 + DriverIncidentDelta.GetHashCode();
hashCode = hashCode * -1521134295 + TeamIncidentCount.GetHashCode();
hashCode = hashCode * -1521134295 + TeamIncidentDelta.GetHashCode();
hashCode = hashCode * -1521134295 + MyIncidentCount.GetHashCode();
hashCode = hashCode * -1521134295 + MyIncidentDelta.GetHashCode();
return hashCode;
}
}
Expand Down
2 changes: 1 addition & 1 deletion Components/IRacing/IIRacingEventFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ IRacingWeatherInfo CreateIRacingWeatherInfo(

IRacingCommandSendRaceFlags CreateIRacingCommandSendRaceFlags();

IRacingDriverIncident CreateIRacingDriverIncident(int totalIncidents, int incidentDelta);
IRacingDriverIncident CreateIRacingDriverIncident(int driverIncidents, int driverIncidentsDelta, int teamIncidents, int teamIncidentsDelta, int myIncidents, int myIncidentsDelta);

IRacingPractice CreateIRacingPractice(double sessionTime, bool lapsLimited, bool timeLimited, double totalSessionTime, int totalSessionLaps, IRacingSessionStateEnum state, IRacingCategoryEnum category);

Expand Down
2 changes: 2 additions & 0 deletions Components/IRacing/Plugins/GameState/IState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public interface IState
public int SessionNum { get; }
public long DriverCarIdx { get; }
public int DriverIncidentCount { get; }
public int TeamIncidentCount { get; }
public int MyIncidentCount { get; }
public Car[] Cars { get; }
public float FuelLevel { get; }
public float LFtempCL { get; }
Expand Down
4 changes: 4 additions & 0 deletions Components/IRacing/Plugins/GameState/State.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public class State : IState
public IRacingSessionTypeEnum SessionType { get; set; } = IRacingSessionTypeEnum.Practice;
public ISession[] Sessions { get; set; } = new Session[] { };
public ISession CurrentSession { get => Sessions[SessionNum]; }
public int MyIncidentCount { get; internal set; }
public int TeamIncidentCount { get; internal set; }

public State()
{
Expand All @@ -84,6 +86,8 @@ public IState Clone()
SessionTime = SessionTime,
SessionNum = SessionNum,
DriverCarIdx = DriverCarIdx,
TeamIncidentCount = TeamIncidentCount,
MyIncidentCount = MyIncidentCount,
DriverIncidentCount = DriverIncidentCount,
Cars = cars.ToArray(),
FuelLevel = FuelLevel,
Expand Down
2 changes: 2 additions & 0 deletions Components/IRacing/Plugins/GameState/StateFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ internal class StateFactory : IStateFactory

DriverCarIdx = ds.SessionData.DriverInfo.DriverCarIdx,
DriverIncidentCount = Convert.ToInt32(ds.Telemetry["PlayerCarDriverIncidentCount"]),
MyIncidentCount = Convert.ToInt32(ds.Telemetry["PlayerCarMyIncidentCount"]),
TeamIncidentCount = Convert.ToInt32(ds.Telemetry["PlayerCarTeamIncidentCount"]),
FuelLevel = ds.Telemetry.FuelLevel,

LFtempCL = ds.Telemetry.LFtempCL,
Expand Down
8 changes: 6 additions & 2 deletions Components/IRacing/Plugins/Models/DriverState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
{
internal class DriverState
{
public int PlayerCarDriverIncidentCount { get; set; }
public int DriverIncidentCount { get; set; }
public int TeamIncidentCount { get; set; }
public int MyIncidentCount { get; set; }

public void ClearState()
{
PlayerCarDriverIncidentCount = 0;
DriverIncidentCount = 0;
TeamIncidentCount = 0;
MyIncidentCount = 0;
}
}
}
26 changes: 21 additions & 5 deletions Components/IRacing/Plugins/Trackers/IncidentTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,29 @@ public IncidentTracker(IEventBus eventBus, IIRacingEventFactory eventFactory)

public void Handle(GameState.IState currentState, IRacingDataTrackerState state)
{
int incidents = currentState.DriverIncidentCount;
var incidentDelta = incidents - state.DriverState_.PlayerCarDriverIncidentCount;
int driverIncidents = currentState.DriverIncidentCount;
var driverIncidentDelta = driverIncidents - state.DriverState_.DriverIncidentCount;

if (incidentDelta > 0)
int teamIncidents = currentState.TeamIncidentCount;
var teamIncidentsDelta = teamIncidents - state.DriverState_.TeamIncidentCount;

int myIncidents = currentState.MyIncidentCount;
var myIncidentsDelta = myIncidents - state.DriverState_.MyIncidentCount;

if (driverIncidentDelta + teamIncidentsDelta + myIncidentsDelta > 0)
{
state.DriverState_.PlayerCarDriverIncidentCount = incidents;
EventBus.PublishEvent(EventFactory.CreateIRacingDriverIncident(totalIncidents: incidents, incidentDelta: incidentDelta));
state.DriverState_.DriverIncidentCount = driverIncidents;
state.DriverState_.TeamIncidentCount = teamIncidents;
state.DriverState_.MyIncidentCount = myIncidents;

EventBus.PublishEvent(EventFactory.CreateIRacingDriverIncident(
driverIncidents: driverIncidents,
driverIncidentsDelta: driverIncidentDelta,
teamIncidents: teamIncidents,
teamIncidentsDelta: teamIncidentsDelta,
myIncidents: myIncidents,
myIncidentsDelta: myIncidentsDelta
));
}
}
}
Expand Down
20 changes: 12 additions & 8 deletions Components/IRacing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,16 +351,20 @@ Sent when connected to IRacing

Sent every time an incident is detected (only for user, not other drivers).

| Name | Type | Description |
|:----------------|:-------:|:------------------------------------------------------------------|
| EventType | string | `IRacingDriverIncident` (constant) |
| ExcludeFromTxrx | boolean | false (constant) |
| Uptime | integer | Time of when the message was sent via Eventbus (in milliseconds). |
| IncidentCount | int | Total incident count |
| IncidentDelta | int | Delta incident count |
| Name | Type | Description |
|:--------------------|:-------:|:------------------------------------------------------------------|
| EventType | string | `IRacingDriverIncident` (constant) |
| ExcludeFromTxrx | boolean | false (constant) |
| Uptime | integer | Time of when the message was sent via Eventbus (in milliseconds). |
| DriverIncidentCount | int | Total incidents for current driver in car |
| DriverIncidentDelta | int | Change since last event |
| TeamIncidentCount | int | Total incidents for the whole team |
| TeamIncidentDelta | int | Change since last event |
| MyIncidentCount | int | Total incidents for the user running IRacing locally |
| MyIncidentDelta | int | Change since last event |

**JSON Example:**
TODO
`{"EventType":"IRacingDriverIncident","ExcludeFromTxrx":false,"Uptime":262234,"DriverIncidentCount":1,"DriverIncidentDelta":1,"TeamIncidentCount":9,"TeamIncidentDelta":5,"MyIncidentCount":0,"MyIncidentDelta":0}`
</details>

<details><summary>IRacingPitEnter</summary><br />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using Slipstream.Components.IRacing;
using Slipstream.Components.IRacing.EventFactory;
using Slipstream.Components.IRacing.Events;
using Slipstream.Components.IRacing.Plugins.GameState;
using Slipstream.Components.IRacing.Plugins.Models;
using Slipstream.Components.IRacing.Plugins.Trackers;
using Slipstream.UnitTests.TestData;
using Xunit;

namespace Slipstream.UnitTests.Components.IRacing.Plugins.Trackers
{
public class IncidentTrackerTests
{
private readonly TestEventBus EventBus;
private readonly IIRacingEventFactory EventFactory;
private readonly IRacingDataTrackerState TrackerState;
private readonly GameStateBuilder Builder;

public IncidentTrackerTests()
{
EventBus = new TestEventBus();
EventFactory = new IRacingEventFactory();
TrackerState = new IRacingDataTrackerState();
Builder = new GameStateBuilder();
}

[Fact]
public void PublishEventWhenMyIncidentCountIncreases()
{
// arrange
Builder.Set(a => a.MyIncidentCount = 1).Commit();
Builder.Set(a => a.MyIncidentCount = 3).Commit();

// act
var sut = new IncidentTracker(EventBus, EventFactory);
foreach (var s in Builder.States)
sut.Handle(s, TrackerState);

// assert
Assert.True(EventBus.Events.Count == 2);

var event1 = EventBus.Events[0] as IRacingDriverIncident;
Assert.NotNull(event1);
Assert.True(event1.MyIncidentCount == 1);
Assert.True(event1.MyIncidentDelta == 1);

var event2 = EventBus.Events[1] as IRacingDriverIncident;
Assert.NotNull(event2);
Assert.True(event2.MyIncidentCount == 3);
Assert.True(event2.MyIncidentDelta == 2);
}

[Fact]
public void PublishEventWhenDriverIncidentCountIncreases()
{
// arrange
Builder.Set(a => a.DriverIncidentCount = 1).Commit();
Builder.Set(a => a.DriverIncidentCount = 3).Commit();

// act
var sut = new IncidentTracker(EventBus, EventFactory);
foreach (var s in Builder.States)
sut.Handle(s, TrackerState);

// assert
Assert.True(EventBus.Events.Count == 2);

var event1 = EventBus.Events[0] as IRacingDriverIncident;
Assert.NotNull(event1);
Assert.True(event1.DriverIncidentCount == 1);
Assert.True(event1.DriverIncidentDelta == 1);

var event2 = EventBus.Events[1] as IRacingDriverIncident;
Assert.NotNull(event2);
Assert.True(event2.DriverIncidentCount == 3);
Assert.True(event2.DriverIncidentDelta == 2);
}

[Fact]
public void PublishEventWhenTeamIncidentCountIncreases()
{
// arrange
Builder.Set(a => a.TeamIncidentCount = 1).Commit();
Builder.Set(a => a.TeamIncidentCount = 3).Commit();

// act
var sut = new IncidentTracker(EventBus, EventFactory);
foreach (var s in Builder.States)
sut.Handle(s, TrackerState);

// assert
Assert.True(EventBus.Events.Count == 2);

var event1 = EventBus.Events[0] as IRacingDriverIncident;
Assert.NotNull(event1);
Assert.True(event1.TeamIncidentCount == 1);
Assert.True(event1.TeamIncidentDelta == 1);

var event2 = EventBus.Events[1] as IRacingDriverIncident;
Assert.NotNull(event2);
Assert.True(event2.TeamIncidentCount == 3);
Assert.True(event2.TeamIncidentDelta == 2);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Slipstream.Components.IRacing;
using Slipstream.Components.IRacing.EventFactory;
using Slipstream.Components.IRacing.Events;
using Slipstream.Components.IRacing.Plugins.GameState;
using Slipstream.Components.IRacing.Plugins.Models;
using Slipstream.Components.IRacing.Plugins.Trackers;
using Slipstream.UnitTests.TestData;
Expand Down Expand Up @@ -50,7 +49,7 @@ public void CarDoesANewLapWithTimingEnabled()
const float NOW = 40.0f;

// arrange
Builder.ChangeState(a => a.DriverCarIdx = 1); // This is not our car, so we wont have fuel data
Builder.Set(a => a.DriverCarIdx = 1); // This is not our car, so we wont have fuel data
Builder.Car(0).EntersGame().AtLap(1).Commit();
Builder.AtSessionTime(LAP_STARTED_AT).Car(0).InPits().Commit();
Builder.Car(0).ExitingPits().Commit();
Expand Down
4 changes: 3 additions & 1 deletion Slipstream.UnitTests/TestData/GameStateBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ public GameStateBuilder()
};
}

public void ChangeState(Action<State> a)
public GameStateBuilder Set(Action<State> a)
{
a(State);

return this;
}

public class CarBuilder
Expand Down
5 changes: 4 additions & 1 deletion Slipstream.UnitTests/TestData/TestState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class TestState : IState

public long DriverCarIdx { get; set; } = 0;

public int DriverIncidentCount { get; set; } = 0;
public int TeamIncidentCount { get; set; } = 0;

public Car[] Cars { get; set; } = new Car[] { };

Expand Down Expand Up @@ -109,6 +109,9 @@ public class TestState : IState

public float LastLapTime { get; set; }

public int DriverIncidentCount { get; set; }
public int MyIncidentCount { get; set; }

public TestState()
{
var list = new List<ISession>
Expand Down

0 comments on commit 03ce5a3

Please sign in to comment.