mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
Merge pull request #689 from paulpach/zigzag
perf: Implement zigzag algorithm so negatives pack efficiently
This commit is contained in:
commit
b876e256eb
@ -229,7 +229,7 @@ bool WriteParameters(NetworkWriter writer)
|
||||
if (par.type == AnimatorControllerParameterType.Int)
|
||||
{
|
||||
int newIntValue = animator.GetInteger(par.nameHash);
|
||||
writer.WritePackedUInt32((uint)newIntValue);
|
||||
writer.WritePackedInt32(newIntValue);
|
||||
}
|
||||
else if (par.type == AnimatorControllerParameterType.Float)
|
||||
{
|
||||
@ -256,7 +256,7 @@ void ReadParameters(NetworkReader reader)
|
||||
AnimatorControllerParameter par = parameters[i];
|
||||
if (par.type == AnimatorControllerParameterType.Int)
|
||||
{
|
||||
int newIntValue = (int)reader.ReadPackedUInt32();
|
||||
int newIntValue = reader.ReadPackedInt32();
|
||||
animator.SetInteger(par.nameHash, newIntValue);
|
||||
}
|
||||
else if (par.type == AnimatorControllerParameterType.Float)
|
||||
|
@ -372,7 +372,7 @@ void GenerateSerialization()
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1)); // writer
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0)); // base
|
||||
serWorker.Append(serWorker.Create(OpCodes.Call, Weaver.NetworkBehaviourDirtyBitsReference));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePacked64));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePackedUInt64));
|
||||
|
||||
// generate a writer call for any dirty variable in this class
|
||||
|
||||
@ -462,7 +462,7 @@ void DeserializeField(FieldDefinition syncVar, ILProcessor serWorker, MethodDefi
|
||||
|
||||
// read id and store in a local variable
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Call, Weaver.NetworkReaderReadPacked32));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Call, Weaver.NetworkReaderReadPackedUInt32));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Stloc, tmpValue));
|
||||
|
||||
if (foundMethod != null)
|
||||
@ -572,7 +572,7 @@ void GenerateDeSerialization()
|
||||
|
||||
// get dirty bits
|
||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkReaderReadPacked64));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkReaderReadPackedUInt64));
|
||||
serWorker.Append(serWorker.Create(OpCodes.Stloc_0));
|
||||
|
||||
// conditionally read each syncvar
|
||||
|
@ -101,11 +101,15 @@ class Weaver
|
||||
public static MethodReference NetworkServerGetLocalClientActive;
|
||||
public static MethodReference NetworkClientGetActive;
|
||||
public static MethodReference UBehaviourIsServer;
|
||||
public static MethodReference NetworkReaderReadPacked32;
|
||||
public static MethodReference NetworkReaderReadPacked64;
|
||||
public static MethodReference NetworkReaderReadPackedUInt32;
|
||||
public static MethodReference NetworkReaderReadPackedInt32;
|
||||
public static MethodReference NetworkReaderReadPackedUInt64;
|
||||
public static MethodReference NetworkReaderReadPackedInt64;
|
||||
public static MethodReference NetworkReaderReadByte;
|
||||
public static MethodReference NetworkWriterWritePacked32;
|
||||
public static MethodReference NetworkWriterWritePacked64;
|
||||
public static MethodReference NetworkWriterWritePackedUInt32;
|
||||
public static MethodReference NetworkWriterWritePackedInt32;
|
||||
public static MethodReference NetworkWriterWritePackedUInt64;
|
||||
public static MethodReference NetworkWriterWritePackedInt64;
|
||||
|
||||
public static MethodReference NetworkReadUInt16;
|
||||
public static MethodReference NetworkWriteUInt16;
|
||||
@ -1101,12 +1105,16 @@ static void SetupTargetTypes()
|
||||
NetworkWriterWriteInt32 = Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", int32Type);
|
||||
NetworkWriterWriteInt16 = Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", int16Type);
|
||||
|
||||
NetworkReaderReadPacked32 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedUInt32");
|
||||
NetworkReaderReadPacked64 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedUInt64");
|
||||
NetworkReaderReadPackedUInt32 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedUInt32");
|
||||
NetworkReaderReadPackedInt32 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedInt32");
|
||||
NetworkReaderReadPackedUInt64 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedUInt64");
|
||||
NetworkReaderReadPackedInt64 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadPackedInt64");
|
||||
NetworkReaderReadByte = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadByte");
|
||||
|
||||
NetworkWriterWritePacked32 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedUInt32");
|
||||
NetworkWriterWritePacked64 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedUInt64");
|
||||
NetworkWriterWritePackedUInt32 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedUInt32");
|
||||
NetworkWriterWritePackedInt32 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedInt32");
|
||||
NetworkWriterWritePackedUInt64 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedUInt64");
|
||||
NetworkWriterWritePackedInt64 = Resolvers.ResolveMethod(NetworkWriterType, CurrentAssembly, "WritePackedInt64");
|
||||
|
||||
NetworkReadUInt16 = Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadUInt16");
|
||||
NetworkWriteUInt16 = Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", uint16Type);
|
||||
@ -1180,10 +1188,10 @@ static void SetupReadFunctions()
|
||||
{ doubleType.FullName, Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadDouble") },
|
||||
{ boolType.FullName, Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadBoolean") },
|
||||
{ stringType.FullName, Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadString") },
|
||||
{ int64Type.FullName, NetworkReaderReadPacked64 },
|
||||
{ uint64Type.FullName, NetworkReaderReadPacked64 },
|
||||
{ int32Type.FullName, NetworkReaderReadPacked32 },
|
||||
{ uint32Type.FullName, NetworkReaderReadPacked32 },
|
||||
{ int64Type.FullName, NetworkReaderReadPackedInt64 },
|
||||
{ uint64Type.FullName, NetworkReaderReadPackedUInt64 },
|
||||
{ int32Type.FullName, NetworkReaderReadPackedInt32 },
|
||||
{ uint32Type.FullName, NetworkReaderReadPackedUInt32 },
|
||||
{ int16Type.FullName, Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadInt16") },
|
||||
{ uint16Type.FullName, Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadUInt16") },
|
||||
{ byteType.FullName, Resolvers.ResolveMethod(NetworkReaderType, CurrentAssembly, "ReadByte") },
|
||||
@ -1218,10 +1226,10 @@ static void SetupWriteFunctions()
|
||||
{ doubleType.FullName, Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", doubleType) },
|
||||
{ boolType.FullName, Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", boolType) },
|
||||
{ stringType.FullName, Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", stringType) },
|
||||
{ int64Type.FullName, NetworkWriterWritePacked64 },
|
||||
{ uint64Type.FullName, NetworkWriterWritePacked64 },
|
||||
{ int32Type.FullName, NetworkWriterWritePacked32 },
|
||||
{ uint32Type.FullName, NetworkWriterWritePacked32 },
|
||||
{ int64Type.FullName, NetworkWriterWritePackedInt64 },
|
||||
{ uint64Type.FullName, NetworkWriterWritePackedUInt64 },
|
||||
{ int32Type.FullName, NetworkWriterWritePackedInt32 },
|
||||
{ uint32Type.FullName, NetworkWriterWritePackedUInt32 },
|
||||
{ int16Type.FullName, Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", int16Type) },
|
||||
{ uint16Type.FullName, Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", uint16Type) },
|
||||
{ byteType.FullName, Resolvers.ResolveMethodWithArg(NetworkWriterType, CurrentAssembly, "Write", byteType) },
|
||||
|
@ -99,12 +99,12 @@ public IntegerMessage(int v)
|
||||
|
||||
public override void Deserialize(NetworkReader reader)
|
||||
{
|
||||
value = (int)reader.ReadPackedUInt32();
|
||||
value = reader.ReadPackedInt32();
|
||||
}
|
||||
|
||||
public override void Serialize(NetworkWriter writer)
|
||||
{
|
||||
writer.WritePackedUInt32((uint)value);
|
||||
writer.WritePackedInt32(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,13 @@ public byte[] ReadBytesAndSize()
|
||||
return null;
|
||||
}
|
||||
|
||||
// zigzag decoding https://gist.github.com/mfuerstenau/ba870a29e16536fdbaba
|
||||
public int ReadPackedInt32()
|
||||
{
|
||||
uint data = ReadPackedUInt32();
|
||||
return (int)((data >> 1) ^ -(data & 1));
|
||||
}
|
||||
|
||||
// http://sqlite.org/src4/doc/trunk/www/varint.wiki
|
||||
// NOTE: big endian.
|
||||
public uint ReadPackedUInt32()
|
||||
@ -69,6 +76,13 @@ public uint ReadPackedUInt32()
|
||||
return (uint)value;
|
||||
}
|
||||
|
||||
// zigzag decoding https://gist.github.com/mfuerstenau/ba870a29e16536fdbaba
|
||||
public long ReadPackedInt64()
|
||||
{
|
||||
ulong data = ReadPackedUInt64();
|
||||
return ((long)(data >> 1)) ^ -((long)data & 1);
|
||||
}
|
||||
|
||||
public ulong ReadPackedUInt64()
|
||||
{
|
||||
byte a0 = ReadByte();
|
||||
@ -145,12 +159,12 @@ public Vector4 ReadVector4()
|
||||
|
||||
public Vector2Int ReadVector2Int()
|
||||
{
|
||||
return new Vector2Int((int)ReadPackedUInt32(), (int)ReadPackedUInt32());
|
||||
return new Vector2Int(ReadPackedInt32(), ReadPackedInt32());
|
||||
}
|
||||
|
||||
public Vector3Int ReadVector3Int()
|
||||
{
|
||||
return new Vector3Int((int)ReadPackedUInt32(), (int)ReadPackedUInt32(), (int)ReadPackedUInt32());
|
||||
return new Vector3Int(ReadPackedInt32(), ReadPackedInt32(), ReadPackedInt32());
|
||||
}
|
||||
|
||||
public Color ReadColor()
|
||||
|
@ -100,6 +100,13 @@ public void WriteBytesAndSize(byte[] buffer)
|
||||
WriteBytesAndSize(buffer, 0, buffer != null ? buffer.Length : 0);
|
||||
}
|
||||
|
||||
// zigzag encoding https://gist.github.com/mfuerstenau/ba870a29e16536fdbaba
|
||||
public void WritePackedInt32(int i)
|
||||
{
|
||||
uint zigzagged = (uint)((i >> 31) ^ (i << 1));
|
||||
WritePackedUInt32(zigzagged);
|
||||
}
|
||||
|
||||
// http://sqlite.org/src4/doc/trunk/www/varint.wiki
|
||||
public void WritePackedUInt32(uint value)
|
||||
{
|
||||
@ -108,6 +115,13 @@ public void WritePackedUInt32(uint value)
|
||||
WritePackedUInt64(value);
|
||||
}
|
||||
|
||||
// zigzag encoding https://gist.github.com/mfuerstenau/ba870a29e16536fdbaba
|
||||
public void WritePackedInt64(long i)
|
||||
{
|
||||
ulong zigzagged = (ulong)((i >> 63) ^ (i << 1));
|
||||
WritePackedUInt64(zigzagged);
|
||||
}
|
||||
|
||||
public void WritePackedUInt64(ulong value)
|
||||
{
|
||||
if (value <= 240)
|
||||
@ -216,15 +230,15 @@ public void Write(Vector4 value)
|
||||
|
||||
public void Write(Vector2Int value)
|
||||
{
|
||||
WritePackedUInt32((uint)value.x);
|
||||
WritePackedUInt32((uint)value.y);
|
||||
WritePackedInt32(value.x);
|
||||
WritePackedInt32(value.y);
|
||||
}
|
||||
|
||||
public void Write(Vector3Int value)
|
||||
{
|
||||
WritePackedUInt32((uint)value.x);
|
||||
WritePackedUInt32((uint)value.y);
|
||||
WritePackedUInt32((uint)value.z);
|
||||
WritePackedInt32(value.x);
|
||||
WritePackedInt32(value.y);
|
||||
WritePackedInt32(value.z);
|
||||
}
|
||||
|
||||
public void Write(Color value)
|
||||
|
@ -19,8 +19,8 @@ public class SyncListFloat : SyncList<float>
|
||||
|
||||
public class SyncListInt : SyncList<int>
|
||||
{
|
||||
protected override void SerializeItem(NetworkWriter writer, int item) => writer.WritePackedUInt32((uint)item);
|
||||
protected override int DeserializeItem(NetworkReader reader) => (int)reader.ReadPackedUInt32();
|
||||
protected override void SerializeItem(NetworkWriter writer, int item) => writer.WritePackedInt32(item);
|
||||
protected override int DeserializeItem(NetworkReader reader) => reader.ReadPackedInt32();
|
||||
}
|
||||
|
||||
public class SyncListUInt : SyncList<uint>
|
||||
|
@ -79,6 +79,42 @@ public void TestPackedUInt32()
|
||||
Assert.That(reader.ReadPackedUInt32(), Is.EqualTo(uint.MaxValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestPackedInt32()
|
||||
{
|
||||
NetworkWriter writer = new NetworkWriter();
|
||||
writer.WritePackedInt32(0);
|
||||
writer.WritePackedInt32(234);
|
||||
writer.WritePackedInt32(2284);
|
||||
writer.WritePackedInt32(67821);
|
||||
writer.WritePackedInt32(16777210);
|
||||
writer.WritePackedInt32(16777219);
|
||||
writer.WritePackedInt32(int.MaxValue);
|
||||
writer.WritePackedInt32(-1);
|
||||
writer.WritePackedInt32(-234);
|
||||
writer.WritePackedInt32(-2284);
|
||||
writer.WritePackedInt32(-67821);
|
||||
writer.WritePackedInt32(-16777210);
|
||||
writer.WritePackedInt32(-16777219);
|
||||
writer.WritePackedInt32(int.MinValue);
|
||||
|
||||
NetworkReader reader = new NetworkReader(writer.ToArray());
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(0));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(234));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(2284));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(67821));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(16777210));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(16777219));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(int.MaxValue));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-1));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-234));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-2284));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-67821));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-16777210));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(-16777219));
|
||||
Assert.That(reader.ReadPackedInt32(), Is.EqualTo(int.MinValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestPackedUInt64()
|
||||
{
|
||||
@ -109,6 +145,58 @@ public void TestPackedUInt64()
|
||||
Assert.That(reader.ReadPackedUInt64(), Is.EqualTo(ulong.MaxValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestPackedInt64()
|
||||
{
|
||||
NetworkWriter writer = new NetworkWriter();
|
||||
writer.WritePackedInt64(0);
|
||||
writer.WritePackedInt64(234);
|
||||
writer.WritePackedInt64(2284);
|
||||
writer.WritePackedInt64(67821);
|
||||
writer.WritePackedInt64(16777210);
|
||||
writer.WritePackedInt64(16777219);
|
||||
writer.WritePackedInt64(4294967295);
|
||||
writer.WritePackedInt64(1099511627775);
|
||||
writer.WritePackedInt64(281474976710655);
|
||||
writer.WritePackedInt64(72057594037927935);
|
||||
writer.WritePackedInt64(long.MaxValue);
|
||||
writer.WritePackedInt64(-1);
|
||||
writer.WritePackedInt64(-234);
|
||||
writer.WritePackedInt64(-2284);
|
||||
writer.WritePackedInt64(-67821);
|
||||
writer.WritePackedInt64(-16777210);
|
||||
writer.WritePackedInt64(-16777219);
|
||||
writer.WritePackedInt64(-4294967295);
|
||||
writer.WritePackedInt64(-1099511627775);
|
||||
writer.WritePackedInt64(-281474976710655);
|
||||
writer.WritePackedInt64(-72057594037927935);
|
||||
writer.WritePackedInt64(long.MinValue);
|
||||
|
||||
NetworkReader reader = new NetworkReader(writer.ToArray());
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(0));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(234));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(2284));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(67821));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(16777210));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(16777219));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(4294967295));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(1099511627775));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(281474976710655));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(72057594037927935));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(long.MaxValue));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(-1));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(-234));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(-2284));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(-67821));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(-16777210));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(-16777219));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(-4294967295));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(-1099511627775));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(-281474976710655));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(-72057594037927935));
|
||||
Assert.That(reader.ReadPackedInt64(), Is.EqualTo(long.MinValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGuid()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user