Skip to content

fix: NetworkList now properly calls INetworkSerializable's NetworkSerialize() method #1586

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
- Fixed error when serializing ConnectionApprovalMessage with scene management disabled when one or more objects is hidden via the CheckObjectVisibility delegate (#1509)
- Fixed The NetworkConfig's checksum hash includes the NetworkTick so that clients with a different tickrate than the server are identified and not allowed to connect. (#1513)
- Fixed OwnedObjects not being properly modified when using ChangeOwnership. (#1572)
- Fixed: NetworkList now properly calls INetworkSerializable's NetworkSerialize() method (#1586)

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,18 @@ public override void WriteDelta(FastBufferWriter writer)
{
case NetworkListEvent<T>.EventType.Add:
{
writer.WriteValueSafe(m_DirtyEvents[i].Value);
NetworkVariable<T>.Write(writer, m_DirtyEvents[i].Value);
}
break;
case NetworkListEvent<T>.EventType.Insert:
{
writer.WriteValueSafe(m_DirtyEvents[i].Index);
writer.WriteValueSafe(m_DirtyEvents[i].Value);
NetworkVariable<T>.Write(writer, m_DirtyEvents[i].Value);
}
break;
case NetworkListEvent<T>.EventType.Remove:
{
writer.WriteValueSafe(m_DirtyEvents[i].Value);
NetworkVariable<T>.Write(writer, m_DirtyEvents[i].Value);
}
break;
case NetworkListEvent<T>.EventType.RemoveAt:
Expand All @@ -112,7 +112,7 @@ public override void WriteDelta(FastBufferWriter writer)
case NetworkListEvent<T>.EventType.Value:
{
writer.WriteValueSafe(m_DirtyEvents[i].Index);
writer.WriteValueSafe(m_DirtyEvents[i].Value);
NetworkVariable<T>.Write(writer, m_DirtyEvents[i].Value);
}
break;
case NetworkListEvent<T>.EventType.Clear:
Expand All @@ -130,7 +130,7 @@ public override void WriteField(FastBufferWriter writer)
writer.WriteValueSafe((ushort)m_List.Length);
for (int i = 0; i < m_List.Length; i++)
{
writer.WriteValueSafe(m_List[i]);
NetworkVariable<T>.Write(writer, m_List[i]);
}
}

Expand All @@ -141,7 +141,7 @@ public override void ReadField(FastBufferReader reader)
reader.ReadValueSafe(out ushort count);
for (int i = 0; i < count; i++)
{
reader.ReadValueSafe(out T value);
NetworkVariable<T>.Read(reader, out T value);
m_List.Add(value);
}
}
Expand All @@ -157,7 +157,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
{
case NetworkListEvent<T>.EventType.Add:
{
reader.ReadValueSafe(out T value);
NetworkVariable<T>.Read(reader, out T value);
m_List.Add(value);

if (OnListChanged != null)
Expand All @@ -184,7 +184,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
case NetworkListEvent<T>.EventType.Insert:
{
reader.ReadValueSafe(out int index);
reader.ReadValueSafe(out T value);
NetworkVariable<T>.Read(reader, out T value);
m_List.InsertRangeWithBeginEnd(index, index + 1);
m_List[index] = value;

Expand All @@ -211,7 +211,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
break;
case NetworkListEvent<T>.EventType.Remove:
{
reader.ReadValueSafe(out T value);
NetworkVariable<T>.Read(reader, out T value);
int index = m_List.IndexOf(value);
if (index == -1)
{
Expand Down Expand Up @@ -271,7 +271,7 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
case NetworkListEvent<T>.EventType.Value:
{
reader.ReadValueSafe(out int index);
reader.ReadValueSafe(out T value);
NetworkVariable<T>.Read(reader, out T value);
if (index >= m_List.Length)
{
throw new Exception("Shouldn't be here, index is higher than list length");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Unity.Netcode
public class NetworkVariable<T> : NetworkVariableBase where T : unmanaged
{
// Functions that know how to serialize INetworkSerializable
internal static void WriteNetworkSerializable<TForMethod>(FastBufferWriter writer, ref TForMethod value)
internal static void WriteNetworkSerializable<TForMethod>(FastBufferWriter writer, in TForMethod value)
where TForMethod : INetworkSerializable, new()
{
writer.WriteNetworkSerializable(value);
Expand All @@ -22,7 +22,7 @@ internal static void ReadNetworkSerializable<TForMethod>(FastBufferReader reader
}

// Functions that serialize other types
private static void WriteValue<TForMethod>(FastBufferWriter writer, ref TForMethod value) where TForMethod : unmanaged
private static void WriteValue<TForMethod>(FastBufferWriter writer, in TForMethod value) where TForMethod : unmanaged
{
writer.WriteValueSafe(value);
}
Expand All @@ -33,7 +33,7 @@ private static void ReadValue<TForMethod>(FastBufferReader reader, out TForMetho
reader.ReadValueSafe(out value);
}

internal delegate void WriteDelegate<TForMethod>(FastBufferWriter writer, ref TForMethod value);
internal delegate void WriteDelegate<TForMethod>(FastBufferWriter writer, in TForMethod value);

internal delegate void ReadDelegate<TForMethod>(FastBufferReader reader, out TForMethod value);

Expand Down Expand Up @@ -174,7 +174,7 @@ public override void ReadField(FastBufferReader reader)
/// <inheritdoc />
public override void WriteField(FastBufferWriter writer)
{
Write(writer, ref m_InternalValue);
Write(writer, m_InternalValue);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Unity.Netcode.RuntimeTests
{
public struct TestStruct : INetworkSerializable
public struct TestStruct : INetworkSerializable, IEquatable<TestStruct>
{
public uint SomeInt;
public bool SomeBool;
Expand All @@ -27,6 +27,24 @@ public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReade
serializer.SerializeValue(ref SomeInt);
serializer.SerializeValue(ref SomeBool);
}

public bool Equals(TestStruct other)
{
return SomeInt == other.SomeInt && SomeBool == other.SomeBool;
}

public override bool Equals(object obj)
{
return obj is TestStruct other && Equals(other);
}

public override int GetHashCode()
{
unchecked
{
return ((int)SomeInt * 397) ^ SomeBool.GetHashCode();
}
}
}

public class NetworkVariableTest : NetworkBehaviour
Expand All @@ -48,6 +66,7 @@ public void Awake()
}

public readonly NetworkVariable<TestStruct> TheStruct = new NetworkVariable<TestStruct>();
public readonly NetworkList<TestStruct> TheListOfStructs = new NetworkList<TestStruct>();

public bool ListDelegateTriggered;
}
Expand Down Expand Up @@ -529,6 +548,28 @@ public IEnumerator TestINetworkSerializableCallsNetworkSerialize([Values(true, f
);
}

[UnityTest]
public IEnumerator TestListOfINetworkSerializableCallsNetworkSerialize([Values(true, false)] bool useHost)
{
m_TestWithHost = useHost;
yield return MultiInstanceHelpers.RunAndWaitForCondition(
() =>
{
TestStruct.NetworkSerializeCalledOnWrite = false;
TestStruct.NetworkSerializeCalledOnRead = false;
m_Player1OnServer.TheListOfStructs.Add(
new TestStruct() { SomeInt = k_TestUInt, SomeBool = false });
m_Player1OnServer.TheListOfStructs.SetDirty(true);
},
() =>
{
return
TestStruct.NetworkSerializeCalledOnWrite &&
TestStruct.NetworkSerializeCalledOnRead;
}
);
}

[UnityTearDown]
public override IEnumerator Teardown()
{
Expand Down