From 1bb3156950a3caa3af8395a8ab5a36cba8e7bd47 Mon Sep 17 00:00:00 2001 From: Benedikt Schroeder Date: Thu, 11 Apr 2019 17:11:09 +0200 Subject: [PATCH] Introduce StartupEventArgs and ExitEventArgs --- samples/BindingDemo/App.xaml.cs | 3 +- samples/ControlCatalog.NetCore/Program.cs | 13 ++---- samples/ControlCatalog/App.xaml.cs | 10 ++--- samples/PlatformSanityChecks/App.xaml.cs | 3 +- samples/Previewer/App.xaml.cs | 5 ++- samples/RenderDemo/App.xaml.cs | 3 +- samples/VirtualizationDemo/App.xaml.cs | 3 +- .../interop/Direct3DInteropSample/App.paml.cs | 3 +- src/Avalonia.Controls/AppBuilderBase.cs | 1 - src/Avalonia.Controls/Application.cs | 43 +++++++++---------- .../IApplicationLifecycle.cs | 12 ++++-- .../Controls/ExitEventArgs.cs | 12 ++++++ .../Controls/StartupEventArgs.cs | 30 +++++++++++++ .../App.xaml.cs | 8 +--- 14 files changed, 93 insertions(+), 56 deletions(-) create mode 100644 src/Avalonia.Styling/Controls/ExitEventArgs.cs create mode 100644 src/Avalonia.Styling/Controls/StartupEventArgs.cs diff --git a/samples/BindingDemo/App.xaml.cs b/samples/BindingDemo/App.xaml.cs index 01c52a2a49..d95241372f 100644 --- a/samples/BindingDemo/App.xaml.cs +++ b/samples/BindingDemo/App.xaml.cs @@ -3,13 +3,12 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Logging.Serilog; using Avalonia.Markup.Xaml; -using Serilog; namespace BindingDemo { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index ee4c3fe350..42be488569 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -3,13 +3,11 @@ using System.Diagnostics; using System.Linq; using System.Threading; using Avalonia; -using Avalonia.Skia; namespace ControlCatalog.NetCore { static class Program - { - + { static void Main(string[] args) { Thread.CurrentThread.TrySetApartmentState(ApartmentState.STA); @@ -28,15 +26,10 @@ namespace ControlCatalog.NetCore AppBuilder.Configure().InitializeWithLinuxFramebuffer(tl => { tl.Content = new MainView(); - System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer()); + ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer()); }); else - BuildAvaloniaApp().Start(AppMain, args); - } - - static void AppMain(Application app, string[] args) - { - app.Run(); + BuildAvaloniaApp().Start(); } /// diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs index 6fbcecfd6e..1f466d9f91 100644 --- a/samples/ControlCatalog/App.xaml.cs +++ b/samples/ControlCatalog/App.xaml.cs @@ -1,18 +1,16 @@ using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace ControlCatalog { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { - AvaloniaXamlLoader.Load(this); - } + base.OnStartup(e); - protected override void OnStartup() - { - base.OnStartup(); + AvaloniaXamlLoader.Load(this); var mainWindow = new MainWindow(); diff --git a/samples/PlatformSanityChecks/App.xaml.cs b/samples/PlatformSanityChecks/App.xaml.cs index 508fc1e34b..b8f8350156 100644 --- a/samples/PlatformSanityChecks/App.xaml.cs +++ b/samples/PlatformSanityChecks/App.xaml.cs @@ -1,11 +1,12 @@ using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace PlatformSanityChecks { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } diff --git a/samples/Previewer/App.xaml.cs b/samples/Previewer/App.xaml.cs index fffa987a27..0fc42583a5 100644 --- a/samples/Previewer/App.xaml.cs +++ b/samples/Previewer/App.xaml.cs @@ -1,14 +1,15 @@ using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace Previewer { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } } -} \ No newline at end of file +} diff --git a/samples/RenderDemo/App.xaml.cs b/samples/RenderDemo/App.xaml.cs index 0f627961e6..4ac844983b 100644 --- a/samples/RenderDemo/App.xaml.cs +++ b/samples/RenderDemo/App.xaml.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using Avalonia; +using Avalonia.Controls; using Avalonia.Logging.Serilog; using Avalonia.Markup.Xaml; @@ -9,7 +10,7 @@ namespace RenderDemo { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } diff --git a/samples/VirtualizationDemo/App.xaml.cs b/samples/VirtualizationDemo/App.xaml.cs index b220807443..787bbf8d11 100644 --- a/samples/VirtualizationDemo/App.xaml.cs +++ b/samples/VirtualizationDemo/App.xaml.cs @@ -2,13 +2,14 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace VirtualizationDemo { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } diff --git a/samples/interop/Direct3DInteropSample/App.paml.cs b/samples/interop/Direct3DInteropSample/App.paml.cs index 1b6d5fd39c..b08c02509c 100644 --- a/samples/interop/Direct3DInteropSample/App.paml.cs +++ b/samples/interop/Direct3DInteropSample/App.paml.cs @@ -1,11 +1,12 @@ using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace Direct3DInteropSample { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); } diff --git a/src/Avalonia.Controls/AppBuilderBase.cs b/src/Avalonia.Controls/AppBuilderBase.cs index cda49a12b3..568b04c78c 100644 --- a/src/Avalonia.Controls/AppBuilderBase.cs +++ b/src/Avalonia.Controls/AppBuilderBase.cs @@ -292,7 +292,6 @@ namespace Avalonia.Controls WindowingSubsystemInitializer(); RenderingSubsystemInitializer(); Instance.RegisterServices(); - Instance.Initialize(); AfterSetupCallback(Self); } } diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index 383b994e70..2893505655 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -55,10 +55,10 @@ namespace Avalonia } /// - public event EventHandler Startup; + public event EventHandler Startup; /// - public event EventHandler Exit; + public event EventHandler Exit; /// public event EventHandler ResourcesChanged; @@ -199,14 +199,7 @@ namespace Avalonia /// /// true if this instance is shutting down; otherwise, false. /// - internal bool IsShuttingDown { get; set; } - - /// - /// Initializes the application by loading XAML etc. - /// - public virtual void Initialize() - { - } + internal bool IsShuttingDown { get; private set; } public void Run() { @@ -217,7 +210,7 @@ namespace Avalonia _mainLoopCancellationTokenSource = new CancellationTokenSource(); - Dispatcher.UIThread.Post(OnStartup, DispatcherPriority.Send); + Dispatcher.UIThread.Post(() => OnStartup(new StartupEventArgs()), DispatcherPriority.Send); Run(_mainLoopCancellationTokenSource.Token); } @@ -233,7 +226,7 @@ namespace Avalonia // Make sure we call OnExit in case an error happened and OnExit() wasn't called explicitly if (!IsShuttingDown) { - OnExit(); + OnExit(new ExitEventArgs()); } } @@ -248,10 +241,10 @@ namespace Avalonia throw new Exception("Run should only called once"); } - closable.Closed += (s, e) => OnExit(); - _mainLoopCancellationTokenSource = new CancellationTokenSource(); + closable.Closed += (s, e) => _mainLoopCancellationTokenSource?.Cancel(); + Run(_mainLoopCancellationTokenSource.Token); } @@ -284,26 +277,34 @@ namespace Avalonia Run(_mainLoopCancellationTokenSource.Token); } - protected virtual void OnStartup() + protected virtual void OnStartup(StartupEventArgs e) { - Startup?.Invoke(this, EventArgs.Empty); + Startup?.Invoke(this, e); } - protected virtual void OnExit() + protected virtual void OnExit(ExitEventArgs e) { - Exit?.Invoke(this, EventArgs.Empty); + Exit?.Invoke(this, e); + + Environment.ExitCode = e.ApplicationExitCode; } /// public void Shutdown() + { + Shutdown(0); + } + + /// + public void Shutdown(int exitCode) { IsShuttingDown = true; Windows.Clear(); - _mainLoopCancellationTokenSource?.Cancel(); + OnExit(new ExitEventArgs { ApplicationExitCode = exitCode }); - OnExit(); + _mainLoopCancellationTokenSource?.Cancel(); } /// @@ -314,8 +315,6 @@ namespace Avalonia Styles.TryGetResource(key, out value); } - - /// /// Register's the services needed by Avalonia. /// diff --git a/src/Avalonia.Controls/IApplicationLifecycle.cs b/src/Avalonia.Controls/IApplicationLifecycle.cs index c088ceb0eb..958c448d3e 100644 --- a/src/Avalonia.Controls/IApplicationLifecycle.cs +++ b/src/Avalonia.Controls/IApplicationLifecycle.cs @@ -10,16 +10,22 @@ namespace Avalonia.Controls /// /// Sent when the application is starting up. /// - event EventHandler Startup; + event EventHandler Startup; /// /// Sent when the application is exiting. /// - event EventHandler Exit; + event EventHandler Exit; /// - /// Exits the application. + /// Shuts down an application that returns the specified exit code to the operating system. /// void Shutdown(); + + /// + /// Shuts down an application that returns the specified exit code to the operating system. + /// + /// An integer exit code for an application. The default exit code is 0. + void Shutdown(int exitCode); } } diff --git a/src/Avalonia.Styling/Controls/ExitEventArgs.cs b/src/Avalonia.Styling/Controls/ExitEventArgs.cs new file mode 100644 index 0000000000..1a4ee15f17 --- /dev/null +++ b/src/Avalonia.Styling/Controls/ExitEventArgs.cs @@ -0,0 +1,12 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Controls +{ + public class ExitEventArgs : EventArgs + { + public int ApplicationExitCode { get; set; } + } +} diff --git a/src/Avalonia.Styling/Controls/StartupEventArgs.cs b/src/Avalonia.Styling/Controls/StartupEventArgs.cs new file mode 100644 index 0000000000..8b66ce0dc2 --- /dev/null +++ b/src/Avalonia.Styling/Controls/StartupEventArgs.cs @@ -0,0 +1,30 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Avalonia.Controls +{ + public class StartupEventArgs : EventArgs + { + private string[] _args; + + public IReadOnlyList Args => _args ?? (_args = GetArgs()); + + private static string[] GetArgs() + { + try + { + var args = Environment.GetCommandLineArgs(); + + return args.Length > 1 ? args.Skip(1).ToArray() : new string[0]; + } + catch (NotSupportedException) + { + return new string[0]; + } + } + } +} diff --git a/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs b/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs index 653a51232b..e2fc6ab7a2 100644 --- a/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs +++ b/tests/Avalonia.DesignerSupport.TestApp/App.xaml.cs @@ -1,15 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Avalonia.Controls; using Avalonia.Markup.Xaml; namespace Avalonia.DesignerSupport.TestApp { public class App : Application { - public override void Initialize() + protected override void OnStartup(StartupEventArgs e) { AvaloniaXamlLoader.Load(this); }