scratch-link/scratch-link-common/ScratchLinkApp.cs
2023-01-13 08:21:38 -08:00

128 lines
4.3 KiB
C#

// <copyright file="ScratchLinkApp.cs" company="Scratch Foundation">
// Copyright (c) Scratch Foundation. All rights reserved.
// </copyright>
namespace ScratchLink;
using System;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using ScratchLink.BLE;
/// <summary>
/// Main entry point for Scratch Link and central service provider for dependency injection.
/// </summary>
public class ScratchLinkApp
{
private const int WebSocketPort = 20111;
private readonly SessionManager sessionManager;
private readonly WebSocketListener webSocketListener;
private ScratchLinkApp(IServiceProvider platformServicesProvider)
{
Debug.AutoFlush = Trace.AutoFlush = true;
this.Services = platformServicesProvider;
if (Current != null)
{
throw new InvalidOperationException("Attempt to create a second app instance");
}
Current = this;
this.sessionManager = this.Services.GetService<SessionManager>();
this.webSocketListener = new ()
{
OnWebSocketConnection = this.sessionManager.ClientDidConnect,
};
}
/// <summary>
/// Gets the current app instance.
/// </summary>
public static ScratchLinkApp Current { get; private set; }
/// <summary>
/// Gets the platform-specific services provider.
/// This provides access to services like the session manager or GATT helpers.
/// </summary>
public IServiceProvider Services { get; private set; }
/// <summary>
/// Run the app.
/// </summary>
public void Run()
{
this.webSocketListener.Start(string.Format("http://0.0.0.0:{0}/", WebSocketPort));
}
/// <summary>
/// Quit the app.
/// </summary>
public void Quit()
{
this.webSocketListener.Stop();
this.sessionManager.EndAllSessions();
}
/// <summary>
/// Builds a Scratch Link app instance.
/// Fills the role of the .NET generic host or <c>MauiAppBuilder</c>.
/// </summary>
public class Builder
{
private string[] arguments;
private Type sessionManagerType;
private Type gattHelpersBaseType;
private Type gattHelpersType;
/// <summary>
/// Sets the arguments which will be passed to the app host.
/// Must be called before Build().
/// </summary>
/// <param name="arguments">Command line arguments from app invocation.</param>
public void SetArguments(string[] arguments)
{
this.arguments = arguments;
}
/// <summary>
/// Sets the type which will be used to build the platform-specific session manager.
/// </summary>
/// <typeparam name="TSessionManager">The platform-specific session manager type.</typeparam>
internal void SetSessionManager<TSessionManager>()
where TSessionManager : SessionManager
{
this.sessionManagerType = typeof(TSessionManager);
}
/// <summary>
/// Sets the types which will be used to build the BLE GATT helpers.
/// </summary>
/// <typeparam name="TGattHelpers">The platform-specific GATT helpers type.</typeparam>
/// <typeparam name="TUUID">The platform-specific type for BLE UUID values.</typeparam>
internal void SetGattHelpers<TGattHelpers, TUUID>()
where TGattHelpers : GattHelpers<TUUID>
{
this.gattHelpersBaseType = typeof(GattHelpers<TUUID>);
this.gattHelpersType = typeof(TGattHelpers);
}
/// <summary>
/// Builds a Scratch Link app host.
/// </summary>
/// <returns>A new Scratch Link app host.</returns>
internal ScratchLinkApp Build()
{
var serviceCollection = new ServiceCollection();
var serviceProviderOptions = new ServiceProviderOptions { ValidateOnBuild = true, ValidateScopes = true };
var servicesProvider = new DefaultServiceProviderFactory(serviceProviderOptions)
.CreateBuilder(serviceCollection)
.AddSingleton(typeof(SessionManager), this.sessionManagerType)
.AddSingleton(this.gattHelpersBaseType, this.gattHelpersType)
.BuildServiceProvider();
return new ScratchLinkApp(servicesProvider);
}
}
}