using Ghost.Editor.Core.AppState; using Ghost.Editor.Core.Inspector; using Ghost.Editor.Core.Notifications; using Ghost.Editor.Core.Progress; using Ghost.Editor.Utilities; using Ghost.Engine.Services; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.UI.Xaml; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. namespace Ghost.Editor; /// /// Provides application-specific behavior to supplement the default Application class. /// public partial class App : Application { private Window? _window; internal static Window? Window { get => (Current as App)!._window; set { if (Current is App app) { // HACK: As far as I can tell, there is no proper application shutdown event in WinUI 3. app._window?.Closed -= app.OnClosed; app._window = value; app._window?.Closed += app.OnClosed; } } } internal IHost Host { get; } /// /// Initializes the singleton application object. This is the first line of authored code /// executed, and as such is the logical equivalent of main() or WinMain(). /// internal App() { InitializeComponent(); Host = Microsoft.Extensions.Hosting.Host. CreateDefaultBuilder(). UseContentRoot(AppContext.BaseDirectory). ConfigureServices((context, services) => { HostHelper.AddLandingScope(context, services); HostHelper.AddEngineScope(context, services); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); }) .Build(); UnhandledException += App_UnhandledException; } internal static IServiceScope CreateScope() { return (Current as App)!.Host.Services.CreateScope(); } public static T GetService() where T : class { if ((Current as App)!.Host.Services.GetService(typeof(T)) is not T service) { throw new ArgumentException($"{typeof(T)} needs to be registered in ConfigureServices within App.xaml.cs."); } return service; } /// /// Invoked when the application is launched. /// /// Details about the launch request and process. protected override async void OnLaunched(LaunchActivatedEventArgs args) { base.OnLaunched(args); await Host.StartAsync(); ActivationHandler.Handle(args); var stateMachine = GetService(); stateMachine.RegisterState(StateKey.Landing, () => new LandingState()); stateMachine.RegisterState(StateKey.EngineEditor, () => new EditorState()); await stateMachine.TransitionToAsync(StateKey.Landing); } private void OnClosed(object? sender, WindowEventArgs args) { Host.StopAsync().GetAwaiter().GetResult(); Host.Dispose(); } private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) { Logger.LogError(e.Exception); } }