|
|
@ -1,5 +1,6 @@ |
|
|
using System; |
|
|
using System; |
|
|
using System.Collections.Generic; |
|
|
using System.Collections.Generic; |
|
|
|
|
|
using System.Diagnostics; |
|
|
using System.Net; |
|
|
using System.Net; |
|
|
using System.Reflection; |
|
|
using System.Reflection; |
|
|
using Avalonia.Controls; |
|
|
using Avalonia.Controls; |
|
|
@ -22,6 +23,15 @@ namespace Avalonia.DesignerSupport.Remote |
|
|
{ |
|
|
{ |
|
|
public string AppPath { get; set; } |
|
|
public string AppPath { get; set; } |
|
|
public Uri Transport { 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) |
|
|
static Exception Die(string error) |
|
|
@ -35,11 +45,13 @@ namespace Avalonia.DesignerSupport.Remote |
|
|
return new Exception("APPEXIT"); |
|
|
return new Exception("APPEXIT"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void Log(string message) => Console.WriteLine(message); |
|
|
|
|
|
|
|
|
static Exception PrintUsage() |
|
|
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(); |
|
|
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(); |
|
|
Console.Error.Flush(); |
|
|
return Die(null); |
|
|
return Die(null); |
|
|
} |
|
|
} |
|
|
@ -59,6 +71,10 @@ namespace Avalonia.DesignerSupport.Remote |
|
|
} |
|
|
} |
|
|
else if (arg == "--transport") |
|
|
else if (arg == "--transport") |
|
|
next = a => rv.Transport = new Uri(a, UriKind.Absolute); |
|
|
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) |
|
|
else if (rv.AppPath == null) |
|
|
rv.AppPath = arg; |
|
|
rv.AppPath = arg; |
|
|
else |
|
|
else |
|
|
@ -84,18 +100,22 @@ namespace Avalonia.DesignerSupport.Remote |
|
|
PrintUsage(); |
|
|
PrintUsage(); |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
interface IAppInitializer |
|
|
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() |
|
|
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; |
|
|
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(); |
|
|
builder.SetupWithoutStarting(); |
|
|
return builder.Instance; |
|
|
return builder.Instance; |
|
|
} |
|
|
} |
|
|
@ -120,13 +140,16 @@ namespace Avalonia.DesignerSupport.Remote |
|
|
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); |
|
|
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); |
|
|
if (builderMethod == null) |
|
|
if (builderMethod == null) |
|
|
throw Die($"{entryPoint.DeclaringType.FullName} doesn't have a method named {BuilderMethodName}"); |
|
|
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); |
|
|
var appBuilder = builderMethod.Invoke(null, null); |
|
|
|
|
|
Log($"Initializing application in design mode"); |
|
|
var initializer =(IAppInitializer)Activator.CreateInstance(typeof(AppInitializer<>).MakeGenericType(appBuilder.GetType())); |
|
|
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; |
|
|
s_transport = transport; |
|
|
transport.OnMessage += OnTransportMessage; |
|
|
transport.OnMessage += OnTransportMessage; |
|
|
transport.OnException += (t, e) => Die(e.ToString()); |
|
|
transport.OnException += (t, e) => Die(e.ToString()); |
|
|
|
|
|
Log("Sending StartDesignerSessionMessage"); |
|
|
|
|
|
transport.Send(new StartDesignerSessionMessage {SessionId = args.SessionId}); |
|
|
app.Run(new NeverClose()); |
|
|
app.Run(new NeverClose()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -139,7 +162,8 @@ namespace Avalonia.DesignerSupport.Remote |
|
|
s_viewportAllocatedMessage |
|
|
s_viewportAllocatedMessage |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static Window s_currentWindow; |
|
|
private static void OnTransportMessage(IAvaloniaRemoteTransportConnection transport, object obj) => Dispatcher.UIThread.Post(() => |
|
|
private static void OnTransportMessage(IAvaloniaRemoteTransportConnection transport, object obj) => Dispatcher.UIThread.Post(() => |
|
|
{ |
|
|
{ |
|
|
if (obj is ClientSupportedPixelFormatsMessage formats) |
|
|
if (obj is ClientSupportedPixelFormatsMessage formats) |
|
|
@ -156,8 +180,17 @@ namespace Avalonia.DesignerSupport.Remote |
|
|
{ |
|
|
{ |
|
|
try |
|
|
try |
|
|
{ |
|
|
{ |
|
|
DesignWindowLoader.LoadDesignerWindow(xaml.Xaml, xaml.AssemblyPath); |
|
|
s_currentWindow?.Close(); |
|
|
s_transport.Send(new UpdateXamlResultMessage()); |
|
|
} |
|
|
|
|
|
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) |
|
|
catch (Exception e) |
|
|
{ |
|
|
{ |
|
|
|