From 74b9c8034e1dd516097902935b78f175ed3b4103 Mon Sep 17 00:00:00 2001 From: vis2k Date: Tue, 28 Sep 2021 15:38:06 +0800 Subject: [PATCH] Weaver: NetworkBehaviourProcessor.InjectIntoConstructor split into cctor & ctor functions --- .../Processors/NetworkBehaviourProcessor.cs | 76 ++++++++++--------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/Assets/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs b/Assets/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs index 1fd92794d..9324c5113 100644 --- a/Assets/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs +++ b/Assets/Mirror/Editor/Weaver/Processors/NetworkBehaviourProcessor.cs @@ -91,8 +91,9 @@ public bool Process(ref bool WeavingFailed) return true; } - // inject initializations into constructor - InjectIntoConstructor(ref WeavingFailed); + // inject initializations into static & instance constructor + InjectIntoStaticConstructor(ref WeavingFailed); + InjectIntoInstanceConstructor(ref WeavingFailed); GenerateSerialization(ref WeavingFailed); if (WeavingFailed) @@ -253,11 +254,10 @@ static bool RemoveFinalRetInstruction(MethodDefinition method) return true; } - // we need to inject several initializations into NetworkBehaviour - // static and regular constructors - void InjectIntoConstructor(ref bool WeavingFailed) + // we need to inject several initializations into NetworkBehaviour cctor + void InjectIntoStaticConstructor(ref bool WeavingFailed) { - if (commands.Count == 0 && clientRpcs.Count == 0 && targetRpcs.Count == 0 && syncObjects.Count == 0) + if (commands.Count == 0 && clientRpcs.Count == 0 && targetRpcs.Count == 0) return; // find static constructor @@ -284,26 +284,6 @@ void InjectIntoConstructor(ref bool WeavingFailed) weaverTypes.Import(typeof(void))); } - // find instance constructor - MethodDefinition ctor = netBehaviourSubclass.GetMethod(".ctor"); - - if (ctor == null) - { - Log.Error($"{netBehaviourSubclass.Name} has invalid constructor", netBehaviourSubclass); - WeavingFailed = true; - return; - } - - // remove the return opcode from end of function. will add our own later. - if (!RemoveFinalRetInstruction(ctor)) - { - Log.Error($"{netBehaviourSubclass.Name} has invalid constructor", ctor); - WeavingFailed = true; - return; - } - - // TODO: find out if the order below matters. If it doesn't split code below into 2 functions - ILProcessor ctorWorker = ctor.Body.GetILProcessor(); ILProcessor cctorWorker = cctor.Body.GetILProcessor(); // register all commands in cctor @@ -326,12 +306,6 @@ void InjectIntoConstructor(ref bool WeavingFailed) GenerateRegisterRemoteDelegate(cctorWorker, weaverTypes, weaverTypes.registerRpcDelegateReference, targetRpcInvocationFuncs[i], targetRpcs[i].Name); } - // initialize all sync objects in ctor - foreach (FieldDefinition fd in syncObjects) - { - SyncObjectInitializer.GenerateSyncObjectInitializer(ctorWorker, weaverTypes, fd); - } - // add final 'Ret' instruction to cctor cctorWorker.Append(cctorWorker.Create(OpCodes.Ret)); if (!cctorFound) @@ -339,13 +313,45 @@ void InjectIntoConstructor(ref bool WeavingFailed) netBehaviourSubclass.Methods.Add(cctor); } - // add final 'Ret' instruction to ctor - ctorWorker.Append(ctorWorker.Create(OpCodes.Ret)); - // in case class had no cctor, it might have BeforeFieldInit, so injected cctor would be called too late netBehaviourSubclass.Attributes &= ~TypeAttributes.BeforeFieldInit; } + // we need to inject several initializations into NetworkBehaviour ctor + void InjectIntoInstanceConstructor(ref bool WeavingFailed) + { + if (syncObjects.Count == 0) + return; + + // find instance constructor + MethodDefinition ctor = netBehaviourSubclass.GetMethod(".ctor"); + if (ctor == null) + { + Log.Error($"{netBehaviourSubclass.Name} has invalid constructor", netBehaviourSubclass); + WeavingFailed = true; + return; + } + + // remove the return opcode from end of function. will add our own later. + if (!RemoveFinalRetInstruction(ctor)) + { + Log.Error($"{netBehaviourSubclass.Name} has invalid constructor", ctor); + WeavingFailed = true; + return; + } + + ILProcessor ctorWorker = ctor.Body.GetILProcessor(); + + // initialize all sync objects in ctor + foreach (FieldDefinition fd in syncObjects) + { + SyncObjectInitializer.GenerateSyncObjectInitializer(ctorWorker, weaverTypes, fd); + } + + // add final 'Ret' instruction to ctor + ctorWorker.Append(ctorWorker.Create(OpCodes.Ret)); + } + /* // This generates code like: NetworkBehaviour.RegisterCommandDelegate(base.GetType(), "CmdThrust", new NetworkBehaviour.CmdDelegate(ShipControl.InvokeCmdCmdThrust));