-
Notifications
You must be signed in to change notification settings - Fork 0
Add source for F1 games #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
1b5fc85
Added F1 2025 packets
codegefluester 05c82b9
Added F1 2024 types
codegefluester 06cbfb8
Added F1 2023 structs
codegefluester d267c63
Added F1 packets and fixtures
codegefluester 7e59998
Added F1 2025 packets
codegefluester 2d0610e
Added F1 2024 types
codegefluester 33773f4
Added F1 2023 structs
codegefluester 03c50c9
Added F1 packets and fixtures
codegefluester 6cc4471
Remove legacy F1 implementation workflow file
codegefluester 4d548e7
Merge branch 'feat/udp-base-source' of https://github.com/codegeflues…
codegefluester b91ad7c
Remove debug tooling for F1
codegefluester 8157ec0
Add F1 fixture files to test project
codegefluester 56a7f24
Add refactoring plan for telemetry source interface
codegefluester c2941a3
Remove debug logging
codegefluester 3831a8d
Added test cases for F1 packet parsing (super basic)
codegefluester c94d0f3
Added tests for event details parsing in F1 2025
codegefluester 2781cda
Tested F1 recording and reading of session recording
codegefluester 2eccdde
Update GamesDat.Demo.Wpf/Resources/Styles.xaml
codegefluester 9e1e0cb
Update GamesDat.Demo.Wpf/ViewModels/IRealtimeSource.cs
codegefluester 5e25ff0
[WIP] WIP Address feedback on adding source for F1 games (#5)
Copilot 007b7a3
Apply BufferSize to UDP socket ReceiveBufferSize (#6)
Copilot f238435
Refactor UdpSourceBase to use proper Dispose pattern (#7)
Copilot d100533
Make LiveryColour struct fields public for deserialization access (#8)
Copilot 1b732a9
Remove unused BytesToStruct method from F1RealtimeTelemetrySource (#9)
Copilot d23cb84
[WIP] WIP address feedback from review on adding source for F1 games …
Copilot 5519f4f
Fix unsafe fixed buffer pointer handling in F1 telemetry extensions (…
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,10 @@ | ||
| { | ||
| "profiles": { | ||
| "GamesDat.Demo.Wpf": { | ||
| "commandName": "Project" | ||
| "commandName": "Project", | ||
| "environmentVariables": { | ||
| "DEBUG": "1" | ||
| } | ||
| } | ||
| } | ||
| } |
166 changes: 166 additions & 0 deletions
166
GamesDat.Demo.Wpf/ViewModels/F1RealtimeSourceViewModel.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,166 @@ | ||
| using CommunityToolkit.Mvvm.ComponentModel; | ||
| using CommunityToolkit.Mvvm.Input; | ||
| using GamesDat.Core; | ||
| using GamesDat.Core.Telemetry.Sources; | ||
| using GamesDat.Core.Telemetry.Sources.Formula1; | ||
| using GamesDat.Core.Writer; | ||
| using System.Windows.Input; | ||
|
|
||
| namespace GamesDat.Demo.Wpf.ViewModels; | ||
|
|
||
| public partial class F1RealtimeSourceViewModel : ViewModelBase, IRealtimeSource | ||
| { | ||
| private GameSession? _gameSession; | ||
| private CancellationTokenSource? _cts; | ||
|
|
||
| [ObservableProperty] | ||
| private string _sourceName = "Formula 1"; | ||
codegefluester marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| [ObservableProperty] | ||
| private bool _isRunning; | ||
|
|
||
| [ObservableProperty] | ||
| private string _statusMessage = "Stopped"; | ||
codegefluester marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| [ObservableProperty] | ||
| private int _totalPacketsReceived; | ||
|
|
||
| [ObservableProperty] | ||
| private string? _sessionOutputPath; | ||
|
|
||
| [ObservableProperty] | ||
| private int _port = 20777; | ||
codegefluester marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Explicit interface implementations for command covariance | ||
| ICommand IRealtimeSource.StartCommand => StartCommand; | ||
| ICommand IRealtimeSource.StopCommand => StopCommand; | ||
| ICommand IRealtimeSource.ClearDataCommand => ClearDataCommand; | ||
|
|
||
| [RelayCommand(CanExecute = nameof(CanStart))] | ||
| private async Task StartAsync() | ||
| { | ||
| if (IsRunning) return; | ||
|
|
||
| try | ||
| { | ||
| StatusMessage = "Starting..."; | ||
|
|
||
| // Create F1 realtime telemetry source | ||
| var options = new UdpSourceOptions | ||
| { | ||
| Port = Port | ||
| }; | ||
|
|
||
| // Set output path for session recording | ||
| SessionOutputPath = $"./sessions/f1_session_{DateTime.UtcNow:yyyy-MM-dd_HH-mm-ss}.dat"; | ||
|
|
||
| F1RealtimeTelemetrySource f1Source; | ||
| try | ||
| { | ||
| f1Source = new F1RealtimeTelemetrySource(options); | ||
| f1Source.OutputTo(SessionOutputPath).UseWriter(new BinarySessionWriter()); | ||
| } | ||
| catch (System.Net.Sockets.SocketException ex) | ||
| { | ||
| StatusMessage = $"Failed to bind to port {Port}: {ex.Message}. Another application may be using this port."; | ||
| IsRunning = false; | ||
| return; | ||
| } | ||
|
|
||
| // Create game session | ||
| _gameSession = new GameSession(defaultOutputDirectory: "./sessions") | ||
| .AddSource(f1Source); | ||
|
|
||
| // Simple callback to count packets | ||
| _gameSession.OnData<F1TelemetryFrame>(frame => | ||
| { | ||
| Interlocked.Increment(ref _totalPacketsReceived); | ||
|
|
||
| // Update status message periodically | ||
| var count = _totalPacketsReceived; | ||
| if (count == 1) | ||
| { | ||
| StatusMessage = $"Receiving data on UDP port {Port}"; | ||
| } | ||
| else if (count % 100 == 0) | ||
| { | ||
| StatusMessage = $"Running... ({count} packets)"; | ||
| } | ||
| }); | ||
codegefluester marked this conversation as resolved.
Show resolved
Hide resolved
codegefluester marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Start the session | ||
| _cts = new CancellationTokenSource(); | ||
| IsRunning = true; | ||
|
|
||
| // Start game session in background | ||
| _ = Task.Run(async () => | ||
| { | ||
| try | ||
| { | ||
| await _gameSession.StartAsync(_cts.Token); | ||
| } | ||
| catch (OperationCanceledException) | ||
| { | ||
| // Normal cancellation | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| StatusMessage = $"Session Error: {ex.Message}"; | ||
| IsRunning = false; | ||
| } | ||
| }); | ||
|
|
||
| // Give it a moment to start | ||
| await Task.Delay(500); | ||
|
|
||
| StatusMessage = $"Listening on UDP port {Port} (Waiting for F1 game data...)"; | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| StatusMessage = $"Startup Error: {ex.Message}"; | ||
| IsRunning = false; | ||
| } | ||
| } | ||
|
|
||
| private bool CanStart() => !IsRunning; | ||
|
|
||
| [RelayCommand(CanExecute = nameof(CanStop))] | ||
| private async Task StopAsync() | ||
| { | ||
| _cts?.Cancel(); | ||
|
|
||
| if (_gameSession != null) | ||
| { | ||
| await _gameSession.StopAsync(); | ||
| await _gameSession.DisposeAsync(); | ||
| _gameSession = null; | ||
| } | ||
|
|
||
| IsRunning = false; | ||
| StatusMessage = "Stopped"; | ||
| } | ||
|
|
||
| private bool CanStop() => IsRunning; | ||
|
|
||
| [RelayCommand] | ||
| private void ClearData() | ||
| { | ||
| TotalPacketsReceived = 0; | ||
| } | ||
|
|
||
| partial void OnIsRunningChanged(bool value) | ||
| { | ||
| StartCommand.NotifyCanExecuteChanged(); | ||
| StopCommand.NotifyCanExecuteChanged(); | ||
| } | ||
|
|
||
| public void Dispose() | ||
| { | ||
| _cts?.Cancel(); | ||
| _gameSession?.StopAsync().GetAwaiter().GetResult(); | ||
| _gameSession?.DisposeAsync().AsTask().GetAwaiter().GetResult(); | ||
| _gameSession = null; | ||
| _cts?.Dispose(); | ||
| GC.SuppressFinalize(this); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| using System.Windows.Input; | ||
|
|
||
| namespace GamesDat.Demo.Wpf.ViewModels; | ||
|
|
||
| public interface IRealtimeSource : IDisposable | ||
| { | ||
| string SourceName { get; } | ||
| bool IsRunning { get; } | ||
| string StatusMessage { get; } | ||
| ICommand StartCommand { get; } | ||
| ICommand StopCommand { get; } | ||
| ICommand ClearDataCommand { get; } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.