diff --git a/RaceLapTimer/Interfaces/ITransponderUtilities.cs b/RaceLapTimer/Interfaces/ITransponderUtilities.cs deleted file mode 100644 index 16c7d39..0000000 --- a/RaceLapTimer/Interfaces/ITransponderUtilities.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Interfaces -{ - public interface ITransponderUtilities - { - int GetLastScannedIdAsync(); - } -} diff --git a/RaceLapTimer/Interfaces/ITransponderUtilityManager.cs b/RaceLapTimer/Interfaces/ITransponderUtilityManager.cs new file mode 100644 index 0000000..5086896 --- /dev/null +++ b/RaceLapTimer/Interfaces/ITransponderUtilityManager.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace Interfaces +{ + public interface ITransponderUtilityManager + { + List GetProviders(); + + int GetLastScannedId(); + } +} diff --git a/RaceLapTimer/Interfaces/ITransponderUtilityProvider.cs b/RaceLapTimer/Interfaces/ITransponderUtilityProvider.cs new file mode 100644 index 0000000..6da3120 --- /dev/null +++ b/RaceLapTimer/Interfaces/ITransponderUtilityProvider.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Interfaces +{ + public interface ITransponderUtilityProvider + { + Task GetLastScannedIdAsync(); + } +} diff --git a/RaceLapTimer/Interfaces/ITransponderUtilityProviderFactory.cs b/RaceLapTimer/Interfaces/ITransponderUtilityProviderFactory.cs index c81b54a..ca2d327 100644 --- a/RaceLapTimer/Interfaces/ITransponderUtilityProviderFactory.cs +++ b/RaceLapTimer/Interfaces/ITransponderUtilityProviderFactory.cs @@ -2,6 +2,6 @@ { public interface ITransponderUtilityProviderFactory { - ITransponderUtilities GetProvider(); + ITransponderUtilityProvider GetProvider(); } } diff --git a/RaceLapTimer/Interfaces/Interfaces.csproj b/RaceLapTimer/Interfaces/Interfaces.csproj index dd8532a..387ab44 100644 --- a/RaceLapTimer/Interfaces/Interfaces.csproj +++ b/RaceLapTimer/Interfaces/Interfaces.csproj @@ -53,7 +53,8 @@ - + + diff --git a/RaceLapTimer/IrDaemonNotifier/IdDaemonTransponderUtilityFactory.cs b/RaceLapTimer/IrDaemonNotifier/IdDaemonTransponderUtilityFactory.cs new file mode 100644 index 0000000..266cb42 --- /dev/null +++ b/RaceLapTimer/IrDaemonNotifier/IdDaemonTransponderUtilityFactory.cs @@ -0,0 +1,12 @@ +using Interfaces; + +namespace IrDaemonNotifier +{ + public class IdDaemonTransponderUtilityFactory : ITransponderUtilityProviderFactory + { + public ITransponderUtilityProvider GetProvider() + { + return new IrDaemonTransponderUtilities(); + } + } +} \ No newline at end of file diff --git a/RaceLapTimer/IrDaemonNotifier/IrDaemonController.cs b/RaceLapTimer/IrDaemonNotifier/IrDaemonController.cs index 9bd432e..83449e0 100644 --- a/RaceLapTimer/IrDaemonNotifier/IrDaemonController.cs +++ b/RaceLapTimer/IrDaemonNotifier/IrDaemonController.cs @@ -10,12 +10,4 @@ namespace IrDaemonNotifier Debug.WriteLine("test"); } } - - public class IrDaemonControllerProviderFactory : ISystemControlProviderFactory - { - public ISystemControl GetProvider() - { - return new IrDaemonController(); - } - } } diff --git a/RaceLapTimer/IrDaemonNotifier/IrDaemonNotifier.csproj b/RaceLapTimer/IrDaemonNotifier/IrDaemonNotifier.csproj index 8033198..8aa8f73 100644 --- a/RaceLapTimer/IrDaemonNotifier/IrDaemonNotifier.csproj +++ b/RaceLapTimer/IrDaemonNotifier/IrDaemonNotifier.csproj @@ -40,9 +40,12 @@ + + + diff --git a/RaceLapTimer/IrDaemonNotifier/IrDaemonTransponderUtilities.cs b/RaceLapTimer/IrDaemonNotifier/IrDaemonTransponderUtilities.cs new file mode 100644 index 0000000..dfc255d --- /dev/null +++ b/RaceLapTimer/IrDaemonNotifier/IrDaemonTransponderUtilities.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; +using Interfaces; + +namespace IrDaemonNotifier +{ + public class IrDaemonTransponderUtilities : ITransponderUtilityProvider + { + public Task GetLastScannedIdAsync() + { + return Task.FromResult(-1); + } + } +} \ No newline at end of file diff --git a/RaceLapTimer/RaceLapTimer/AuthenticationBootstrapper.cs b/RaceLapTimer/RaceLapTimer/AuthenticationBootstrapper.cs index ab0bc78..bcc9b4b 100644 --- a/RaceLapTimer/RaceLapTimer/AuthenticationBootstrapper.cs +++ b/RaceLapTimer/RaceLapTimer/AuthenticationBootstrapper.cs @@ -10,6 +10,7 @@ using Ninject; using RaceLapTimer.Extensions; using RaceLapTimer.Extensions.Notifications; using RaceLapTimer.Extensions.SystemControl; +using RaceLapTimer.Extensions.TransponderUtilities; namespace RaceLapTimer { @@ -38,9 +39,10 @@ namespace RaceLapTimer container.Bind().To().InSingletonScope(); container.Bind().To().InSingletonScope(); + container.Bind().To().InSingletonScope(); - var sM = container.Get(); - sM.Shutdown(); + var tM = container.Get(); + tM.GetLastScannedId(); } protected override void ConfigureRequestContainer(IKernel container, NancyContext context) diff --git a/RaceLapTimer/RaceLapTimer/Extensions/TransponderUtilities/TransponderUtilityManager.cs b/RaceLapTimer/RaceLapTimer/Extensions/TransponderUtilities/TransponderUtilityManager.cs new file mode 100644 index 0000000..afc2f23 --- /dev/null +++ b/RaceLapTimer/RaceLapTimer/Extensions/TransponderUtilities/TransponderUtilityManager.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Interfaces; +using RaceLapTimer.Helpers; + +namespace RaceLapTimer.Extensions.TransponderUtilities +{ + class TransponderUtilityManager:ITransponderUtilityManager + { + private List _providers; + private readonly ILoggerService _logger; + + public TransponderUtilityManager(ILoggerService logger, IPluginLocator locator) + { + _logger = logger; + RegisterProviders(locator); + } + + private void RegisterProviders(IPluginLocator locator) + { + try + { + var providerFactories = locator.Locate(); + _providers = new List(); + foreach (var factory in providerFactories) + { + _providers.Add(factory.GetProvider()); + } + } + catch (Exception ex) + { + _logger.Error(ex); + } + } + + public List GetProviders() + { + return _providers; + } + + public int GetLastScannedId() + { + //TODO: Implement a utlity provider selector, this can only work with one transponder utility provider. + if (_providers.Any()) + { + var provider = _providers.First(); + var lastId = AsyncHelpers.RunSync(_providers.First().GetLastScannedIdAsync); + _logger.Trace("Got Id {0} from provider {1}", lastId, provider.GetType().Name); + return lastId; + } + return -1; + } + } +} diff --git a/RaceLapTimer/RaceLapTimer/Helpers/AsyncHelpers.cs b/RaceLapTimer/RaceLapTimer/Helpers/AsyncHelpers.cs new file mode 100644 index 0000000..46ce6ae --- /dev/null +++ b/RaceLapTimer/RaceLapTimer/Helpers/AsyncHelpers.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace RaceLapTimer.Helpers +{ + public static class AsyncHelpers + { + /// + /// Execute's an async Task method which has a void return value synchronously + /// + /// Task method to execute + public static void RunSync(Func task) + { + var oldContext = SynchronizationContext.Current; + var synch = new ExclusiveSynchronizationContext(); + SynchronizationContext.SetSynchronizationContext(synch); + synch.Post(async _ => + { + try + { + await task(); + } + catch (Exception e) + { + synch.InnerException = e; + throw; + } + finally + { + synch.EndMessageLoop(); + } + }, null); + synch.BeginMessageLoop(); + + SynchronizationContext.SetSynchronizationContext(oldContext); + } + + /// + /// Execute's an async Task method which has a T return type synchronously + /// + /// Return Type + /// Task method to execute + /// + public static T RunSync(Func> task) + { + var oldContext = SynchronizationContext.Current; + var synch = new ExclusiveSynchronizationContext(); + SynchronizationContext.SetSynchronizationContext(synch); + T ret = default(T); + synch.Post(async _ => + { + try + { + ret = await task(); + } + catch (Exception e) + { + synch.InnerException = e; + throw; + } + finally + { + synch.EndMessageLoop(); + } + }, null); + synch.BeginMessageLoop(); + SynchronizationContext.SetSynchronizationContext(oldContext); + return ret; + } + + private class ExclusiveSynchronizationContext : SynchronizationContext + { + private bool done; + public Exception InnerException { get; set; } + readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false); + readonly Queue> items = + new Queue>(); + + public override void Send(SendOrPostCallback d, object state) + { + throw new NotSupportedException("We cannot send to our same thread"); + } + + public override void Post(SendOrPostCallback d, object state) + { + lock (items) + { + items.Enqueue(Tuple.Create(d, state)); + } + workItemsWaiting.Set(); + } + + public void EndMessageLoop() + { + Post(_ => done = true, null); + } + + public void BeginMessageLoop() + { + while (!done) + { + Tuple task = null; + lock (items) + { + if (items.Count > 0) + { + task = items.Dequeue(); + } + } + if (task != null) + { + task.Item1(task.Item2); + if (InnerException != null) // the method threw an exeption + { + throw new AggregateException("AsyncHelpers.Run method threw an exception.", InnerException); + } + } + else + { + workItemsWaiting.WaitOne(); + } + } + } + + public override SynchronizationContext CreateCopy() + { + return this; + } + } + } +} diff --git a/RaceLapTimer/RaceLapTimer/RaceLapTimer.csproj b/RaceLapTimer/RaceLapTimer/RaceLapTimer.csproj index af757ba..9fe1759 100644 --- a/RaceLapTimer/RaceLapTimer/RaceLapTimer.csproj +++ b/RaceLapTimer/RaceLapTimer/RaceLapTimer.csproj @@ -116,6 +116,7 @@ +