1
0
Эх сурвалжийг харах

Make Application to be an AvaloniaObject. With properties and stuff.

Nikita Tsukanov 6 жил өмнө
parent
commit
ef7e8f2107

+ 3 - 3
src/Android/Avalonia.Android/AndroidPlatform.cs

@@ -17,7 +17,7 @@ namespace Avalonia
     {
         public static T UseAndroid<T>(this T builder) where T : AppBuilderBase<T>, new()
         {
-            builder.UseWindowingSubsystem(() => Android.AndroidPlatform.Initialize(builder.Instance), "Android");
+            builder.UseWindowingSubsystem(() => Android.AndroidPlatform.Initialize(builder.ApplicationType), "Android");
             builder.UseSkia();
             return builder;
         }
@@ -41,7 +41,7 @@ namespace Avalonia.Android
             _scalingFactor = global::Android.App.Application.Context.Resources.DisplayMetrics.ScaledDensity;
         }
 
-        public static void Initialize(Avalonia.Application app)
+        public static void Initialize(Type appType)
         {
             AvaloniaLocator.CurrentMutable
                 .Bind<IClipboard>().ToTransient<ClipboardImpl>()
@@ -55,7 +55,7 @@ namespace Avalonia.Android
                 .Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
                 .Bind<IRenderLoop>().ToConstant(new RenderLoop())
                 .Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>()
-                .Bind<IAssetLoader>().ToConstant(new AssetLoader(app.GetType().Assembly));
+                .Bind<IAssetLoader>().ToConstant(new AssetLoader(appType.Assembly));
 
             SkiaPlatform.Initialize();
             ((global::Android.App.Application) global::Android.App.Application.Context.ApplicationContext)

+ 29 - 21
src/Avalonia.Controls/AppBuilderBase.cs

@@ -18,7 +18,9 @@ namespace Avalonia.Controls
     {
         private static bool s_setupWasAlreadyCalled;
         private Action _optionsInitializers;
-
+        private Func<Application> _appFactory;
+        private IApplicationLifetime _lifetime;
+        
         /// <summary>
         /// Gets or sets the <see cref="IRuntimePlatform"/> instance.
         /// </summary>
@@ -30,10 +32,15 @@ namespace Avalonia.Controls
         public Action RuntimePlatformServicesInitializer { get; private set; }
 
         /// <summary>
-        /// Gets or sets the <see cref="Application"/> instance being initialized.
+        /// Gets the <see cref="Application"/> instance being initialized.
         /// </summary>
-        public Application Instance { get; protected set; }
-
+        public Application Instance { get; private set; }
+        
+        /// <summary>
+        /// Gets the type of the Instance (even if it's not created yet)
+        /// </summary>
+        public Type ApplicationType { get; private set; }
+        
         /// <summary>
         /// Gets or sets a method to call the initialize the windowing subsystem.
         /// </summary>
@@ -76,20 +83,11 @@ namespace Avalonia.Controls
         public static TAppBuilder Configure<TApp>()
             where TApp : Application, new()
         {
-            return Configure(new TApp());
-        }
-
-        /// <summary>
-        /// Begin configuring an <see cref="Application"/>.
-        /// </summary>
-        /// <returns>An <typeparamref name="TAppBuilder"/> instance.</returns>
-        public static TAppBuilder Configure(Application app)
-        {
-            AvaloniaLocator.CurrentMutable.BindToSelf(app);
-
             return new TAppBuilder()
             {
-                Instance = app,
+                ApplicationType = typeof(TApp),
+                // Needed for CoreRT compatibility
+                _appFactory = () => new TApp()
             };
         }
 
@@ -157,6 +155,18 @@ namespace Avalonia.Controls
             return Self;
         }
 
+        /// <summary>
+        /// Sets up the platform-specific services for the application and initialized it with a particular lifetime, but does not run it.
+        /// </summary>
+        /// <param name="lifetime"></param>
+        /// <returns></returns>
+        public TAppBuilder SetupWithLifetime(IApplicationLifetime lifetime)
+        {
+            _lifetime = lifetime;
+            Setup();
+            return Self;
+        }
+        
         /// <summary>
         /// Specifies a windowing subsystem to use.
         /// </summary>
@@ -254,11 +264,6 @@ namespace Avalonia.Controls
         /// </summary>
         private void Setup()
         {
-            if (Instance == null)
-            {
-                throw new InvalidOperationException("No App instance configured.");
-            }
-
             if (RuntimePlatformServicesInitializer == null)
             {
                 throw new InvalidOperationException("No runtime platform services configured.");
@@ -282,6 +287,9 @@ namespace Avalonia.Controls
             s_setupWasAlreadyCalled = true;
             _optionsInitializers?.Invoke();
             RuntimePlatformServicesInitializer();
+            Instance = _appFactory();
+            Instance.ApplicationLifetime = _lifetime;
+            AvaloniaLocator.CurrentMutable.BindToSelf(Instance);
             WindowingSubsystemInitializer();
             RenderingSubsystemInitializer();
             AfterPlatformServicesSetupCallback(Self);

+ 1 - 1
src/Avalonia.Controls/Application.cs

@@ -32,7 +32,7 @@ namespace Avalonia
     /// method.
     /// - Tracks the lifetime of the application.
     /// </remarks>
-    public class Application : IGlobalDataTemplates, IGlobalStyles, IStyleRoot, IResourceNode
+    public class Application : AvaloniaObject, IGlobalDataTemplates, IGlobalStyles, IStyleRoot, IResourceNode
     {
         /// <summary>
         /// The application-global data templates.

+ 1 - 2
src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs

@@ -125,8 +125,7 @@ namespace Avalonia
             where T : AppBuilderBase<T>, new()
         {
             var lifetime = new ClassicDesktopStyleApplicationLifetime(builder.Instance) {ShutdownMode = shutdownMode};
-            builder.Instance.ApplicationLifetime = lifetime;
-            builder.SetupWithoutStarting();
+            builder.SetupWithLifetime(lifetime);
             return lifetime.Start(args);
         }
     }

+ 1 - 10
src/Avalonia.DesktopRuntime/AppBuilder.cs

@@ -18,19 +18,10 @@ namespace Avalonia
         /// </summary>
         public AppBuilder()
             : base(new StandardRuntimePlatform(),
-                builder => StandardRuntimePlatformServices.Register(builder.Instance?.GetType()?.Assembly))
+                builder => StandardRuntimePlatformServices.Register(builder.ApplicationType.Assembly))
         {
         }
 
-        /// <summary>
-        /// Initializes a new instance of the <see cref="AppBuilder"/> class.
-        /// </summary>
-        /// <param name="app">The <see cref="Application"/> instance.</param>
-        public AppBuilder(Application app) : this()
-        {
-            Instance = app;
-        }
-
         bool CheckEnvironment(Type checkerType)
         {
             if (checkerType == null)

+ 1 - 2
src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs

@@ -118,8 +118,7 @@ public static class LinuxFramebufferPlatformExtensions
         where T : AppBuilderBase<T>, new()
     {
         var lifetime = LinuxFramebufferPlatform.Initialize(builder, backend);
-        builder.Instance.ApplicationLifetime = lifetime;
-        builder.SetupWithoutStarting();
+        builder.SetupWithLifetime(lifetime);
         lifetime.Start(args);
         builder.Instance.Run(lifetime.Token);
         return lifetime.ExitCode;

+ 1 - 1
src/iOS/Avalonia.iOS/AppBuilder.cs

@@ -6,7 +6,7 @@ namespace Avalonia
     public class AppBuilder : AppBuilderBase<AppBuilder>
     {
         public AppBuilder() : base(new StandardRuntimePlatform(),
-            builder => StandardRuntimePlatformServices.Register(builder.Instance?.GetType().Assembly))
+            builder => StandardRuntimePlatformServices.Register(builder.ApplicationType.Assembly))
         {
 
         }