mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
Weaver: NetworkBehaviourProcessor.InjectIntoConstructor split into cctor & ctor functions
This commit is contained in:
parent
d7516a8c95
commit
74b9c8034e
@ -91,8 +91,9 @@ public bool Process(ref bool WeavingFailed)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// inject initializations into constructor
|
// inject initializations into static & instance constructor
|
||||||
InjectIntoConstructor(ref WeavingFailed);
|
InjectIntoStaticConstructor(ref WeavingFailed);
|
||||||
|
InjectIntoInstanceConstructor(ref WeavingFailed);
|
||||||
|
|
||||||
GenerateSerialization(ref WeavingFailed);
|
GenerateSerialization(ref WeavingFailed);
|
||||||
if (WeavingFailed)
|
if (WeavingFailed)
|
||||||
@ -253,11 +254,10 @@ static bool RemoveFinalRetInstruction(MethodDefinition method)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to inject several initializations into NetworkBehaviour
|
// we need to inject several initializations into NetworkBehaviour cctor
|
||||||
// static and regular constructors
|
void InjectIntoStaticConstructor(ref bool WeavingFailed)
|
||||||
void InjectIntoConstructor(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;
|
return;
|
||||||
|
|
||||||
// find static constructor
|
// find static constructor
|
||||||
@ -284,26 +284,6 @@ void InjectIntoConstructor(ref bool WeavingFailed)
|
|||||||
weaverTypes.Import(typeof(void)));
|
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();
|
ILProcessor cctorWorker = cctor.Body.GetILProcessor();
|
||||||
|
|
||||||
// register all commands in cctor
|
// register all commands in cctor
|
||||||
@ -326,12 +306,6 @@ void InjectIntoConstructor(ref bool WeavingFailed)
|
|||||||
GenerateRegisterRemoteDelegate(cctorWorker, weaverTypes, weaverTypes.registerRpcDelegateReference, targetRpcInvocationFuncs[i], targetRpcs[i].Name);
|
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
|
// add final 'Ret' instruction to cctor
|
||||||
cctorWorker.Append(cctorWorker.Create(OpCodes.Ret));
|
cctorWorker.Append(cctorWorker.Create(OpCodes.Ret));
|
||||||
if (!cctorFound)
|
if (!cctorFound)
|
||||||
@ -339,13 +313,45 @@ void InjectIntoConstructor(ref bool WeavingFailed)
|
|||||||
netBehaviourSubclass.Methods.Add(cctor);
|
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
|
// in case class had no cctor, it might have BeforeFieldInit, so injected cctor would be called too late
|
||||||
netBehaviourSubclass.Attributes &= ~TypeAttributes.BeforeFieldInit;
|
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:
|
// This generates code like:
|
||||||
NetworkBehaviour.RegisterCommandDelegate(base.GetType(), "CmdThrust", new NetworkBehaviour.CmdDelegate(ShipControl.InvokeCmdCmdThrust));
|
NetworkBehaviour.RegisterCommandDelegate(base.GetType(), "CmdThrust", new NetworkBehaviour.CmdDelegate(ShipControl.InvokeCmdCmdThrust));
|
||||||
|
Loading…
Reference in New Issue
Block a user