Browse Source

Designer proccess fixes

pull/569/head
Nikita Tsukanov 10 years ago
parent
commit
99878ef8bb
  1. 87
      src/Windows/Avalonia.Designer/AppHost/AvaloniaAppHost.cs
  2. 7
      src/Windows/Avalonia.Designer/Avalonia.Designer.csproj
  3. 25
      src/Windows/Avalonia.Designer/AvaloniaDesigner.xaml.cs
  4. 13
      src/Windows/Avalonia.Designer/Comm/ProcessHost.cs
  5. 20
      src/Windows/Avalonia.Designer/Comm/UpdateMetadata.cs
  6. 5
      src/Windows/Avalonia.Designer/DemoWindow.xaml
  7. 21
      src/Windows/Avalonia.Designer/DemoWindow.xaml.cs
  8. 51
      src/Windows/Avalonia.Designer/Metadata/AvaloniaDesignerMetadata.cs

87
src/Windows/Avalonia.Designer/AppHost/AvaloniaAppHost.cs

@ -10,7 +10,6 @@ using System.Windows.Forms.Integration;
using System.Xml;
using Avalonia.Designer.Comm;
using Avalonia.Designer.InProcDesigner;
using Avalonia.Designer.Metadata;
using Timer = System.Windows.Forms.Timer;
using Avalonia.DesignerSupport;
@ -91,88 +90,7 @@ namespace Avalonia.Designer.AppHost
}
}
AvaloniaDesignerMetadata BuildMetadata(List<Assembly> asms, Type xmlNsAttr)
{
var rv = new AvaloniaDesignerMetadata()
{
NamespaceAliases = new List<MetadataNamespaceAlias>(),
Types = new List<MetadataType>()
};
foreach (var asm in asms)
{
foreach (dynamic xmlns in asm.GetCustomAttributes().Where(a => a.GetType() == xmlNsAttr))
{
rv.NamespaceAliases.Add(new MetadataNamespaceAlias
{
Namespace = (string)xmlns.ClrNamespace,
XmlNamespace = (string)xmlns.XmlNamespace
});
}
try
{
foreach (var type in asm.GetTypes())
{
try
{
if (!type.IsPublic || type.IsAbstract)
continue;
var t = new MetadataType()
{
Name = type.Name,
Namespace = type.Namespace,
Properties = new List<MetadataProperty>()
};
rv.Types.Add(t);
foreach (var prop in type.GetProperties())
{
if (prop.GetMethod?.IsPublic != true)
continue;
var p = new MetadataProperty()
{
Name = prop.Name,
Type =
prop.PropertyType == typeof (string) ||
(prop.PropertyType.IsValueType &&
prop.PropertyType.Assembly == typeof (int).Assembly)
? MetadataPropertyType.BasicType
: prop.PropertyType.IsEnum
? MetadataPropertyType.Enum
: MetadataPropertyType.MetadataType
};
if (p.Type == MetadataPropertyType.Enum)
p.EnumValues = Enum.GetNames(prop.PropertyType);
if (p.Type == MetadataPropertyType.MetadataType)
p.MetadataFullTypeName = prop.PropertyType.Namespace + "." + prop.PropertyType.Name;
t.Properties.Add(p);
}
}
catch
{
//
}
}
}
catch
{
//
}
}
return rv;
}
void BuildMetadataAndSendMessageAsync(List<Assembly> asms)
{
var xmlNsAttr = LookupType("Avalonia.Metadata.XmlnsDefinitionAttribute");
new Thread(() =>
{
_comm.SendMessage(new UpdateMetadataMessage(BuildMetadata(asms, xmlNsAttr)));
}).Start();
}
private void DoInit(string targetExe, StringBuilder logger)
{
@ -196,9 +114,6 @@ namespace Avalonia.Designer.AppHost
logger.AppendLine(e.ToString());
}
log("Looking up Avalonia types");
BuildMetadataAndSendMessageAsync(asms);
log("Initializing built-in designer");
var dic = new Dictionary<string, object>();
Api = new DesignerApi(dic) {OnResize = OnResize, OnWindowCreated = OnWindowCreated};

7
src/Windows/Avalonia.Designer/Avalonia.Designer.csproj

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
@ -82,7 +82,6 @@
<Compile Include="Comm\InitMessage.cs" />
<Compile Include="Comm\ProcessHost.cs" />
<Compile Include="Comm\StateMessage.cs" />
<Compile Include="Comm\UpdateMetadata.cs" />
<Compile Include="Comm\UpdateXamlMessage.cs" />
<Compile Include="Comm\WindowCreatedMessage.cs" />
<Compile Include="DemoWindow.xaml.cs">
@ -91,7 +90,6 @@
<Compile Include="InProcDesigner\InProcDesignerView.xaml.cs">
<DependentUpon>InProcDesignerView.xaml</DependentUpon>
</Compile>
<Compile Include="Metadata\AvaloniaDesignerMetadata.cs" />
<Compile Include="AvaloniaDesigner.xaml.cs">
<DependentUpon>AvaloniaDesigner.xaml</DependentUpon>
</Compile>
@ -126,6 +124,9 @@
<ItemGroup>
<Content Include="README.txt" />
</ItemGroup>
<ItemGroup>
<Folder Include="Metadata\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

25
src/Windows/Avalonia.Designer/AvaloniaDesigner.xaml.cs

@ -18,7 +18,6 @@ using System.Windows.Navigation;
using System.Windows.Shapes;
using Avalonia.Designer.AppHost;
using Avalonia.Designer.Comm;
using Avalonia.Designer.Metadata;
namespace Avalonia.Designer
{
@ -53,8 +52,7 @@ namespace Avalonia.Designer
get { return (string) GetValue(XamlProperty); }
set { SetValue(XamlProperty, value); }
}
public AvaloniaDesignerMetadata Metadata { get; private set; }
private readonly ProcessHost _host = new ProcessHost();
@ -66,24 +64,28 @@ namespace Avalonia.Designer
new Binding(nameof(ProcessHost.State)) {Source = _host, Mode = BindingMode.OneWay});
_host.PropertyChanged += _host_PropertyChanged;
_host.MetadataArrived += data => Metadata = data;
}
private void _host_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(ProcessHost.WindowHandle))
{
if (NativeContainer.Child != null)
{
var child = NativeContainer.Child;
NativeContainer.Child = null;
child.Dispose();
}
ResetNativeContainer();
if(_host.WindowHandle == IntPtr.Zero)
return;
NativeContainer.Child = new WindowHost(false);
var wndHost = ((WindowHost) NativeContainer.Child);
wndHost.SetWindow(_host.WindowHandle);
}
}
void ResetNativeContainer()
{
if (NativeContainer.Child != null)
{
var child = NativeContainer.Child;
NativeContainer.Child = null;
child.Dispose();
}
}
@ -91,6 +93,7 @@ namespace Avalonia.Designer
public void KillProcess()
{
_host.Kill();
ResetNativeContainer();
}
bool CheckTargetExeOrSetError()

13
src/Windows/Avalonia.Designer/Comm/ProcessHost.cs

@ -7,9 +7,6 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using Avalonia.Designer.Metadata;
namespace Avalonia.Designer.Comm
{
@ -28,9 +25,7 @@ namespace Avalonia.Designer.Comm
OnPropertyChanged();
}
}
public event Action<AvaloniaDesignerMetadata> MetadataArrived;
private bool _isAlive;
private readonly SynchronizationContext _dispatcher;
private Process _proc;
@ -67,6 +62,8 @@ namespace Avalonia.Designer.Comm
void OnExited(object sender, EventArgs eventArgs)
{
if(_proc != sender)
return;
_proc = null;
_dispatcher.Post(_ =>
{
@ -90,6 +87,7 @@ namespace Avalonia.Designer.Comm
_proc.Exited -= OnExited;
try
{
_comm?.Dispose();
_proc.Kill();
}
catch { }
@ -143,9 +141,6 @@ namespace Avalonia.Designer.Comm
var windowMessage = obj as WindowCreatedMessage;
if (windowMessage != null)
WindowHandle = windowMessage.Handle;
var metadata = obj as UpdateMetadataMessage;
if (metadata != null)
_dispatcher.Post(_ => MetadataArrived?.Invoke(metadata.Metadata), null);
}
public void Kill()

20
src/Windows/Avalonia.Designer/Comm/UpdateMetadata.cs

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Designer.Metadata;
namespace Avalonia.Designer.Comm
{
[Serializable]
public class UpdateMetadataMessage
{
public UpdateMetadataMessage(AvaloniaDesignerMetadata metadata)
{
Metadata = metadata;
}
public AvaloniaDesignerMetadata Metadata { get; }
}
}

5
src/Windows/Avalonia.Designer/DemoWindow.xaml

@ -10,11 +10,12 @@
<DockPanel Dock="Bottom" LastChildFill="True">
<TextBlock Margin="5,0">Target Exe: </TextBlock>
<Button DockPanel.Dock="Right">Load XAML</Button>
<Button Margin="5,0" DockPanel.Dock="Right">Select EXE</Button>
<Button Margin="5,0" DockPanel.Dock="Right" Click="SelectExeClicked">Select EXE</Button>
<Button Margin="5,0" DockPanel.Dock="Right" Click="RestartClicked">Restart</Button>
<TextBlock x:Name="TargetExe"/>
</DockPanel>
<UniformGrid Columns="1" Rows="2">
<local:AvaloniaDesigner
<local:AvaloniaDesigner x:Name="Designer"
TargetExe="{Binding ElementName=TargetExe, Path=Text, Mode=OneWay}"
Xaml="{Binding ElementName=Xaml, Path=Text, Mode=OneWay}"/>
<TextBox x:Name="Xaml"/>

21
src/Windows/Avalonia.Designer/DemoWindow.xaml.cs

@ -13,6 +13,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
namespace Avalonia.Designer
{
@ -30,5 +31,25 @@ namespace Avalonia.Designer
if (targetExe != null)
Xaml.Text = File.ReadAllText(targetPath);
}
static string OpenFile(string filter)
{
var dlg = new OpenFileDialog {Filter = filter};
if (dlg.ShowDialog() == true)
return dlg.FileName;
return null;
}
private void SelectExeClicked(object sender, RoutedEventArgs e)
{
var exe = OpenFile("exe|*.exe");
if (exe != null)
TargetExe.Text = exe;
}
private void RestartClicked(object sender, RoutedEventArgs e)
{
Designer.RestartProcess();
}
}
}

51
src/Windows/Avalonia.Designer/Metadata/AvaloniaDesignerMetadata.cs

@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Avalonia.Designer.Metadata
{
[Serializable]
public class AvaloniaDesignerMetadata
{
public List<MetadataType> Types { get; set; }
public List<MetadataNamespaceAlias> NamespaceAliases { get; set; }
}
[Serializable]
public class MetadataType
{
public string Namespace { get; set; }
public string Name { get; set; }
public List<MetadataProperty> Properties { get; set; }
public string FullName => Namespace + "." + Name;
}
[Serializable]
public class MetadataNamespaceAlias
{
public string Namespace { get; set; }
public string XmlNamespace { get; set; }
}
[Serializable]
public class MetadataProperty
{
public string Name { get; set; }
public MetadataPropertyType Type { get; set; }
public string MetadataFullTypeName { get; set; }
public string[] EnumValues { get; set; }
}
[Serializable]
public enum MetadataPropertyType
{
BasicType,
MetadataType,
Enum
}
}
Loading…
Cancel
Save