Skip to content

Commit

Permalink
feat: support null when serializing classes (#2290)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulpach committed Sep 29, 2020
1 parent fe641ad commit 513a0f9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
20 changes: 20 additions & 0 deletions Assets/Mirror/Editor/Weaver/Readers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ static MethodDefinition GenerateClassOrStructReadFunction(TypeReference variable

TypeDefinition td = variable.Resolve();

if (!td.IsValueType)
GenerateNullCheck(worker);

CreateNew(variable, worker, td);
ReadAllFields(variable, recursionCount, worker);

Expand All @@ -405,6 +408,23 @@ static MethodDefinition GenerateClassOrStructReadFunction(TypeReference variable
return readerFunc;
}

private static void GenerateNullCheck(ILProcessor worker)
{
// if (!reader.ReadBoolean()) {
// return null;
// }

worker.Append(worker.Create(OpCodes.Ldarg_0));
worker.Append(worker.Create(OpCodes.Call, GetReadFunc(WeaverTypes.Import<bool>())));

Instruction labelEmptyArray = worker.Create(OpCodes.Nop);
worker.Append(worker.Create(OpCodes.Brtrue, labelEmptyArray));
// return null
worker.Append(worker.Create(OpCodes.Ldnull));
worker.Append(worker.Create(OpCodes.Ret));
worker.Append(labelEmptyArray);
}

// Initialize the local variable with a new instance
static void CreateNew(TypeReference variable, ILProcessor worker, TypeDefinition td)
{
Expand Down
27 changes: 27 additions & 0 deletions Assets/Mirror/Editor/Weaver/Writers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,40 @@ static MethodDefinition GenerateClassOrStructWriterFunction(TypeReference variab

ILProcessor worker = writerFunc.Body.GetILProcessor();

if (!variable.Resolve().IsValueType)
WriteNullCheck(worker);

if (!WriteAllFields(variable, recursionCount, worker))
return null;

worker.Append(worker.Create(OpCodes.Ret));
return writerFunc;
}

private static void WriteNullCheck(ILProcessor worker)
{
// if (value == null)
// {
// writer.WriteBoolean(false);
// return;
// }
//

Instruction labelNotNull = worker.Create(OpCodes.Nop);
worker.Append(worker.Create(OpCodes.Ldarg_1));
worker.Append(worker.Create(OpCodes.Brtrue, labelNotNull));
worker.Append(worker.Create(OpCodes.Ldarg_0));
worker.Append(worker.Create(OpCodes.Ldc_I4_0));
worker.Append(worker.Create(OpCodes.Call, GetWriteFunc(WeaverTypes.Import<bool>())));
worker.Append(worker.Create(OpCodes.Ret));
worker.Append(labelNotNull);

// write.WriteBoolean(true);
worker.Append(worker.Create(OpCodes.Ldarg_0));
worker.Append(worker.Create(OpCodes.Ldc_I4_1));
worker.Append(worker.Create(OpCodes.Call, GetWriteFunc(WeaverTypes.Import<bool>())));
}

/// <summary>
/// Find all fields in type and write them
/// </summary>
Expand Down
28 changes: 28 additions & 0 deletions Assets/Mirror/Tests/Editor/MessageBaseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ class Layer3Message : Layer2Message
public int value3;
}

class NullableObject
{
public int id = 3;
}

class NullableObjectMessage : MessageBase
{
public string name;
public NullableObject nullObj;
}

[TestFixture]
public class MessageBaseTests
{
Expand Down Expand Up @@ -158,5 +169,22 @@ public void MessageInheirtanceWorksWithMultipleLayers()
Assert.That(unpacked.value2, Is.EqualTo(value2));
Assert.That(unpacked.value3, Is.EqualTo(value3));
}

[Test]
public void NullObjectMessageTest()
{
NullableObjectMessage nullableObjectMessage = new NullableObjectMessage
{
name = "pepe",
nullObj = null
};

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

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

Assert.That(unpacked.name, Is.EqualTo("pepe"));
Assert.That(unpacked.nullObj, Is.Null);
}
}
}

0 comments on commit 513a0f9

Please sign in to comment.