mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
Weaver: WeaverLists renamed to SyncVarAccessLists because that's what it's for
This commit is contained in:
parent
3dbab83615
commit
37af48b83e
@ -16,7 +16,7 @@ class NetworkBehaviourProcessor
|
|||||||
{
|
{
|
||||||
AssemblyDefinition assembly;
|
AssemblyDefinition assembly;
|
||||||
WeaverTypes weaverTypes;
|
WeaverTypes weaverTypes;
|
||||||
WeaverLists weaverLists;
|
SyncVarAccessLists syncVarAccessLists;
|
||||||
SyncVarProcessor syncVarProcessor;
|
SyncVarProcessor syncVarProcessor;
|
||||||
Writers writers;
|
Writers writers;
|
||||||
Readers readers;
|
Readers readers;
|
||||||
@ -47,15 +47,15 @@ public struct ClientRpcResult
|
|||||||
public bool includeOwner;
|
public bool includeOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkBehaviourProcessor(AssemblyDefinition assembly, WeaverTypes weaverTypes, WeaverLists weaverLists, Writers writers, Readers readers, Logger Log, TypeDefinition td)
|
public NetworkBehaviourProcessor(AssemblyDefinition assembly, WeaverTypes weaverTypes, SyncVarAccessLists syncVarAccessLists, Writers writers, Readers readers, Logger Log, TypeDefinition td)
|
||||||
{
|
{
|
||||||
this.assembly = assembly;
|
this.assembly = assembly;
|
||||||
this.weaverTypes = weaverTypes;
|
this.weaverTypes = weaverTypes;
|
||||||
this.weaverLists = weaverLists;
|
this.syncVarAccessLists = syncVarAccessLists;
|
||||||
this.writers = writers;
|
this.writers = writers;
|
||||||
this.readers = readers;
|
this.readers = readers;
|
||||||
this.Log = Log;
|
this.Log = Log;
|
||||||
syncVarProcessor = new SyncVarProcessor(assembly, weaverTypes, weaverLists, Log);
|
syncVarProcessor = new SyncVarProcessor(assembly, weaverTypes, syncVarAccessLists, Log);
|
||||||
netBehaviourSubclass = td;
|
netBehaviourSubclass = td;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,7 +453,7 @@ void GenerateSerialization(ref bool WeavingFailed)
|
|||||||
// generate a writer call for any dirty variable in this class
|
// generate a writer call for any dirty variable in this class
|
||||||
|
|
||||||
// start at number of syncvars in parent
|
// start at number of syncvars in parent
|
||||||
int dirtyBit = weaverLists.GetSyncVarStart(netBehaviourSubclass.BaseType.FullName);
|
int dirtyBit = syncVarAccessLists.GetSyncVarStart(netBehaviourSubclass.BaseType.FullName);
|
||||||
foreach (FieldDefinition syncVar in syncVars)
|
foreach (FieldDefinition syncVar in syncVars)
|
||||||
{
|
{
|
||||||
Instruction varLabel = worker.Create(OpCodes.Nop);
|
Instruction varLabel = worker.Create(OpCodes.Nop);
|
||||||
@ -865,7 +865,7 @@ void GenerateDeSerialization(ref bool WeavingFailed)
|
|||||||
|
|
||||||
// conditionally read each syncvar
|
// conditionally read each syncvar
|
||||||
// start at number of syncvars in parent
|
// start at number of syncvars in parent
|
||||||
int dirtyBit = weaverLists.GetSyncVarStart(netBehaviourSubclass.BaseType.FullName);
|
int dirtyBit = syncVarAccessLists.GetSyncVarStart(netBehaviourSubclass.BaseType.FullName);
|
||||||
foreach (FieldDefinition syncVar in syncVars)
|
foreach (FieldDefinition syncVar in syncVars)
|
||||||
{
|
{
|
||||||
Instruction varLabel = serWorker.Create(OpCodes.Nop);
|
Instruction varLabel = serWorker.Create(OpCodes.Nop);
|
||||||
|
@ -11,7 +11,7 @@ namespace Mirror.Weaver
|
|||||||
public static class SyncVarAccessReplacer
|
public static class SyncVarAccessReplacer
|
||||||
{
|
{
|
||||||
// process the module
|
// process the module
|
||||||
public static void Process(ModuleDefinition moduleDef, WeaverLists weaverLists)
|
public static void Process(ModuleDefinition moduleDef, SyncVarAccessLists syncVarAccessLists)
|
||||||
{
|
{
|
||||||
DateTime startTime = DateTime.Now;
|
DateTime startTime = DateTime.Now;
|
||||||
|
|
||||||
@ -20,31 +20,31 @@ public static void Process(ModuleDefinition moduleDef, WeaverLists weaverLists)
|
|||||||
{
|
{
|
||||||
if (td.IsClass)
|
if (td.IsClass)
|
||||||
{
|
{
|
||||||
ProcessClass(weaverLists, td);
|
ProcessClass(syncVarAccessLists, td);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($" ProcessSitesModule {moduleDef.Name} elapsed time:{(DateTime.Now - startTime)}");
|
Console.WriteLine($" ProcessSitesModule {moduleDef.Name} elapsed time:{(DateTime.Now - startTime)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessClass(WeaverLists weaverLists, TypeDefinition td)
|
static void ProcessClass(SyncVarAccessLists syncVarAccessLists, TypeDefinition td)
|
||||||
{
|
{
|
||||||
//Console.WriteLine(" ProcessClass " + td);
|
//Console.WriteLine(" ProcessClass " + td);
|
||||||
|
|
||||||
// process all methods in this class
|
// process all methods in this class
|
||||||
foreach (MethodDefinition md in td.Methods)
|
foreach (MethodDefinition md in td.Methods)
|
||||||
{
|
{
|
||||||
ProcessMethod(weaverLists, md);
|
ProcessMethod(syncVarAccessLists, md);
|
||||||
}
|
}
|
||||||
|
|
||||||
// processes all nested classes in this class recursively
|
// processes all nested classes in this class recursively
|
||||||
foreach (TypeDefinition nested in td.NestedTypes)
|
foreach (TypeDefinition nested in td.NestedTypes)
|
||||||
{
|
{
|
||||||
ProcessClass(weaverLists, nested);
|
ProcessClass(syncVarAccessLists, nested);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessMethod(WeaverLists weaverLists, MethodDefinition md)
|
static void ProcessMethod(SyncVarAccessLists syncVarAccessLists, MethodDefinition md)
|
||||||
{
|
{
|
||||||
// process all references to replaced members with properties
|
// process all references to replaced members with properties
|
||||||
//Weaver.DLog(td, " ProcessSiteMethod " + md);
|
//Weaver.DLog(td, " ProcessSiteMethod " + md);
|
||||||
@ -67,24 +67,24 @@ static void ProcessMethod(WeaverLists weaverLists, MethodDefinition md)
|
|||||||
for (int i = 0; i < md.Body.Instructions.Count;)
|
for (int i = 0; i < md.Body.Instructions.Count;)
|
||||||
{
|
{
|
||||||
Instruction instr = md.Body.Instructions[i];
|
Instruction instr = md.Body.Instructions[i];
|
||||||
i += ProcessInstruction(weaverLists, md, instr, i);
|
i += ProcessInstruction(syncVarAccessLists, md, instr, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ProcessInstruction(WeaverLists weaverLists, MethodDefinition md, Instruction instr, int iCount)
|
static int ProcessInstruction(SyncVarAccessLists syncVarAccessLists, MethodDefinition md, Instruction instr, int iCount)
|
||||||
{
|
{
|
||||||
// stfld (sets value of a field)?
|
// stfld (sets value of a field)?
|
||||||
if (instr.OpCode == OpCodes.Stfld && instr.Operand is FieldDefinition opFieldst)
|
if (instr.OpCode == OpCodes.Stfld && instr.Operand is FieldDefinition opFieldst)
|
||||||
{
|
{
|
||||||
ProcessSetInstruction(weaverLists, md, instr, opFieldst);
|
ProcessSetInstruction(syncVarAccessLists, md, instr, opFieldst);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ldfld (load value of a field)?
|
// ldfld (load value of a field)?
|
||||||
if (instr.OpCode == OpCodes.Ldfld && instr.Operand is FieldDefinition opFieldld)
|
if (instr.OpCode == OpCodes.Ldfld && instr.Operand is FieldDefinition opFieldld)
|
||||||
{
|
{
|
||||||
// this instruction gets the value of a field. cache the field reference.
|
// this instruction gets the value of a field. cache the field reference.
|
||||||
ProcessGetInstruction(weaverLists, md, instr, opFieldld);
|
ProcessGetInstruction(syncVarAccessLists, md, instr, opFieldld);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ldflda (load field address aka reference)
|
// ldflda (load field address aka reference)
|
||||||
@ -92,7 +92,7 @@ static int ProcessInstruction(WeaverLists weaverLists, MethodDefinition md, Inst
|
|||||||
{
|
{
|
||||||
// watch out for initobj instruction
|
// watch out for initobj instruction
|
||||||
// see https://github.com/vis2k/Mirror/issues/696
|
// see https://github.com/vis2k/Mirror/issues/696
|
||||||
return ProcessLoadAddressInstruction(weaverLists, md, instr, opFieldlda, iCount);
|
return ProcessLoadAddressInstruction(syncVarAccessLists, md, instr, opFieldlda, iCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we processed one instruction (instr)
|
// we processed one instruction (instr)
|
||||||
@ -100,14 +100,14 @@ static int ProcessInstruction(WeaverLists weaverLists, MethodDefinition md, Inst
|
|||||||
}
|
}
|
||||||
|
|
||||||
// replaces syncvar write access with the NetworkXYZ.set property calls
|
// replaces syncvar write access with the NetworkXYZ.set property calls
|
||||||
static void ProcessSetInstruction(WeaverLists weaverLists, MethodDefinition md, Instruction i, FieldDefinition opField)
|
static void ProcessSetInstruction(SyncVarAccessLists syncVarAccessLists, MethodDefinition md, Instruction i, FieldDefinition opField)
|
||||||
{
|
{
|
||||||
// don't replace property call sites in constructors
|
// don't replace property call sites in constructors
|
||||||
if (md.Name == ".ctor")
|
if (md.Name == ".ctor")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// does it set a field that we replaced?
|
// does it set a field that we replaced?
|
||||||
if (weaverLists.replacementSetterProperties.TryGetValue(opField, out MethodDefinition replacement))
|
if (syncVarAccessLists.replacementSetterProperties.TryGetValue(opField, out MethodDefinition replacement))
|
||||||
{
|
{
|
||||||
//replace with property
|
//replace with property
|
||||||
//DLog(td, " replacing " + md.Name + ":" + i);
|
//DLog(td, " replacing " + md.Name + ":" + i);
|
||||||
@ -118,14 +118,14 @@ static void ProcessSetInstruction(WeaverLists weaverLists, MethodDefinition md,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// replaces syncvar read access with the NetworkXYZ.get property calls
|
// replaces syncvar read access with the NetworkXYZ.get property calls
|
||||||
static void ProcessGetInstruction(WeaverLists weaverLists, MethodDefinition md, Instruction i, FieldDefinition opField)
|
static void ProcessGetInstruction(SyncVarAccessLists syncVarAccessLists, MethodDefinition md, Instruction i, FieldDefinition opField)
|
||||||
{
|
{
|
||||||
// don't replace property call sites in constructors
|
// don't replace property call sites in constructors
|
||||||
if (md.Name == ".ctor")
|
if (md.Name == ".ctor")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// does it set a field that we replaced?
|
// does it set a field that we replaced?
|
||||||
if (weaverLists.replacementGetterProperties.TryGetValue(opField, out MethodDefinition replacement))
|
if (syncVarAccessLists.replacementGetterProperties.TryGetValue(opField, out MethodDefinition replacement))
|
||||||
{
|
{
|
||||||
//replace with property
|
//replace with property
|
||||||
//DLog(td, " replacing " + md.Name + ":" + i);
|
//DLog(td, " replacing " + md.Name + ":" + i);
|
||||||
@ -135,14 +135,14 @@ static void ProcessGetInstruction(WeaverLists weaverLists, MethodDefinition md,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ProcessLoadAddressInstruction(WeaverLists weaverLists, MethodDefinition md, Instruction instr, FieldDefinition opField, int iCount)
|
static int ProcessLoadAddressInstruction(SyncVarAccessLists syncVarAccessLists, MethodDefinition md, Instruction instr, FieldDefinition opField, int iCount)
|
||||||
{
|
{
|
||||||
// don't replace property call sites in constructors
|
// don't replace property call sites in constructors
|
||||||
if (md.Name == ".ctor")
|
if (md.Name == ".ctor")
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// does it set a field that we replaced?
|
// does it set a field that we replaced?
|
||||||
if (weaverLists.replacementSetterProperties.TryGetValue(opField, out MethodDefinition replacement))
|
if (syncVarAccessLists.replacementSetterProperties.TryGetValue(opField, out MethodDefinition replacement))
|
||||||
{
|
{
|
||||||
// we have a replacement for this property
|
// we have a replacement for this property
|
||||||
// is the next instruction a initobj?
|
// is the next instruction a initobj?
|
||||||
|
@ -14,17 +14,17 @@ public class SyncVarProcessor
|
|||||||
|
|
||||||
AssemblyDefinition assembly;
|
AssemblyDefinition assembly;
|
||||||
WeaverTypes weaverTypes;
|
WeaverTypes weaverTypes;
|
||||||
WeaverLists weaverLists;
|
SyncVarAccessLists syncVarAccessLists;
|
||||||
Logger Log;
|
Logger Log;
|
||||||
|
|
||||||
string HookParameterMessage(string hookName, TypeReference ValueType) =>
|
string HookParameterMessage(string hookName, TypeReference ValueType) =>
|
||||||
$"void {hookName}({ValueType} oldValue, {ValueType} newValue)";
|
$"void {hookName}({ValueType} oldValue, {ValueType} newValue)";
|
||||||
|
|
||||||
public SyncVarProcessor(AssemblyDefinition assembly, WeaverTypes weaverTypes, WeaverLists weaverLists, Logger Log)
|
public SyncVarProcessor(AssemblyDefinition assembly, WeaverTypes weaverTypes, SyncVarAccessLists syncVarAccessLists, Logger Log)
|
||||||
{
|
{
|
||||||
this.assembly = assembly;
|
this.assembly = assembly;
|
||||||
this.weaverTypes = weaverTypes;
|
this.weaverTypes = weaverTypes;
|
||||||
this.weaverLists = weaverLists;
|
this.syncVarAccessLists = syncVarAccessLists;
|
||||||
this.Log = Log;
|
this.Log = Log;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +342,7 @@ public void ProcessSyncVar(TypeDefinition td, FieldDefinition fd, Dictionary<Fie
|
|||||||
td.Methods.Add(get);
|
td.Methods.Add(get);
|
||||||
td.Methods.Add(set);
|
td.Methods.Add(set);
|
||||||
td.Properties.Add(propertyDefinition);
|
td.Properties.Add(propertyDefinition);
|
||||||
weaverLists.replacementSetterProperties[fd] = set;
|
syncVarAccessLists.replacementSetterProperties[fd] = set;
|
||||||
|
|
||||||
// replace getter field if GameObject/NetworkIdentity so it uses
|
// replace getter field if GameObject/NetworkIdentity so it uses
|
||||||
// netId instead
|
// netId instead
|
||||||
@ -350,7 +350,7 @@ public void ProcessSyncVar(TypeDefinition td, FieldDefinition fd, Dictionary<Fie
|
|||||||
// end up in recursion.
|
// end up in recursion.
|
||||||
if (fd.FieldType.IsNetworkIdentityField())
|
if (fd.FieldType.IsNetworkIdentityField())
|
||||||
{
|
{
|
||||||
weaverLists.replacementGetterProperties[fd] = get;
|
syncVarAccessLists.replacementGetterProperties[fd] = get;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,7 +361,7 @@ public void ProcessSyncVar(TypeDefinition td, FieldDefinition fd, Dictionary<Fie
|
|||||||
|
|
||||||
// the mapping of dirtybits to sync-vars is implicit in the order of the fields here. this order is recorded in m_replacementProperties.
|
// the mapping of dirtybits to sync-vars is implicit in the order of the fields here. this order is recorded in m_replacementProperties.
|
||||||
// start assigning syncvars at the place the base class stopped, if any
|
// start assigning syncvars at the place the base class stopped, if any
|
||||||
int dirtyBitCounter = weaverLists.GetSyncVarStart(td.BaseType.FullName);
|
int dirtyBitCounter = syncVarAccessLists.GetSyncVarStart(td.BaseType.FullName);
|
||||||
|
|
||||||
// find syncvars
|
// find syncvars
|
||||||
foreach (FieldDefinition fd in td.Fields)
|
foreach (FieldDefinition fd in td.Fields)
|
||||||
@ -408,7 +408,7 @@ public void ProcessSyncVar(TypeDefinition td, FieldDefinition fd, Dictionary<Fie
|
|||||||
{
|
{
|
||||||
td.Fields.Add(fd);
|
td.Fields.Add(fd);
|
||||||
}
|
}
|
||||||
weaverLists.SetNumSyncVars(td.FullName, syncVars.Count);
|
syncVarAccessLists.SetNumSyncVars(td.FullName, syncVars.Count);
|
||||||
|
|
||||||
return (syncVars, syncVarNetIds);
|
return (syncVars, syncVarNetIds);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
namespace Mirror.Weaver
|
namespace Mirror.Weaver
|
||||||
{
|
{
|
||||||
// This data is flushed each time - if we are run multiple times in the same process/domain
|
// This data is flushed each time - if we are run multiple times in the same process/domain
|
||||||
public class WeaverLists
|
public class SyncVarAccessLists
|
||||||
{
|
{
|
||||||
// setter functions that replace [SyncVar] member variable references. dict<field, replacement>
|
// setter functions that replace [SyncVar] member variable references. dict<field, replacement>
|
||||||
public Dictionary<FieldDefinition, MethodDefinition> replacementSetterProperties =
|
public Dictionary<FieldDefinition, MethodDefinition> replacementSetterProperties =
|
@ -20,7 +20,7 @@ internal class Weaver
|
|||||||
public const string MirrorAssemblyName = "Mirror";
|
public const string MirrorAssemblyName = "Mirror";
|
||||||
|
|
||||||
WeaverTypes weaverTypes;
|
WeaverTypes weaverTypes;
|
||||||
WeaverLists weaverLists;
|
SyncVarAccessLists syncVarAccessLists;
|
||||||
IAssemblyResolver Resolver;
|
IAssemblyResolver Resolver;
|
||||||
AssemblyDefinition CurrentAssembly;
|
AssemblyDefinition CurrentAssembly;
|
||||||
Writers writers;
|
Writers writers;
|
||||||
@ -78,7 +78,7 @@ bool WeaveNetworkBehavior(TypeDefinition td)
|
|||||||
bool modified = false;
|
bool modified = false;
|
||||||
foreach (TypeDefinition behaviour in behaviourClasses)
|
foreach (TypeDefinition behaviour in behaviourClasses)
|
||||||
{
|
{
|
||||||
modified |= new NetworkBehaviourProcessor(CurrentAssembly, weaverTypes, weaverLists, writers, readers, Log, behaviour).Process(ref WeavingFailed);
|
modified |= new NetworkBehaviourProcessor(CurrentAssembly, weaverTypes, syncVarAccessLists, writers, readers, Log, behaviour).Process(ref WeavingFailed);
|
||||||
}
|
}
|
||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
@ -159,7 +159,7 @@ public bool Weave(AssemblyDefinition assembly, IAssemblyResolver resolver, out b
|
|||||||
CreateGeneratedCodeClass();
|
CreateGeneratedCodeClass();
|
||||||
|
|
||||||
// WeaverList depends on WeaverTypes setup because it uses Import
|
// WeaverList depends on WeaverTypes setup because it uses Import
|
||||||
weaverLists = new WeaverLists();
|
syncVarAccessLists = new SyncVarAccessLists();
|
||||||
|
|
||||||
// initialize readers & writers with this assembly.
|
// initialize readers & writers with this assembly.
|
||||||
// we need to do this in every Process() call.
|
// we need to do this in every Process() call.
|
||||||
@ -187,7 +187,7 @@ public bool Weave(AssemblyDefinition assembly, IAssemblyResolver resolver, out b
|
|||||||
|
|
||||||
if (modified)
|
if (modified)
|
||||||
{
|
{
|
||||||
SyncVarAccessReplacer.Process(moduleDefinition, weaverLists);
|
SyncVarAccessReplacer.Process(moduleDefinition, syncVarAccessLists);
|
||||||
|
|
||||||
// add class that holds read/write functions
|
// add class that holds read/write functions
|
||||||
moduleDefinition.Types.Add(GeneratedCodeClass);
|
moduleDefinition.Types.Add(GeneratedCodeClass);
|
||||||
|
Loading…
Reference in New Issue
Block a user