diff --git a/OpenF1.Console/ConsoleLoop.cs b/OpenF1.Console/ConsoleLoop.cs index 9251d82..0d4e15d 100644 --- a/OpenF1.Console/ConsoleLoop.cs +++ b/OpenF1.Console/ConsoleLoop.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using System.Security.Cryptography; using Spectre.Console; using Spectre.Console.Rendering; diff --git a/OpenF1.Console/Program.cs b/OpenF1.Console/Program.cs index 3ee090d..c4f31c6 100644 --- a/OpenF1.Console/Program.cs +++ b/OpenF1.Console/Program.cs @@ -21,6 +21,10 @@ var services = serviceCollection.BuildServiceProvider(); +var notifyService = services.GetRequiredService(); +// When notifications are received, send a ASCII BEL to the console to make a noise to alert the user. +notifyService.RegisterNotificationHandler(() => Console.Write("\u0007")); + var consoleLoop = services.GetRequiredService(); await consoleLoop.ExecuteAsync(); diff --git a/OpenF1.Data/Interfaces/INotifyService.cs b/OpenF1.Data/Interfaces/INotifyService.cs new file mode 100644 index 0000000..cde5f88 --- /dev/null +++ b/OpenF1.Data/Interfaces/INotifyService.cs @@ -0,0 +1,16 @@ +namespace OpenF1.Data; + +public interface INotifyService +{ + /// + /// Sends a notification to any registered handlers. + /// This should only be used to alert a user to some important action, and not to transmit any data. + /// + public void SendNotification(); + + /// + /// Registers the provided as a handler for any notification that is sent. + /// + /// The action to call when a notification has been sent. + public void RegisterNotificationHandler(Action action); +} diff --git a/OpenF1.Data/NotifyService.cs b/OpenF1.Data/NotifyService.cs new file mode 100644 index 0000000..3928883 --- /dev/null +++ b/OpenF1.Data/NotifyService.cs @@ -0,0 +1,13 @@ + +namespace OpenF1.Data; + +public class NotifyService : INotifyService +{ + private Action? _action; + + /// + public void RegisterNotificationHandler(Action action) => _action = action; + + /// + public void SendNotification() => _action?.Invoke(); +} diff --git a/OpenF1.Data/Processors/RaceControlMessageProcessor.cs b/OpenF1.Data/Processors/RaceControlMessageProcessor.cs index bd97b19..1cd0ade 100644 --- a/OpenF1.Data/Processors/RaceControlMessageProcessor.cs +++ b/OpenF1.Data/Processors/RaceControlMessageProcessor.cs @@ -1,6 +1,6 @@ namespace OpenF1.Data; -public class RaceControlMessageProcessor : IProcessor +public class RaceControlMessageProcessor(INotifyService notifyService) : IProcessor { public RaceControlMessageDataPoint RaceControlMessages { get; private set; } = new(); @@ -8,7 +8,12 @@ public void Process(RaceControlMessageDataPoint data) { foreach (var message in data.Messages) { - RaceControlMessages.Messages.TryAdd(message.Key, message.Value); + var added = RaceControlMessages.Messages.TryAdd(message.Key, message.Value); + if (added) + { + // New race control messages are important, so alert the user + notifyService.SendNotification(); + } } } } diff --git a/OpenF1.Data/ServiceCollectionExtensions.cs b/OpenF1.Data/ServiceCollectionExtensions.cs index 8c9221e..9c690a4 100644 --- a/OpenF1.Data/ServiceCollectionExtensions.cs +++ b/OpenF1.Data/ServiceCollectionExtensions.cs @@ -11,6 +11,7 @@ public static partial class ServiceCollectionExtensions /// Adds the services required to support processing live timing data. /// A is registered to support ingesting live timing data from the live feed. /// A is registered to support ingesting previously recorded timing data from JSON files. + /// A is registered to support sending notifications for when interesting data changes happen. /// /// The to add services to. /// The to bind @@ -21,7 +22,8 @@ public static IServiceCollection AddLiveTiming(this IServiceCollection collectio .Configure(configuration) .AddAutoMapper(cfg => cfg.AddCollectionMappers(), typeof(TimingDataPointConfiguration).Assembly) .AddLiveTimingClient() - .AddLiveTimingProcessors(); + .AddLiveTimingProcessors() + .AddSingleton(); return collection; }