mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 19:10:32 +00:00
Weaver: Weave(AssemblyDefinition). WeaveFromFile code moved into CompilationFinishedHook to prepare for ILPP.
This commit is contained in:
parent
ba067d30bf
commit
5f93a7ce7e
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Mono.CecilX;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditor.Compilation;
|
using UnityEditor.Compilation;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -139,7 +140,7 @@ static void OnCompilationFinished(string assemblyPath, CompilerMessage[] message
|
|||||||
Log.Warning = HandleWarning;
|
Log.Warning = HandleWarning;
|
||||||
Log.Error = HandleError;
|
Log.Error = HandleError;
|
||||||
|
|
||||||
if (!Weaver.Weave(assemblyPath, dependencyPaths.ToArray()))
|
if (!WeaveFromFile(assemblyPath, dependencyPaths.ToArray()))
|
||||||
{
|
{
|
||||||
// Set false...will be checked in \Editor\EnterPlayModeSettingsCheck.CheckSuccessfulWeave()
|
// Set false...will be checked in \Editor\EnterPlayModeSettingsCheck.CheckSuccessfulWeave()
|
||||||
SessionState.SetBool("MIRROR_WEAVE_SUCCESS", false);
|
SessionState.SetBool("MIRROR_WEAVE_SUCCESS", false);
|
||||||
@ -167,5 +168,29 @@ static HashSet<string> GetDependecyPaths(string assemblyPath)
|
|||||||
|
|
||||||
return dependencyPaths;
|
return dependencyPaths;
|
||||||
}
|
}
|
||||||
|
// helper function to invoke Weaver with an AssemblyDefinition from a
|
||||||
|
// file path, with dependencies added.
|
||||||
|
static bool WeaveFromFile(string assemblyPath, string[] dependencies)
|
||||||
|
{
|
||||||
|
// open the file as stream
|
||||||
|
using (FileStream stream = new FileStream(assemblyPath, FileMode.Open, FileAccess.ReadWrite))
|
||||||
|
{
|
||||||
|
using (DefaultAssemblyResolver asmResolver = new DefaultAssemblyResolver())
|
||||||
|
using (AssemblyDefinition asmDef = AssemblyDefinition.ReadAssembly(stream, new ReaderParameters { ReadWrite = true, ReadSymbols = true, AssemblyResolver = asmResolver }))
|
||||||
|
{
|
||||||
|
asmResolver.AddSearchDirectory(Path.GetDirectoryName(assemblyPath));
|
||||||
|
asmResolver.AddSearchDirectory(Helpers.UnityEngineDllDirectoryName());
|
||||||
|
if (dependencies != null)
|
||||||
|
{
|
||||||
|
foreach (string path in dependencies)
|
||||||
|
{
|
||||||
|
asmResolver.AddSearchDirectory(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Weaver.Weave(asmDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,72 +125,65 @@ static bool ContainsGeneratedCodeClass(ModuleDefinition module)
|
|||||||
td.Name == GeneratedCodeClassName);
|
td.Name == GeneratedCodeClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Weave(string assName, IEnumerable<string> dependencies)
|
// Weave takes an AssemblyDefinition to be compatible with both old and
|
||||||
|
// new weavers:
|
||||||
|
// * old takes a filepath, new takes a in-memory byte[]
|
||||||
|
// * old uses DefaultAssemblyResolver with added dependencies paths,
|
||||||
|
// new uses ...?
|
||||||
|
public static bool Weave(AssemblyDefinition asmDef)
|
||||||
{
|
{
|
||||||
WeavingFailed = false;
|
WeavingFailed = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (DefaultAssemblyResolver asmResolver = new DefaultAssemblyResolver())
|
CurrentAssembly = asmDef;
|
||||||
using (CurrentAssembly = AssemblyDefinition.ReadAssembly(assName, new ReaderParameters { ReadWrite = true, ReadSymbols = true, AssemblyResolver = asmResolver }))
|
|
||||||
|
// fix "No writer found for ..." error
|
||||||
|
// https://github.com/vis2k/Mirror/issues/2579
|
||||||
|
// -> when restarting Unity, weaver would try to weave a DLL
|
||||||
|
// again
|
||||||
|
// -> resulting in two GeneratedNetworkCode classes (see ILSpy)
|
||||||
|
// -> the second one wouldn't have all the writer types setup
|
||||||
|
if (ContainsGeneratedCodeClass(CurrentAssembly.MainModule))
|
||||||
{
|
{
|
||||||
asmResolver.AddSearchDirectory(Path.GetDirectoryName(assName));
|
//Log.Warning($"Weaver: skipping {CurrentAssembly.Name} because already weaved");
|
||||||
asmResolver.AddSearchDirectory(Helpers.UnityEngineDllDirectoryName());
|
return true;
|
||||||
if (dependencies != null)
|
}
|
||||||
{
|
|
||||||
foreach (string path in dependencies)
|
|
||||||
{
|
|
||||||
asmResolver.AddSearchDirectory(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix "No writer found for ..." error
|
WeaverTypes.SetupTargetTypes(CurrentAssembly);
|
||||||
// https://github.com/vis2k/Mirror/issues/2579
|
|
||||||
// -> when restarting Unity, weaver would try to weave a DLL
|
|
||||||
// again
|
|
||||||
// -> resulting in two GeneratedNetworkCode classes (see ILSpy)
|
|
||||||
// -> the second one wouldn't have all the writer types setup
|
|
||||||
if (ContainsGeneratedCodeClass(CurrentAssembly.MainModule))
|
|
||||||
{
|
|
||||||
//Log.Warning($"Weaver: skipping {CurrentAssembly.Name} because already weaved");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
WeaverTypes.SetupTargetTypes(CurrentAssembly);
|
CreateGeneratedCodeClass();
|
||||||
|
|
||||||
CreateGeneratedCodeClass();
|
// WeaverList depends on WeaverTypes setup because it uses Import
|
||||||
|
WeaveLists = new WeaverLists();
|
||||||
|
|
||||||
// WeaverList depends on WeaverTypes setup because it uses Import
|
System.Diagnostics.Stopwatch rwstopwatch = System.Diagnostics.Stopwatch.StartNew();
|
||||||
WeaveLists = new WeaverLists();
|
// Need to track modified from ReaderWriterProcessor too because it could find custom read/write functions or create functions for NetworkMessages
|
||||||
|
bool modified = ReaderWriterProcessor.Process(CurrentAssembly);
|
||||||
|
rwstopwatch.Stop();
|
||||||
|
Console.WriteLine($"Find all reader and writers took {rwstopwatch.ElapsedMilliseconds} milliseconds");
|
||||||
|
|
||||||
System.Diagnostics.Stopwatch rwstopwatch = System.Diagnostics.Stopwatch.StartNew();
|
ModuleDefinition moduleDefinition = CurrentAssembly.MainModule;
|
||||||
// Need to track modified from ReaderWriterProcessor too because it could find custom read/write functions or create functions for NetworkMessages
|
Console.WriteLine($"Script Module: {moduleDefinition.Name}");
|
||||||
bool modified = ReaderWriterProcessor.Process(CurrentAssembly);
|
|
||||||
rwstopwatch.Stop();
|
|
||||||
Console.WriteLine($"Find all reader and writers took {rwstopwatch.ElapsedMilliseconds} milliseconds");
|
|
||||||
|
|
||||||
ModuleDefinition moduleDefinition = CurrentAssembly.MainModule;
|
modified |= WeaveModule(moduleDefinition);
|
||||||
Console.WriteLine($"Script Module: {moduleDefinition.Name}");
|
|
||||||
|
|
||||||
modified |= WeaveModule(moduleDefinition);
|
if (WeavingFailed)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (WeavingFailed)
|
if (modified)
|
||||||
{
|
{
|
||||||
return false;
|
PropertySiteProcessor.Process(moduleDefinition);
|
||||||
}
|
|
||||||
|
|
||||||
if (modified)
|
// add class that holds read/write functions
|
||||||
{
|
moduleDefinition.Types.Add(GeneratedCodeClass);
|
||||||
PropertySiteProcessor.Process(moduleDefinition);
|
|
||||||
|
|
||||||
// add class that holds read/write functions
|
ReaderWriterProcessor.InitializeReaderAndWriters(CurrentAssembly);
|
||||||
moduleDefinition.Types.Add(GeneratedCodeClass);
|
|
||||||
|
|
||||||
ReaderWriterProcessor.InitializeReaderAndWriters(CurrentAssembly);
|
// write to outputDir if specified, otherwise perform in-place write
|
||||||
|
WriterParameters writeParams = new WriterParameters { WriteSymbols = true };
|
||||||
// write to outputDir if specified, otherwise perform in-place write
|
CurrentAssembly.Write(writeParams);
|
||||||
WriterParameters writeParams = new WriterParameters { WriteSymbols = true };
|
|
||||||
CurrentAssembly.Write(writeParams);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user