Skip to content

Commit

Permalink
Merge pull request #77 from dennis/detect-iracing-towing
Browse files Browse the repository at this point in the history
Event for IRacing towing
  • Loading branch information
dennis committed Mar 9, 2021
2 parents 03ce5a3 + 2ce6526 commit 8591f40
Show file tree
Hide file tree
Showing 14 changed files with 215 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- 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)
- IRacingPlugin: Adds: IRacingTowed event

## [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: 10 additions & 0 deletions Components/IRacing/EventFactory/IRacingEventFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Slipstream.Components.IRacing.Events;
using Slipstream.Components.IRacing.Plugins.GameState;
using Slipstream.Shared;
using System;
using static Slipstream.Components.IRacing.IIRacingEventFactory;

Expand Down Expand Up @@ -431,5 +432,14 @@ public IRacingRaw CreateIRacingRaw(IState state)
CurrentState = state
};
}

public IEvent CreateIRacingTowed(double sessionTime, float remainingTowTime)
{
return new IRacingTowed
{
SessionTime = sessionTime,
RemainingTowTime = remainingTowTime,
};
}
}
}
14 changes: 14 additions & 0 deletions Components/IRacing/EventHandler/IRacing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public IRacing(EventHandlerController eventHandler)

public delegate void OnIRacingRawHandler(EventHandlerController source, EventHandlerArgs<IRacingRaw> e);

public delegate void OnIRacingTowedHandler(EventHandlerController source, EventHandlerArgs<IRacingTowed> e);

public event OnIRacingCarCompletedLapHandler? OnIRacingCarCompletedLap;

public event OnIRacingCarInfoHandler? OnIRacingCarInfo;
Expand Down Expand Up @@ -106,6 +108,8 @@ public IRacing(EventHandlerController eventHandler)

public event OnIRacingRawHandler? OnIRacingRaw;

public event OnIRacingTowedHandler? OnIRacingTowed;

public IEventHandler.HandledStatus HandleEvent(IEvent @event)
{
switch (@event)
Expand Down Expand Up @@ -340,6 +344,16 @@ public IEventHandler.HandledStatus HandleEvent(IEvent @event)
{
return IEventHandler.HandledStatus.UseDefault;
}
case IRacingTowed tev:
if (OnIRacingTowed != null)
{
OnIRacingTowed(Parent, new EventHandlerArgs<IRacingTowed>(tev));
return IEventHandler.HandledStatus.Handled;
}
else
{
return IEventHandler.HandledStatus.UseDefault;
}
}

return IEventHandler.HandledStatus.NotMine;
Expand Down
33 changes: 33 additions & 0 deletions Components/IRacing/Events/IRacingTowed.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Slipstream.Shared;
using System.Collections.Generic;

namespace Slipstream.Components.IRacing.Events
{
public class IRacingTowed : IEvent
{
public string EventType => "IRacingTowed";
public bool ExcludeFromTxrx => false;
public ulong Uptime { get; set; }
public double SessionTime { get; set; }
public double RemainingTowTime { get; set; }

public override bool Equals(object obj)
{
return obj is IRacingTowed other &&
EventType == other.EventType &&
ExcludeFromTxrx == other.ExcludeFromTxrx &&
SessionTime == other.SessionTime &&
RemainingTowTime == other.RemainingTowTime;
}

public override int GetHashCode()
{
int hashCode = 2084919435;
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(EventType);
hashCode = hashCode * -1521134295 + ExcludeFromTxrx.GetHashCode();
hashCode = hashCode * -1521134295 + SessionTime.GetHashCode();
hashCode = hashCode * -1521134295 + RemainingTowTime.GetHashCode();
return hashCode;
}
}
}
3 changes: 3 additions & 0 deletions Components/IRacing/IIRacingEventFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Slipstream.Components.IRacing.Events;
using Slipstream.Components.IRacing.Plugins.GameState;
using Slipstream.Shared;

#nullable enable

Expand Down Expand Up @@ -47,6 +48,8 @@ IRacingCompletedLap CreateIRacingCompletedLap(
bool bestLap
);

IEvent CreateIRacingTowed(double sessionTime, float remainingTowTime);

IRacingCarInfo CreateIRacingCarInfo(
double sessionTime,
long carIdx,
Expand Down
1 change: 1 addition & 0 deletions Components/IRacing/Plugins/GameState/IState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ public interface IState
public IRacingSessionTypeEnum SessionType { get; }
public ISession[] Sessions { get; }
public ISession CurrentSession { get; }
public float PlayerCarTowTime { get; }
}
}
6 changes: 4 additions & 2 deletions Components/IRacing/Plugins/GameState/State.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ 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 int MyIncidentCount { get; set; }
public int TeamIncidentCount { get; set; }
public float PlayerCarTowTime { get; set; }

public State()
{
Expand Down Expand Up @@ -134,6 +135,7 @@ public IState Clone()
SessionState = SessionState,
SessionType = SessionType,
Sessions = sessions.ToArray(),
PlayerCarTowTime = PlayerCarTowTime,
};
}
}
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 @@ -112,6 +112,8 @@ internal class StateFactory : IStateFactory
FogLevel = ds.Telemetry.FogLevel,

RaceCategory = IRacingCategoryTypes[ds.SessionData.WeekendInfo.Category],

PlayerCarTowTime = (float)ds.Telemetry["PlayerCarTowTime"],
};

{
Expand Down
44 changes: 44 additions & 0 deletions Components/IRacing/Plugins/Trackers/TowTracker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Slipstream.Components.IRacing.Plugins.Models;
using Slipstream.Shared;
using System.Diagnostics;

#nullable enable

namespace Slipstream.Components.IRacing.Plugins.Trackers
{
internal class TowTracker : IIRacingDataTracker
{
private readonly IIRacingEventFactory EventFactory;
private readonly IEventBus EventBus;
private bool BeingTowed = false;

public TowTracker(IEventBus eventBus, IIRacingEventFactory eventFactory)
{
EventBus = eventBus;
EventFactory = eventFactory;
}

public void Handle(GameState.IState currentState, IRacingDataTrackerState state)
{
var towTime = currentState.PlayerCarTowTime;

if (towTime > 0)
{
if (!BeingTowed)
{
Debug.WriteLine($"TOW: {towTime}");
BeingTowed = true;

EventBus.PublishEvent(EventFactory.CreateIRacingTowed(
sessionTime: currentState.SessionTime,
remainingTowTime: towTime
));
}
}
else
{
BeingTowed = false;
}
}
}
}
1 change: 1 addition & 0 deletions Components/IRacing/Plugins/Trackers/Trackers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public Trackers(IEventBus eventBus, IIRacingEventFactory eventFactory)
DataTrackers.Add(new PitUsageTracker(eventBus, eventFactory));
DataTrackers.Add(new IRacingSessionTracker(eventBus, eventFactory));
DataTrackers.Add(new CarPositionTracker(eventBus, eventFactory));
DataTrackers.Add(new TowTracker(eventBus, eventFactory));
}

public void Handle(GameState.IState currentState)
Expand Down
18 changes: 17 additions & 1 deletion Components/IRacing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ Published every time car changes positions.
| EventType | string | `IRacingCarPosition` (constant) |
| ExcludeFromTxrx | boolean | false (constant) |
| Uptime | integer | Time of when the message was sent via Eventbus (in milliseconds). |
| SessionTime | string | |
| SessionTime | float | |
| CarIdx | int | Car Index |
| LocalUser | bool | Is it our car? |
| PositionInClass | int | Position in class |
Expand All @@ -547,3 +547,19 @@ Published every time car changes positions.
**JSON Example:**
`{"EventType":"IRacingCarPosition","ExcludeFromTxrx":false,"Uptime":2528216,"SessionTime":2711.7666666666669,"CarIdx":28,"LocalUser":true,"PositionInClass":15,"PositionInRace":15}`
</details>

<details><summary>IRacingTowed</summary><br />

Published every your car is being towed to pits. You will not get these events for other cars. These isn't published during replays.

| Name | Type | Description |
|:-----------------|:-------:|:------------------------------------------------------------------|
| EventType | string | `IRacingTowed` (constant) |
| ExcludeFromTxrx | boolean | false (constant) |
| Uptime | integer | Time of when the message was sent via Eventbus (in milliseconds). |
| SessionTime | float | |
| RemainingTowTime | float | How many seconds before we're in pit |

**JSON Example:**
`{"EventType":"IRacingTowed","ExcludeFromTxrx":false,"Uptime":2528216,"SessionTime":2711.7666666666669,"CarIdx":28,"LocalUser":true,"PositionInClass":15,"PositionInRace":15}`
</details>
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
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 TowTrackerTests
{
private readonly TestEventBus EventBus;
private readonly IIRacingEventFactory EventFactory;
private readonly IRacingDataTrackerState TrackerState;
private readonly GameStateBuilder Builder;

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

[Fact]
public void PublishEventIfBeginTowed()
{
const float NOW = 1234.2f;
const float TOW_TIME = 32.2f;

// arrange
Builder.AtSessionTime(NOW).Set(a => a.PlayerCarTowTime = TOW_TIME).Commit();
Builder.AtSessionTime(NOW + 1).Set(a => a.PlayerCarTowTime = TOW_TIME - 1).Commit();
Builder.AtSessionTime(NOW + 2).Set(a => a.PlayerCarTowTime = TOW_TIME - 2).Commit();

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

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

var @event = EventBus.Events[0] as IRacingTowed;
Assert.NotNull(@event);
Assert.True(@event.SessionTime == NOW);
Assert.True(@event.RemainingTowTime == TOW_TIME);
}

[Fact]
public void PublishEventsIfPlayerGotAReallyShittyRace()
{
const float NOW = 1234.2f;
const float TOW_TIME = 32.2f;
const float TOW2_TIME = 10f;

// arrange
// first two
Builder.AtSessionTime(NOW).Set(a => a.PlayerCarTowTime = TOW_TIME).Commit();
Builder.AtSessionTime(NOW + 1).Set(a => a.PlayerCarTowTime = TOW_TIME - 1).Commit();
// all ok again
Builder.AtSessionTime(NOW + 2).Set(a => a.PlayerCarTowTime = 0).Commit();
// another tow
Builder.AtSessionTime(NOW + 3).Set(a => a.PlayerCarTowTime = TOW2_TIME).Commit();

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

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

var @event = EventBus.Events[1] as IRacingTowed;
Assert.NotNull(@event);
Assert.True(@event.SessionTime == NOW + 3);
Assert.True(@event.RemainingTowTime == TOW2_TIME);
}
}
}
3 changes: 1 addition & 2 deletions Slipstream.UnitTests/TestData/TestState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,10 @@ public class TestState : IState
public ISession[] Sessions { get; set; } = new Session[] { };

public ISession CurrentSession { get => Sessions[0]; }

public float LastLapTime { get; set; }

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

public TestState()
{
Expand Down
2 changes: 2 additions & 0 deletions Slipstream.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
<Compile Include="Components\Internal\LuaGLues\HttpLuaGlueFactory.cs" />
<Compile Include="Components\Internal\LuaGLues\CoreLuaGlueFactory.cs" />
<Compile Include="Components\Internal\Internal.cs" />
<Compile Include="Components\IRacing\Events\IRacingTowed.cs" />
<Compile Include="Components\IRacing\Events\IRacingRaw.cs" />
<Compile Include="Components\IRacing\LuaGlueFactory.cs" />
<Compile Include="Components\IRacing\Plugins\GameState\Car.cs" />
Expand All @@ -177,6 +178,7 @@
<Compile Include="Components\IRacing\Plugins\Models\DriverState.cs" />
<Compile Include="Components\IRacing\Plugins\Trackers\CarInfoTracker.cs" />
<Compile Include="Components\IRacing\Plugins\Trackers\CarPositionTracker.cs" />
<Compile Include="Components\IRacing\Plugins\Trackers\TowTracker.cs" />
<Compile Include="Components\IRacing\Plugins\Trackers\IRacingSessionTracker.cs" />
<Compile Include="Components\IRacing\Plugins\Trackers\PitUsageTracker.cs" />
<Compile Include="Components\IRacing\Plugins\Trackers\LapsCompletedTracker.cs" />
Expand Down

0 comments on commit 8591f40

Please sign in to comment.