Browse Source

Implemented `--session-id` and `--method win32` for previewer

Nikita Tsukanov 7 years ago
parent
commit
13171c4be3

+ 1 - 0
samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj

@@ -6,6 +6,7 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <ProjectReference Include="..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj" />
     <ProjectReference Include="..\..\src\Avalonia.DotNetCoreRuntime\Avalonia.DotNetCoreRuntime.csproj" />
     <ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
     <ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />

+ 44 - 11
src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Net;
 using System.Reflection;
 using Avalonia.Controls;
@@ -22,6 +23,15 @@ namespace Avalonia.DesignerSupport.Remote
         {
             public string AppPath { get; set; }
             public Uri Transport { get; set; }
+            public string Method { get; set; } = Methods.AvaloniaRemote;
+            public string SessionId { get; set; } = Guid.NewGuid().ToString();
+        }
+
+        static class Methods
+        {
+            public const string AvaloniaRemote = "avalonia-remote";
+            public const string Win32 = "win32";
+
         }
 
         static Exception Die(string error)
@@ -35,11 +45,13 @@ namespace Avalonia.DesignerSupport.Remote
             return new Exception("APPEXIT");
         }
 
+        static void Log(string message) => Console.WriteLine(message);
+
         static Exception PrintUsage()
         {
-            Console.Error.WriteLine("Usage: --transport transport_spec app");
+            Console.Error.WriteLine("Usage: --transport transport_spec --session-id sid --method method app");
             Console.Error.WriteLine();
-            Console.Error.WriteLine("Example: --transport tcp-bson://127.0.0.1:30243/ MyApp.exe");
+            Console.Error.WriteLine("Example: --transport tcp-bson://127.0.0.1:30243/ --session-id 123 --method avalonia-remote MyApp.exe");
             Console.Error.Flush();
             return Die(null);
         }
@@ -59,6 +71,10 @@ namespace Avalonia.DesignerSupport.Remote
                     }
                     else if (arg == "--transport")
                         next = a => rv.Transport = new Uri(a, UriKind.Absolute);
+                    else if (arg == "--method")
+                        next = a => rv.Method = a;
+                    else if (arg == "--session-id")
+                        next = a => rv.SessionId = a;
                     else if (rv.AppPath == null)
                         rv.AppPath = arg;
                     else
@@ -84,18 +100,22 @@ namespace Avalonia.DesignerSupport.Remote
             PrintUsage();
             return null;
         }
-
+        
         interface IAppInitializer
         {
-            Application GetConfiguredApp(IAvaloniaRemoteTransportConnection transport, object obj);
+            Application GetConfiguredApp(IAvaloniaRemoteTransportConnection transport, CommandLineArgs args, object obj);
         }
         
         class AppInitializer<T> : IAppInitializer where T : AppBuilderBase<T>, new()
         {
-            public Application GetConfiguredApp(IAvaloniaRemoteTransportConnection transport, object obj)
+            public Application GetConfiguredApp(IAvaloniaRemoteTransportConnection transport,
+                CommandLineArgs args, object obj)
             {
                 var builder = (AppBuilderBase<T>) obj;
-                builder.UseWindowingSubsystem(() => PreviewerWindowingPlatform.Initialize(transport));
+                if (args.Method == Methods.AvaloniaRemote)
+                    builder.UseWindowingSubsystem(() => PreviewerWindowingPlatform.Initialize(transport));
+                if (args.Method == Methods.Win32)
+                    builder.UseWindowingSubsystem("Avalonia.Win32");
                 builder.SetupWithoutStarting();
                 return builder.Instance;
             }
@@ -120,13 +140,16 @@ namespace Avalonia.DesignerSupport.Remote
                 BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
             if (builderMethod == null)
                 throw Die($"{entryPoint.DeclaringType.FullName} doesn't have a method named {BuilderMethodName}");
-
+            Log($"Obtaining AppBuilder instance from {builderMethod.DeclaringType.FullName}.{builderMethod.Name}");
             var appBuilder = builderMethod.Invoke(null, null);
+            Log($"Initializing application in design mode");
             var initializer =(IAppInitializer)Activator.CreateInstance(typeof(AppInitializer<>).MakeGenericType(appBuilder.GetType()));
-            var app = initializer.GetConfiguredApp(transport, appBuilder);
+            var app = initializer.GetConfiguredApp(transport, args, appBuilder);
             s_transport = transport;
             transport.OnMessage += OnTransportMessage;
             transport.OnException += (t, e) => Die(e.ToString());
+            Log("Sending StartDesignerSessionMessage");
+            transport.Send(new StartDesignerSessionMessage {SessionId = args.SessionId});
             app.Run(new NeverClose());
         }
 
@@ -139,7 +162,8 @@ namespace Avalonia.DesignerSupport.Remote
                 s_viewportAllocatedMessage
             };
         }
-        
+
+        private static Window s_currentWindow;
         private static void OnTransportMessage(IAvaloniaRemoteTransportConnection transport, object obj) => Dispatcher.UIThread.Post(() =>
         {
             if (obj is ClientSupportedPixelFormatsMessage formats)
@@ -156,8 +180,17 @@ namespace Avalonia.DesignerSupport.Remote
             {
                 try
                 {
-                    DesignWindowLoader.LoadDesignerWindow(xaml.Xaml, xaml.AssemblyPath);
-                    s_transport.Send(new UpdateXamlResultMessage());
+                    s_currentWindow?.Close();
+                }
+                catch
+                {
+                    //Ignore
+                }
+                s_currentWindow = null;
+                try
+                {
+                    s_currentWindow = DesignWindowLoader.LoadDesignerWindow(xaml.Xaml, xaml.AssemblyPath);
+                    s_transport.Send(new UpdateXamlResultMessage(){Handle = s_currentWindow.PlatformImpl?.Handle?.Handle.ToString()});
                 }
                 catch (Exception e)
                 {

+ 10 - 2
src/Avalonia.Remote.Protocol/DesignMessages.cs

@@ -1,4 +1,6 @@
-namespace Avalonia.Remote.Protocol.Designer
+using System;
+
+namespace Avalonia.Remote.Protocol.Designer
 {
     [AvaloniaRemoteMessageGuid("9AEC9A2E-6315-4066-B4BA-E9A9EFD0F8CC")]
     public class UpdateXamlMessage
@@ -11,7 +13,13 @@
     public class UpdateXamlResultMessage
     {
         public string Error { get; set; }
+        public string Handle { get; set; }
+    }
+
+    [AvaloniaRemoteMessageGuid("854887CF-2694-4EB6-B499-7461B6FB96C7")]
+    public class StartDesignerSessionMessage
+    {
+        public string SessionId { get; set; }
     }
-    
     
 }

+ 1 - 1
src/Avalonia.Remote.Protocol/TcpTransportBase.cs

@@ -72,7 +72,7 @@ namespace Avalonia.Remote.Protocol
         {
             var c = new TcpClient();
             await c.ConnectAsync(address, port);
-            return CreateTransport(_resolver, c.GetStream(), c.Dispose);
+            return CreateTransport(_resolver, c.GetStream(), ((IDisposable)c).Dispose);
         }
     }
 }

+ 34 - 1
src/tools/Avalonia.Designer.HostApp.NetFX/Program.cs

@@ -1,6 +1,9 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
 using System.Linq;
+using System.Reflection;
 using System.Text;
 using System.Threading.Tasks;
 
@@ -8,7 +11,37 @@ namespace Avalonia.Designer.HostApp.NetFX
 {
     class Program
     {
+        private static string s_appDir;
         public static void Main(string[] args)
-            => Avalonia.DesignerSupport.Remote.RemoteDesignerEntryPoint.Main(args);
+        {
+            s_appDir = Directory.GetCurrentDirectory();
+            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
+            foreach (var dll in Directory.GetFiles(s_appDir, "*.dll"))
+            {
+                try
+                {
+                    Console.WriteLine("Loading " + dll);
+                    Assembly.LoadFile(dll);
+                }
+                catch
+                {
+                    
+                }
+            }
+            Exec(args);
+        }
+
+        static void Exec(string[] args)
+        {
+            Avalonia.DesignerSupport.Remote.RemoteDesignerEntryPoint.Main(args);
+        }
+
+        private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
+        {
+            string assemblyPath = Path.Combine(s_appDir, new AssemblyName(args.Name).Name + ".dll");
+            if (File.Exists(assemblyPath) == false) return null;
+            Assembly assembly = Assembly.LoadFrom(assemblyPath);
+            return assembly;
+        }
     }
 }