Browse Source

Designer: Implemented metadata transfer

pull/148/head
Nikita Tsukanov 11 years ago
parent
commit
a4a5df0289
  1. 85
      src/Windows/Perspex.Designer/AppHost/PerspexAppHost.cs
  2. 6
      src/Windows/Perspex.Designer/Comm/ProcessHost.cs
  3. 20
      src/Windows/Perspex.Designer/Comm/UpdateMetadata.cs
  4. 51
      src/Windows/Perspex.Designer/Metadata/PerspexDesignerMetadata.cs
  5. 2
      src/Windows/Perspex.Designer/Perspex.Designer.csproj
  6. 4
      src/Windows/Perspex.Designer/PerspexDesigner.xaml.cs

85
src/Windows/Perspex.Designer/AppHost/PerspexAppHost.cs

@ -4,10 +4,13 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Forms;
using Perspex.Designer.Comm;
using Perspex.Designer.Metadata;
using Timer = System.Windows.Forms.Timer;
namespace Perspex.Designer.AppHost
{
@ -81,6 +84,84 @@ namespace Perspex.Designer.AppHost
UpdateState("Unable to load Perspex:\n\n" + e + "\n\n" + log);
}
}
PerspexDesignerMetadata BuildMetadata(List<Assembly> asms)
{
var rv = new PerspexDesignerMetadata()
{
NamespaceAliases = new List<MetadataNamespaceAlias>
{
new MetadataNamespaceAlias
{
Namespace = "Perspex.Controls",
XmlNamespace = "https://github.com/grokys/Perspex"
}
},
Types = new List<MetadataType>()
};
foreach (var asm in asms)
{
try
{
foreach (var type in asm.GetTypes())
{
try
{
if (!type.IsPublic)
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)
{
new Thread(() =>
{
_comm.SendMessage(new UpdateMetadataMessage(BuildMetadata(asms)));
}).Start();
}
private void DoInit(string targetExe, StringBuilder logger)
{
_appDir = Path.GetFullPath(Path.GetDirectoryName(targetExe));
@ -91,16 +172,18 @@ namespace Perspex.Designer.AppHost
logger.AppendLine(s);
};
log("Loading assemblies from " + _appDir);
var asms = new List<Assembly>();
foreach(var asm in Directory.GetFiles(_appDir).Where(f=>f.ToLower().EndsWith(".dll")||f.ToLower().EndsWith(".exe")))
try
{
log("Trying to load " + asm);
Assembly.LoadFrom(asm);
asms.Add(Assembly.LoadFrom(asm));
}
catch (Exception e)
{
logger.AppendLine(e.ToString());
}
BuildMetadataAndSendMessageAsync(asms);
log("Looking up Perspex types");
var syncContext = LookupType("Perspex.Threading.PerspexSynchronizationContext");
syncContext.GetProperty("AutoInstall", BindingFlags.Public | BindingFlags.Static).SetValue(null, false);

6
src/Windows/Perspex.Designer/Comm/ProcessHost.cs

@ -9,6 +9,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using Perspex.Designer.Metadata;
namespace Perspex.Designer.Comm
{
@ -28,6 +29,8 @@ namespace Perspex.Designer.Comm
}
}
public event Action<PerspexDesignerMetadata> MetadataArrived;
private bool _isAlive;
private readonly SynchronizationContext _dispatcher;
private Process _proc;
@ -140,6 +143,9 @@ namespace Perspex.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/Perspex.Designer/Comm/UpdateMetadata.cs

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

51
src/Windows/Perspex.Designer/Metadata/PerspexDesignerMetadata.cs

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Perspex.Designer.Metadata
{
[Serializable]
public class PerspexDesignerMetadata
{
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
}
}

2
src/Windows/Perspex.Designer/Perspex.Designer.csproj

@ -74,12 +74,14 @@
<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">
<DependentUpon>DemoWindow.xaml</DependentUpon>
</Compile>
<Compile Include="DesignerAppHost.cs" />
<Compile Include="Metadata\PerspexDesignerMetadata.cs" />
<Compile Include="PerspexDesigner.xaml.cs">
<DependentUpon>PerspexDesigner.xaml</DependentUpon>
</Compile>

4
src/Windows/Perspex.Designer/PerspexDesigner.xaml.cs

@ -18,6 +18,7 @@ using System.Windows.Navigation;
using System.Windows.Shapes;
using Perspex.Designer.AppHost;
using Perspex.Designer.Comm;
using Perspex.Designer.Metadata;
namespace Perspex.Designer
{
@ -53,6 +54,8 @@ namespace Perspex.Designer
set { SetValue(XamlProperty, value); }
}
public PerspexDesignerMetadata Metadata { get; private set; }
private readonly ProcessHost _host = new ProcessHost();
@ -63,6 +66,7 @@ namespace Perspex.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)

Loading…
Cancel
Save