dragon-iso/src/TeamsISO.App/App.xaml.cs
2026-05-07 15:41:58 +00:00

107 lines
3.5 KiB
C#

using System.IO;
using System.Windows;
using System.Windows.Threading;
using Microsoft.Extensions.Logging;
using TeamsISO.App.ViewModels;
using TeamsISO.Engine.Controller;
using TeamsISO.Engine.Interop;
using TeamsISO.Engine.Logging;
using TeamsISO.Engine.NdiInterop;
using TeamsISO.Engine.Persistence;
using TeamsISO.Engine.Pipeline;
namespace TeamsISO.App;
public partial class App : Application
{
private ILoggerFactory? _loggerFactory;
private NdiInteropPInvoke? _interop;
private IsoController? _controller;
private MainViewModel? _viewModel;
protected override async void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
try
{
_loggerFactory = EngineLogging.CreateConsole(LogLevel.Information);
var logger = _loggerFactory.CreateLogger<App>();
// ---- Preflight: NDI runtime ----
try
{
_interop = new NdiInteropPInvoke(_loggerFactory.CreateLogger<NdiInteropPInvoke>());
}
catch (Exception ex)
{
MessageBox.Show(
"TeamsISO could not initialize the NDI runtime.\n\n" +
"Install the NDI Runtime from https://ndi.video/tools/ and try again.\n\n" +
"Details: " + ex.Message,
"TeamsISO — NDI runtime missing",
MessageBoxButton.OK,
MessageBoxImage.Error);
Shutdown(2);
return;
}
// ---- Engine wiring ----
var configPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"TeamsISO", "config.json");
var configStore = new ConfigStore(configPath, _loggerFactory.CreateLogger<ConfigStore>());
var probe = new NdiRuntimeProbe(_interop, NdiVersion.ExpectedRuntimeVersionPrefix);
var scaler = new ManagedNearestNeighborFrameScaler();
var loggerFactoryRef = _loggerFactory;
var interopRef = _interop;
IsoPipeline PipelineFactory(IsoPipelineConfig config)
{
var clock = new PeriodicTimerFrameClock(config.Settings.FramerateHz);
return new IsoPipeline(
config, interopRef, scaler, clock,
ExponentialBackoff.Default,
(delay, ct) => Task.Delay(delay, ct),
loggerFactoryRef);
}
_controller = new IsoController(
_interop, PipelineFactory, configStore, probe, _loggerFactory);
_viewModel = new MainViewModel(_controller, Dispatcher);
var window = new MainWindow(_viewModel);
window.Show();
MainWindow = window;
await _viewModel.InitializeAsync(CancellationToken.None);
}
catch (Exception ex)
{
MessageBox.Show(
"TeamsISO failed to start.\n\nDetails: " + ex,
"TeamsISO — startup error",
MessageBoxButton.OK,
MessageBoxImage.Error);
Shutdown(1);
}
}
protected override async void OnExit(ExitEventArgs e)
{
try
{
_viewModel?.Dispose();
if (_controller is not null)
await _controller.DisposeAsync();
_interop?.Dispose();
_loggerFactory?.Dispose();
}
catch
{
// Best-effort shutdown
}
base.OnExit(e);
}
}