Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ParadoxCommandsProxy.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.IO;
5 using System.Reflection;
6 using System.Runtime.InteropServices;
7 using EnvDTE;
8 using EnvDTE80;
9 using SiliconStudio.Assets;
10 
11 namespace SiliconStudio.Paradox.VisualStudio.Commands
12 {
13  /// <summary>
14  /// Proxies commands to real <see cref="IParadoxCommands"/> implementation.
15  /// </summary>
17  {
18  private static object computedParadoxSdkDirLock = new object();
19  private static string computedParadoxSdkDir = null;
20  private IParadoxCommands remote;
21 
22  static ParadoxCommandsProxy()
23  {
24  AppDomain.CurrentDomain.AssemblyResolve += domain_AssemblyResolve;
25  }
26 
28  {
29  var assembly = Assembly.Load("SiliconStudio.Paradox.VisualStudio.Commands");
30  remote = (IParadoxCommands)assembly.CreateInstance("SiliconStudio.Paradox.VisualStudio.Commands.ParadoxCommands");
31  }
32 
33  public static string ParadoxSdkDir
34  {
35  get
36  {
37  lock (computedParadoxSdkDirLock)
38  {
39  if (computedParadoxSdkDir == null)
40  computedParadoxSdkDir = FindParadoxSdkDir();
41 
42  return computedParadoxSdkDir;
43  }
44  }
45  }
46 
47  public static AppDomain CreateAppDomain()
48  {
49  return AppDomain.CreateDomain("paradox-domain");
50  }
51 
52  public static ParadoxCommandsProxy CreateProxy(AppDomain domain)
53  {
54  bool createDomain = domain == null;
55  if (createDomain)
56  domain = CreateAppDomain();
57 
58  try
59  {
60  return (ParadoxCommandsProxy)domain.CreateInstanceFromAndUnwrap(typeof(ParadoxCommandsProxy).Assembly.Location, typeof(ParadoxCommandsProxy).FullName);
61  }
62  catch
63  {
64  if (createDomain)
65  AppDomain.Unload(domain);
66  throw;
67  }
68  }
69 
70  static Assembly LoadAssembly(string assemblyFile, bool shadowMemoryCopy)
71  {
72  if (shadowMemoryCopy)
73  {
74  // Check if .pdb exists as well
75  var pdbFile = Path.ChangeExtension(assemblyFile, "pdb");
76  if (File.Exists(pdbFile))
77  return Assembly.Load(File.ReadAllBytes(assemblyFile), File.ReadAllBytes(pdbFile));
78 
79  // Otherwise load assembly without PDB
80  return Assembly.Load(File.ReadAllBytes(assemblyFile));
81  }
82 
83  // Load from HDD directly
84  return Assembly.Load(assemblyFile);
85  }
86 
87  static Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args)
88  {
89  if (args.Name == Assembly.GetExecutingAssembly().FullName)
90  return Assembly.GetExecutingAssembly();
91 
92  var paradoxSdkDir = ParadoxSdkDir;
93  if (paradoxSdkDir == null)
94  return null;
95 
96  var paradoxSdkBinDir = Path.Combine(paradoxSdkDir, @"Bin\Windows-Direct3D11");
97 
98  // Try to load .dll/.exe from Paradox SDK directory
99  var assemblyName = new AssemblyName(args.Name);
100  var assemblyFile = Path.Combine(paradoxSdkBinDir, assemblyName.Name + ".dll");
101  if (File.Exists(assemblyFile))
102  return LoadAssembly(assemblyFile, true);
103 
104  assemblyFile = Path.Combine(paradoxSdkBinDir, assemblyName.Name + ".exe");
105  if (File.Exists(assemblyFile))
106  return LoadAssembly(assemblyFile, true);
107 
108  return null;
109  }
110 
111  public void StartRemoteBuildLogServer(IBuildMonitorCallback buildMonitorCallback, string logPipeUrl)
112  {
113  remote.StartRemoteBuildLogServer(buildMonitorCallback, logPipeUrl);
114  }
115 
116  public byte[] GenerateShaderKeys(string inputFileName, string inputFileContent)
117  {
118  return remote.GenerateShaderKeys(inputFileName, inputFileContent);
119  }
120 
121  public byte[] GenerateDataClasses(string assemblyOutput, string projectFullName, string intermediateAssembly)
122  {
123  return remote.GenerateDataClasses(assemblyOutput, projectFullName, intermediateAssembly);
124  }
125 
126  /// <summary>
127  /// Gets the paradox SDK dir.
128  /// </summary>
129  /// <returns></returns>
130  private static string FindParadoxSdkDir()
131  {
132  // TODO: Maybe move it in some common class somewhere? (in this case it would be included with "Add as link" in VSPackage)
133  var paradoxSdkDir = Environment.GetEnvironmentVariable("SiliconStudioParadoxDir");
134 
135  // Check if it is a dev directory
136  if (File.Exists(Path.Combine(paradoxSdkDir, "build\\Paradox.sln")))
137  return paradoxSdkDir;
138 
139  // Check if we are in a root directory with store/packages facilities
140  if (NugetStore.IsStoreDirectory(paradoxSdkDir))
141  {
142  var store = new NugetStore(paradoxSdkDir) { DefaultPackageId = "Paradox" };
143 
144  var paradoxPackage = store.GetLatestPackageInstalled(store.DefaultPackageId);
145  if (paradoxPackage == null)
146  return null;
147 
148  var packageDirectory = store.PathResolver.GetPackageDirectory(paradoxPackage);
149  return Path.Combine(paradoxSdkDir, NugetStore.DefaultGamePackagesDirectory, packageDirectory);
150  }
151 
152  return null;
153  }
154  }
155 }
Proxies commands to real IParadoxCommands implementation.
void StartRemoteBuildLogServer(IBuildMonitorCallback buildMonitorCallback, string logPipeUrl)
System.IO.File File
static ParadoxCommandsProxy CreateProxy(AppDomain domain)
Describes paradox commands accessed by VS Package to current paradox package (so that VSPackage doesn...
byte[] GenerateDataClasses(string assemblyOutput, string projectFullName, string intermediateAssembly)
byte[] GenerateShaderKeys(string inputFileName, string inputFileContent)