/// <summary> /// Creates a method that will store all the readers and writers into /// <see cref="Writer{T}.write"/> and <see cref="Reader{T}.read"/> /// /// The method will be marked InitializeOnLoadMethodAttribute so it gets /// executed before mirror runtime code /// </summary> /// <param name="currentAssembly"></param> public static void InitializeReaderAndWriters(AssemblyDefinition currentAssembly) { var rwInitializer = new MethodDefinition("InitReadWriters", MethodAttributes.Public | MethodAttributes.Static, WeaverTypes.Import(typeof(void))); System.Reflection.ConstructorInfo attributeconstructor = typeof(RuntimeInitializeOnLoadMethodAttribute).GetConstructor(new [] { typeof(RuntimeInitializeLoadType) }); var customAttributeRef = new CustomAttribute(currentAssembly.MainModule.ImportReference(attributeconstructor)); customAttributeRef.ConstructorArguments.Add(new CustomAttributeArgument(WeaverTypes.Import <RuntimeInitializeLoadType>(), RuntimeInitializeLoadType.BeforeSceneLoad)); rwInitializer.CustomAttributes.Add(customAttributeRef); if (IsEditorAssembly(currentAssembly)) { // editor assembly, add InitializeOnLoadMethod too. Useful for the editor tests System.Reflection.ConstructorInfo initializeOnLoadConstructor = typeof(InitializeOnLoadMethodAttribute).GetConstructor(new Type[0]); var initializeCustomConstructorRef = new CustomAttribute(currentAssembly.MainModule.ImportReference(initializeOnLoadConstructor)); rwInitializer.CustomAttributes.Add(initializeCustomConstructorRef); } ILProcessor worker = rwInitializer.Body.GetILProcessor(); Writers.InitializeWriters(worker); Readers.InitializeReaders(worker); worker.Append(worker.Create(OpCodes.Ret)); Weaver.WeaveLists.ConfirmGeneratedCodeClass(); TypeDefinition generateClass = Weaver.WeaveLists.generateContainerClass; generateClass.Methods.Add(rwInitializer); }
// adds Mirror.GeneratedNetworkCode.InitReadWriters() method that // registers all generated writers into Mirror.Writer<T> static class. // -> uses [RuntimeInitializeOnLoad] attribute so it's invoke at runtime // -> uses [InitializeOnLoad] if UnityEditor is referenced so it works // in Editor and in tests too // // use ILSpy to see the result (it's in the DLL's 'Mirror' namespace) public static void InitializeReaderAndWriters(AssemblyDefinition currentAssembly) { MethodDefinition rwInitializer = new MethodDefinition("InitReadWriters", MethodAttributes.Public | MethodAttributes.Static, WeaverTypes.Import(typeof(void))); // add [RuntimeInitializeOnLoad] in any case System.Reflection.ConstructorInfo attributeconstructor = typeof(RuntimeInitializeOnLoadMethodAttribute).GetConstructor(new[] { typeof(RuntimeInitializeLoadType) }); CustomAttribute customAttributeRef = new CustomAttribute(currentAssembly.MainModule.ImportReference(attributeconstructor)); customAttributeRef.ConstructorArguments.Add(new CustomAttributeArgument(WeaverTypes.Import <RuntimeInitializeLoadType>(), RuntimeInitializeLoadType.BeforeSceneLoad)); rwInitializer.CustomAttributes.Add(customAttributeRef); // add [InitializeOnLoad] if UnityEditor is referenced if (IsEditorAssembly(currentAssembly)) { System.Reflection.ConstructorInfo initializeOnLoadConstructor = typeof(InitializeOnLoadMethodAttribute).GetConstructor(new Type[0]); CustomAttribute initializeCustomConstructorRef = new CustomAttribute(currentAssembly.MainModule.ImportReference(initializeOnLoadConstructor)); rwInitializer.CustomAttributes.Add(initializeCustomConstructorRef); } // fill function body with reader/writer initializers ILProcessor worker = rwInitializer.Body.GetILProcessor(); // for debugging: add a log to see if initialized on load //worker.Emit(OpCodes.Ldstr, $"[InitReadWriters] called!"); //worker.Emit(OpCodes.Call, WeaverTypes.logWarningReference); Writers.InitializeWriters(worker); Readers.InitializeReaders(worker); worker.Emit(OpCodes.Ret); Weaver.GeneratedCodeClass.Methods.Add(rwInitializer); }
/// <summary> /// Creates a method that will store all the readers and writers into /// <see cref="Writer{T}.Write"/> and <see cref="Reader{T}.Read"/> /// /// The method will be marked InitializeOnLoadMethodAttribute so it gets /// executed before mirror runtime code /// </summary> /// <param name="currentAssembly"></param> public void InitializeReaderAndWriters() { MethodDefinition rwInitializer = module.GeneratedClass().AddMethod( "InitReadWriters", Mono.Cecil.MethodAttributes.Public | Mono.Cecil.MethodAttributes.Static); ConstructorInfo attributeconstructor = typeof(RuntimeInitializeOnLoadMethodAttribute).GetConstructor(new [] { typeof(RuntimeInitializeLoadType) }); var customAttributeRef = new CustomAttribute(module.ImportReference(attributeconstructor)); customAttributeRef.ConstructorArguments.Add(new CustomAttributeArgument(module.ImportReference <RuntimeInitializeLoadType>(), RuntimeInitializeLoadType.BeforeSceneLoad)); rwInitializer.CustomAttributes.Add(customAttributeRef); if (IsEditorAssembly(module)) { // editor assembly, add InitializeOnLoadMethod too. Useful for the editor tests ConstructorInfo initializeOnLoadConstructor = typeof(InitializeOnLoadMethodAttribute).GetConstructor(new Type[0]); var initializeCustomConstructorRef = new CustomAttribute(module.ImportReference(initializeOnLoadConstructor)); rwInitializer.CustomAttributes.Add(initializeCustomConstructorRef); } ILProcessor worker = rwInitializer.Body.GetILProcessor(); writers.InitializeWriters(worker); readers.InitializeReaders(worker); RegisterMessages(worker); worker.Append(worker.Create(OpCodes.Ret)); }
// adds Mirror.GeneratedNetworkCode.InitReadWriters() method that // registers all generated writers into Mirror.Writer<T> static class. // -> uses [RuntimeInitializeOnLoad] attribute so it's invoke at runtime // -> uses [InitializeOnLoad] if UnityEditor is referenced so it works // in Editor and in tests too // // use ILSpy to see the result (it's in the DLL's 'Mirror' namespace) public static void InitializeReaderAndWriters(AssemblyDefinition currentAssembly, WeaverTypes weaverTypes, Writers writers, Readers readers, TypeDefinition GeneratedCodeClass) { MethodDefinition initReadWriters = new MethodDefinition("InitReadWriters", MethodAttributes.Public | MethodAttributes.Static, weaverTypes.Import(typeof(void))); // add [RuntimeInitializeOnLoad] in any case AddRuntimeInitializeOnLoadAttribute(currentAssembly, weaverTypes, initReadWriters); // add [InitializeOnLoad] if UnityEditor is referenced if (Helpers.IsEditorAssembly(currentAssembly)) { AddInitializeOnLoadAttribute(currentAssembly, weaverTypes, initReadWriters); } // fill function body with reader/writer initializers ILProcessor worker = initReadWriters.Body.GetILProcessor(); // for debugging: add a log to see if initialized on load //worker.Emit(OpCodes.Ldstr, $"[InitReadWriters] called!"); //worker.Emit(OpCodes.Call, Weaver.weaverTypes.logWarningReference); writers.InitializeWriters(worker); readers.InitializeReaders(worker); worker.Emit(OpCodes.Ret); GeneratedCodeClass.Methods.Add(initReadWriters); }