mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
fix: Set syncvar variables after calling the hook (#659)
Previously, during deserialize, Mirror either called the hook for a syncvar or it set the variable, but never both. So users had to set the variable inside the hook. ```cs class Player : NetworkBehaviour { [SyncVar(hook=nameof(OnVarChanged))] public int myvar; public void OnVarChanged(int newvalue) { Debug.Log("Got new value " + newvalue); Debug.Log("Old value is " + myvar); // with this pull request the following line is no longer needed // the weaver will do this after the hook finishes // this.myvar = newvalue; } } ``` fix: Hook not working with NetworkIdentity or GameObjects Deserializing NetworkIdentity or GameObjects was broken, it called the hook only if there was no hook, and it saved the variable only if there was a hook.
This commit is contained in:
parent
fac05428cc
commit
2d63ee1318
@ -438,7 +438,7 @@ public static int GetChannelId(CustomAttribute ca)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DeserializeField(FieldDefinition syncVar, ILProcessor serWorker)
|
||||
void DeserializeField(FieldDefinition syncVar, ILProcessor serWorker, MethodDefinition deserialize)
|
||||
{
|
||||
// check for Hook function
|
||||
MethodDefinition foundMethod;
|
||||
@ -457,21 +457,21 @@ void DeserializeField(FieldDefinition syncVar, ILProcessor serWorker)
|
||||
// move in and out of range repeatedly)
|
||||
FieldDefinition netIdField = m_SyncVarNetIds[syncVar];
|
||||
|
||||
if (foundMethod == null)
|
||||
{
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
|
||||
VariableDefinition tmpValue = new VariableDefinition(Weaver.uint32Type);
|
||||
deserialize.Body.Variables.Add(tmpValue);
|
||||
|
||||
// read id and store in a local variable
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkReaderReadPacked32));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Stfld, netIdField));
|
||||
}
|
||||
else
|
||||
serWorker.Append(serWorker.Create(OpCodes.Call, Weaver.NetworkReaderReadPacked32));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Stloc, tmpValue));
|
||||
|
||||
if (foundMethod != null)
|
||||
{
|
||||
// call Hook(this.GetSyncVarGameObject/NetworkIdentity(reader.ReadPackedUInt32()))
|
||||
// because we send/receive the netID, not the GameObject/NetworkIdentity
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0)); // this.
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkReaderReadPacked32));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldloc, tmpValue));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldflda, syncVar));
|
||||
if (syncVar.FieldType.FullName == Weaver.gameObjectType.FullName)
|
||||
@ -480,6 +480,10 @@ void DeserializeField(FieldDefinition syncVar, ILProcessor serWorker)
|
||||
serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.getSyncVarNetworkIdentityReference));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Call, foundMethod));
|
||||
}
|
||||
// set the netid field
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldloc, tmpValue));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Stfld, netIdField));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -489,23 +493,25 @@ void DeserializeField(FieldDefinition syncVar, ILProcessor serWorker)
|
||||
Weaver.Error("GenerateDeSerialization for " + m_td.Name + " unknown type [" + syncVar.FieldType + "]. Mirror [SyncVar] member variables must be basic types.");
|
||||
return;
|
||||
}
|
||||
VariableDefinition tmpValue = new VariableDefinition(syncVar.FieldType);
|
||||
deserialize.Body.Variables.Add(tmpValue);
|
||||
|
||||
if (foundMethod == null)
|
||||
{
|
||||
// just assign value
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
|
||||
// read value and put it in a local variable
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Call, readFunc));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Stfld, syncVar));
|
||||
}
|
||||
else
|
||||
serWorker.Append(serWorker.Create(OpCodes.Stloc, tmpValue));
|
||||
|
||||
if (foundMethod != null)
|
||||
{
|
||||
// call hook instead
|
||||
// call hook
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Call, readFunc));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldloc, tmpValue));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Call, foundMethod));
|
||||
}
|
||||
// set the property
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldloc, tmpValue));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Stfld, syncVar));
|
||||
}
|
||||
|
||||
}
|
||||
@ -533,6 +539,10 @@ void GenerateDeSerialization()
|
||||
serialize.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.CurrentAssembly.MainModule.ImportReference(Weaver.NetworkReaderType)));
|
||||
serialize.Parameters.Add(new ParameterDefinition("initialState", ParameterAttributes.None, Weaver.boolType));
|
||||
ILProcessor serWorker = serialize.Body.GetILProcessor();
|
||||
// setup local for dirty bits
|
||||
serialize.Body.InitLocals = true;
|
||||
VariableDefinition dirtyBitsLocal = new VariableDefinition(Weaver.int64Type);
|
||||
serialize.Body.Variables.Add(dirtyBitsLocal);
|
||||
|
||||
MethodReference baseDeserialize = Resolvers.ResolveMethodInParents(m_td.BaseType, Weaver.CurrentAssembly, "OnDeserialize");
|
||||
if (baseDeserialize != null)
|
||||
@ -551,7 +561,7 @@ void GenerateDeSerialization()
|
||||
|
||||
foreach (FieldDefinition syncVar in m_SyncVars)
|
||||
{
|
||||
DeserializeField(syncVar, serWorker);
|
||||
DeserializeField(syncVar, serWorker, serialize);
|
||||
}
|
||||
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ret));
|
||||
@ -559,10 +569,6 @@ void GenerateDeSerialization()
|
||||
// Generates: end if (initialState);
|
||||
serWorker.Append(initialStateLabel);
|
||||
|
||||
// setup local for dirty bits
|
||||
serialize.Body.InitLocals = true;
|
||||
VariableDefinition dirtyBitsLocal = new VariableDefinition(Weaver.int64Type);
|
||||
serialize.Body.Variables.Add(dirtyBitsLocal);
|
||||
|
||||
// get dirty bits
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
|
||||
@ -581,7 +587,7 @@ void GenerateDeSerialization()
|
||||
serWorker.Append(serWorker.Create(OpCodes.And));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Brfalse, varLabel));
|
||||
|
||||
DeserializeField(syncVar, serWorker);
|
||||
DeserializeField(syncVar, serWorker, serialize);
|
||||
|
||||
serWorker.Append(varLabel);
|
||||
dirtyBit += 1;
|
||||
|
Loading…
Reference in New Issue
Block a user