Skip to content

Commit

Permalink
fix: auto fill serialize/deserialize for classes (#2120)
Browse files Browse the repository at this point in the history
Note this method is being called in 3 places:
one in MessageClassProcessor and 2 in NetworkBehaviorProcessor.

The NetworkBehaviorProcess is really a don't care, this condition cannot happen since it would not be invoked unless the class extends from NetworkBehavior. In this case, it will always resolve.
but even if it does not resolve, they handle the null case gracefully by not calling the base method.

MessageClassProcessor also calls this method, and if it is null it does not call the base method. That is precisely the behavior we want to resolve #2117

so all 3 places are perfectly fine receiving null.

The only way to trigger the error was #2117

I renamed the method to make it clearer that this may not find the method in the parent class.
  • Loading branch information
paulpach committed Aug 1, 2020
1 parent 0cb84ba commit 890ee6b
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ static void CallWriter(ILProcessor worker, FieldDefinition field)

static void CallBase(TypeDefinition td, ILProcessor worker, string name)
{
MethodReference method = Resolvers.ResolveMethodInParents(td.BaseType, Weaver.CurrentAssembly, name);
MethodReference method = Resolvers.TryResolveMethodInParents(td.BaseType, Weaver.CurrentAssembly, name);
if (method != null)
{
// base
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ void GenerateSerialization()
VariableDefinition dirtyLocal = new VariableDefinition(Weaver.boolType);
serialize.Body.Variables.Add(dirtyLocal);

MethodReference baseSerialize = Resolvers.ResolveMethodInParents(netBehaviourSubclass.BaseType, Weaver.CurrentAssembly, SerializeMethodName);
MethodReference baseSerialize = Resolvers.TryResolveMethodInParents(netBehaviourSubclass.BaseType, Weaver.CurrentAssembly, SerializeMethodName);
if (baseSerialize != null)
{
// base
Expand Down Expand Up @@ -730,7 +730,7 @@ void GenerateDeSerialization()
VariableDefinition dirtyBitsLocal = new VariableDefinition(Weaver.int64Type);
serialize.Body.Variables.Add(dirtyBitsLocal);

MethodReference baseDeserialize = Resolvers.ResolveMethodInParents(netBehaviourSubclass.BaseType, Weaver.CurrentAssembly, DeserializeMethodName);
MethodReference baseDeserialize = Resolvers.TryResolveMethodInParents(netBehaviourSubclass.BaseType, Weaver.CurrentAssembly, DeserializeMethodName);
if (baseDeserialize != null)
{
// base
Expand Down
6 changes: 3 additions & 3 deletions Assets/Mirror/Editor/Weaver/Resolvers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ public static MethodReference ResolveMethod(TypeReference t, AssemblyDefinition
return null;
}

public static MethodReference ResolveMethodInParents(TypeReference tr, AssemblyDefinition scriptDef, string name)
public static MethodReference TryResolveMethodInParents(TypeReference tr, AssemblyDefinition scriptDef, string name)
{
if (tr == null)
{
Weaver.Error($"Cannot resolve method {name} without a type");
return null;
}
foreach (MethodDefinition methodRef in tr.Resolve().Methods)
Expand All @@ -53,8 +52,9 @@ public static MethodReference ResolveMethodInParents(TypeReference tr, AssemblyD
return scriptDef.MainModule.ImportReference(methodRef);
}
}

// Could not find the method in this class, try the parent
return ResolveMethodInParents(tr.Resolve().BaseType, scriptDef, name);
return TryResolveMethodInParents(tr.Resolve().BaseType, scriptDef, name);
}

// System.Byte[] arguments need a version with a string
Expand Down
26 changes: 26 additions & 0 deletions Assets/Mirror/Tests/Editor/MessageBaseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ struct WovenTestMessage : IMessageBase
public void Serialize(NetworkWriter writer) { }
}

class ArrayIntIMessage : IMessageBase
{
public int[] array;

// Mirror will fill out these empty methods
public void Deserialize(NetworkReader reader) { }
public void Serialize(NetworkWriter writer) { }
}


[TestFixture]
public class MessageBaseTests
{
Expand All @@ -62,5 +72,21 @@ public void WovenSerializationBodyRoundtrip()
Assert.AreEqual("2", t.StringValue);
Assert.AreEqual(3.3, t.DoubleValue);
}

[Test]
public void TestIntArrayInIMessageBase()
{
ArrayIntIMessage intMessage = new ArrayIntIMessage
{
array = new[] { 3, 4, 5 }
};

byte[] data = MessagePacker.Pack(intMessage);

ArrayIntIMessage unpacked = MessagePacker.Unpack<ArrayIntIMessage>(data);

Assert.That(unpacked.array, Is.EquivalentTo(new int[] { 3, 4, 5 }));
}

}
}

0 comments on commit 890ee6b

Please sign in to comment.