Skip to content

Commit 688640c

Browse files
fix: missing value on NetworkListEvent for EventType.RemoveAt events [MTT-6354] (#2559)
* fix: missing value on NetworkListEvent for EventType.RemoveAt events server side (#2542) * Update CHANGELOG.md * test Updated the NetworkList remove tests to be combined into one test and to validate that the list changed event is returning the value of the element removed. Cleaned up the tests a bit and removed some legacy tests that were being ignored and no longer serve a purpose. --------- Co-authored-by: PitouGames <[email protected]>
1 parent 31e5e1d commit 688640c

File tree

3 files changed

+79
-81
lines changed

3 files changed

+79
-81
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1313
### Fixed
1414

1515
- Fixed the "Generate Default Network Prefabs List" setting not loading correctly and always reverting to being checked. (#2545)
16+
- Fixed missing value on `NetworkListEvent` for `EventType.RemoveAt` events. (#2542,#2543)
1617
- Fixed the inspector throwing exceptions when attempting to render `NetworkVariable`s of enum types. (#2529)
1718
- Making a `NetworkVariable` with an `INetworkSerializable` type that doesn't meet the `new()` constraint will now create a compile-time error instead of an editor crash (#2528)
1819
- Fixed Multiplayer Tools package installation docs page link on the NetworkManager popup. (#2526)

com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,12 +490,14 @@ public void RemoveAt(int index)
490490
throw new InvalidOperationException("Client is not allowed to write to this NetworkList");
491491
}
492492

493+
var value = m_List[index];
493494
m_List.RemoveAt(index);
494495

495496
var listEvent = new NetworkListEvent<T>()
496497
{
497498
Type = NetworkListEvent<T>.EventType.RemoveAt,
498-
Index = index
499+
Index = index,
500+
Value = value
499501
};
500502

501503
HandleAddListEvent(listEvent);

com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs

Lines changed: 75 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ protected override bool CanStartServerAndClients()
557557
/// This is an adjustment to how the server and clients are started in order
558558
/// to avoid timing issues when running in a stand alone test runner build.
559559
/// </summary>
560-
private void InitializeServerAndClients(bool useHost)
560+
private void InitializeServerAndClients(HostOrServer useHost)
561561
{
562562
s_ClientNetworkVariableTestInstances.Clear();
563563
m_PlayerPrefab.AddComponent<NetworkVariableTest>();
@@ -574,7 +574,7 @@ private void InitializeServerAndClients(bool useHost)
574574
client.NetworkConfig.PlayerPrefab = m_PlayerPrefab;
575575
}
576576

577-
Assert.True(NetcodeIntegrationTestHelpers.Start(useHost, m_ServerNetworkManager, m_ClientNetworkManagers), "Failed to start server and client instances");
577+
Assert.True(NetcodeIntegrationTestHelpers.Start(useHost == HostOrServer.Host, m_ServerNetworkManager, m_ClientNetworkManagers), "Failed to start server and client instances");
578578

579579
RegisterSceneManagerHandler();
580580

@@ -611,7 +611,7 @@ private void InitializeServerAndClients(bool useHost)
611611
throw new Exception("at least one client network container not empty at start");
612612
}
613613

614-
var instanceCount = useHost ? NumberOfClients * 3 : NumberOfClients * 2;
614+
var instanceCount = useHost == HostOrServer.Host ? NumberOfClients * 3 : NumberOfClients * 2;
615615
// Wait for the client-side to notify it is finished initializing and spawning.
616616
success = WaitForConditionOrTimeOutWithTimeTravel(() => s_ClientNetworkVariableTestInstances.Count == instanceCount);
617617

@@ -624,15 +624,15 @@ private void InitializeServerAndClients(bool useHost)
624624
/// Runs generalized tests on all predefined NetworkVariable types
625625
/// </summary>
626626
[Test]
627-
public void AllNetworkVariableTypes([Values(true, false)] bool useHost)
627+
public void AllNetworkVariableTypes([Values] HostOrServer useHost)
628628
{
629629
// Create, instantiate, and host
630630
// This would normally go in Setup, but since every other test but this one
631631
// uses NetworkManagerHelper, and it does its own NetworkManager setup / teardown,
632632
// for now we put this within this one test until we migrate it to MIH
633-
Assert.IsTrue(NetworkManagerHelper.StartNetworkManager(out NetworkManager server, useHost ? NetworkManagerHelper.NetworkManagerOperatingMode.Host : NetworkManagerHelper.NetworkManagerOperatingMode.Server));
633+
Assert.IsTrue(NetworkManagerHelper.StartNetworkManager(out NetworkManager server, useHost == HostOrServer.Host ? NetworkManagerHelper.NetworkManagerOperatingMode.Host : NetworkManagerHelper.NetworkManagerOperatingMode.Server));
634634

635-
Assert.IsTrue(server.IsHost == useHost, $"{nameof(useHost)} does not match the server.IsHost value!");
635+
Assert.IsTrue(server.IsHost == (useHost == HostOrServer.Host), $"{nameof(useHost)} does not match the server.IsHost value!");
636636

637637
Guid gameObjectId = NetworkManagerHelper.AddGameNetworkObject("NetworkVariableTestComponent");
638638

@@ -662,7 +662,7 @@ public void AllNetworkVariableTypes([Values(true, false)] bool useHost)
662662
}
663663

664664
[Test]
665-
public void ClientWritePermissionTest([Values(true, false)] bool useHost)
665+
public void ClientWritePermissionTest([Values] HostOrServer useHost)
666666
{
667667
InitializeServerAndClients(useHost);
668668

@@ -674,7 +674,7 @@ public void ClientWritePermissionTest([Values(true, false)] bool useHost)
674674
/// Runs tests that network variables sync on client whatever the local value of <see cref="Time.timeScale"/>.
675675
/// </summary>
676676
[Test]
677-
public void NetworkVariableSync_WithDifferentTimeScale([Values(true, false)] bool useHost, [Values(0.0f, 1.0f, 2.0f)] float timeScale)
677+
public void NetworkVariableSync_WithDifferentTimeScale([Values] HostOrServer useHost, [Values(0.0f, 1.0f, 2.0f)] float timeScale)
678678
{
679679
Time.timeScale = timeScale;
680680

@@ -688,7 +688,7 @@ public void NetworkVariableSync_WithDifferentTimeScale([Values(true, false)] boo
688688
}
689689

690690
[Test]
691-
public void FixedString32Test([Values(true, false)] bool useHost)
691+
public void FixedString32Test([Values] HostOrServer useHost)
692692
{
693693
InitializeServerAndClients(useHost);
694694
m_Player1OnServer.FixedString32.Value = k_FixedStringTestValue;
@@ -699,23 +699,23 @@ public void FixedString32Test([Values(true, false)] bool useHost)
699699
}
700700

701701
[Test]
702-
public void NetworkListAdd([Values(true, false)] bool useHost)
702+
public void NetworkListAdd([Values] HostOrServer useHost)
703703
{
704704
InitializeServerAndClients(useHost);
705705
m_NetworkListPredicateHandler = new NetworkListTestPredicate(m_Player1OnServer, m_Player1OnClient1, NetworkListTestPredicate.NetworkListTestStates.Add, 10);
706706
Assert.True(WaitForConditionOrTimeOutWithTimeTravel(m_NetworkListPredicateHandler));
707707
}
708708

709709
[Test]
710-
public void WhenListContainsManyLargeValues_OverflowExceptionIsNotThrown([Values(true, false)] bool useHost)
710+
public void WhenListContainsManyLargeValues_OverflowExceptionIsNotThrown([Values] HostOrServer useHost)
711711
{
712712
InitializeServerAndClients(useHost);
713713
m_NetworkListPredicateHandler = new NetworkListTestPredicate(m_Player1OnServer, m_Player1OnClient1, NetworkListTestPredicate.NetworkListTestStates.ContainsLarge, 20);
714714
Assert.True(WaitForConditionOrTimeOutWithTimeTravel(m_NetworkListPredicateHandler));
715715
}
716716

717717
[Test]
718-
public void NetworkListContains([Values(true, false)] bool useHost)
718+
public void NetworkListContains([Values] HostOrServer useHost)
719719
{
720720
// Re-use the NetworkListAdd to initialize the server and client as well as make sure the list is populated
721721
NetworkListAdd(useHost);
@@ -725,23 +725,9 @@ public void NetworkListContains([Values(true, false)] bool useHost)
725725
Assert.True(WaitForConditionOrTimeOutWithTimeTravel(m_NetworkListPredicateHandler));
726726
}
727727

728-
[Test]
729-
public void NetworkListRemove([Values(true, false)] bool useHost)
730-
{
731-
// Re-use the NetworkListAdd to initialize the server and client as well as make sure the list is populated
732-
NetworkListAdd(useHost);
733-
734-
// Remove two entries by index
735-
m_Player1OnServer.TheList.Remove(3);
736-
m_Player1OnServer.TheList.Remove(5);
737-
738-
// Really just verifies the data at this point
739-
m_NetworkListPredicateHandler.SetNetworkListTestState(NetworkListTestPredicate.NetworkListTestStates.VerifyData);
740-
Assert.True(WaitForConditionOrTimeOutWithTimeTravel(m_NetworkListPredicateHandler));
741-
}
742728

743729
[Test]
744-
public void NetworkListInsert([Values(true, false)] bool useHost)
730+
public void NetworkListInsert([Values] HostOrServer useHost)
745731
{
746732
// Re-use the NetworkListAdd to initialize the server and client as well as make sure the list is populated
747733
NetworkListAdd(useHost);
@@ -755,7 +741,7 @@ public void NetworkListInsert([Values(true, false)] bool useHost)
755741
}
756742

757743
[Test]
758-
public void NetworkListIndexOf([Values(true, false)] bool useHost)
744+
public void NetworkListIndexOf([Values] HostOrServer useHost)
759745
{
760746
// Re-use the NetworkListAdd to initialize the server and client as well as make sure the list is populated
761747
NetworkListAdd(useHost);
@@ -765,7 +751,7 @@ public void NetworkListIndexOf([Values(true, false)] bool useHost)
765751
}
766752

767753
[Test]
768-
public void NetworkListValueUpdate([Values(true, false)] bool useHost)
754+
public void NetworkListValueUpdate([Values] HostOrServer useHost)
769755
{
770756
var testSucceeded = false;
771757
InitializeServerAndClients(useHost);
@@ -796,24 +782,68 @@ void TestValueUpdatedCallback(NetworkListEvent<int> changedEvent)
796782
m_Player1OnClient1.TheList.OnListChanged -= TestValueUpdatedCallback;
797783
}
798784

785+
private List<int> m_ExpectedValuesServer = new List<int>();
786+
private List<int> m_ExpectedValuesClient = new List<int>();
787+
788+
public enum ListRemoveTypes
789+
{
790+
Remove,
791+
RemoveAt
792+
}
793+
794+
799795
[Test]
800-
public void NetworkListRemoveAt([Values(true, false)] bool useHost)
796+
public void NetworkListRemoveTests([Values] HostOrServer useHost, [Values] ListRemoveTypes listRemoveType)
801797
{
798+
m_ExpectedValuesServer.Clear();
799+
m_ExpectedValuesClient.Clear();
802800
// Re-use the NetworkListAdd to initialize the server and client as well as make sure the list is populated
803801
NetworkListAdd(useHost);
804802

805803
// Randomly remove a few entries
806-
m_Player1OnServer.TheList.RemoveAt(Random.Range(0, m_Player1OnServer.TheList.Count - 1));
807-
m_Player1OnServer.TheList.RemoveAt(Random.Range(0, m_Player1OnServer.TheList.Count - 1));
808-
m_Player1OnServer.TheList.RemoveAt(Random.Range(0, m_Player1OnServer.TheList.Count - 1));
804+
m_Player1OnServer.TheList.OnListChanged += Server_OnListChanged;
805+
m_Player1OnClient1.TheList.OnListChanged += Client_OnListChanged;
806+
807+
// Remove half of the elements
808+
for (int i = 0; i < (int)(m_Player1OnServer.TheList.Count * 0.5f); i++)
809+
{
810+
var index = Random.Range(0, m_Player1OnServer.TheList.Count - 1);
811+
var value = m_Player1OnServer.TheList[index];
812+
m_ExpectedValuesServer.Add(value);
813+
m_ExpectedValuesClient.Add(value);
814+
815+
if (listRemoveType == ListRemoveTypes.RemoveAt)
816+
{
817+
m_Player1OnServer.TheList.RemoveAt(index);
818+
}
819+
else
820+
{
821+
m_Player1OnServer.TheList.Remove(value);
822+
}
823+
}
809824

810825
// Verify the element count and values on the client matches the server
811826
m_NetworkListPredicateHandler.SetNetworkListTestState(NetworkListTestPredicate.NetworkListTestStates.VerifyData);
812827
Assert.True(WaitForConditionOrTimeOutWithTimeTravel(m_NetworkListPredicateHandler));
828+
829+
Assert.True(m_ExpectedValuesServer.Count == 0, $"Server was not notified of all elements removed and still has {m_ExpectedValuesServer.Count} elements left!");
830+
Assert.True(m_ExpectedValuesClient.Count == 0, $"Client was not notified of all elements removed and still has {m_ExpectedValuesClient.Count} elements left!");
831+
}
832+
833+
private void Server_OnListChanged(NetworkListEvent<int> changeEvent)
834+
{
835+
Assert.True(m_ExpectedValuesServer.Contains(changeEvent.Value));
836+
m_ExpectedValuesServer.Remove(changeEvent.Value);
837+
}
838+
839+
private void Client_OnListChanged(NetworkListEvent<int> changeEvent)
840+
{
841+
Assert.True(m_ExpectedValuesClient.Contains(changeEvent.Value));
842+
m_ExpectedValuesClient.Remove(changeEvent.Value);
813843
}
814844

815845
[Test]
816-
public void NetworkListClear([Values(true, false)] bool useHost)
846+
public void NetworkListClear([Values] HostOrServer useHost)
817847
{
818848
// Re-use the NetworkListAdd to initialize the server and client as well as make sure the list is populated
819849
NetworkListAdd(useHost);
@@ -824,7 +854,7 @@ public void NetworkListClear([Values(true, false)] bool useHost)
824854
}
825855

826856
[Test]
827-
public void TestNetworkVariableClass([Values(true, false)] bool useHost)
857+
public void TestNetworkVariableClass([Values] HostOrServer useHost)
828858
{
829859
InitializeServerAndClients(useHost);
830860

@@ -843,7 +873,7 @@ bool VerifyClass()
843873
}
844874

845875
[Test]
846-
public void TestNetworkVariableTemplateClass([Values(true, false)] bool useHost)
876+
public void TestNetworkVariableTemplateClass([Values] HostOrServer useHost)
847877
{
848878
InitializeServerAndClients(useHost);
849879

@@ -861,7 +891,7 @@ bool VerifyClass()
861891
}
862892

863893
[Test]
864-
public void TestNetworkListStruct([Values(true, false)] bool useHost)
894+
public void TestNetworkListStruct([Values] HostOrServer useHost)
865895
{
866896
InitializeServerAndClients(useHost);
867897

@@ -881,7 +911,7 @@ bool VerifyList()
881911
}
882912

883913
[Test]
884-
public void TestNetworkVariableStruct([Values(true, false)] bool useHost)
914+
public void TestNetworkVariableStruct([Values] HostOrServer useHost)
885915
{
886916
InitializeServerAndClients(useHost);
887917

@@ -899,7 +929,7 @@ bool VerifyStructure()
899929
}
900930

901931
[Test]
902-
public void TestNetworkVariableTemplateStruct([Values(true, false)] bool useHost)
932+
public void TestNetworkVariableTemplateStruct([Values] HostOrServer useHost)
903933
{
904934
InitializeServerAndClients(useHost);
905935

@@ -917,7 +947,7 @@ bool VerifyStructure()
917947
}
918948

919949
[Test]
920-
public void TestNetworkVariableTemplateBehaviourClass([Values(true, false)] bool useHost)
950+
public void TestNetworkVariableTemplateBehaviourClass([Values] HostOrServer useHost)
921951
{
922952
InitializeServerAndClients(useHost);
923953

@@ -939,7 +969,7 @@ bool VerifyClass()
939969
}
940970

941971
[Test]
942-
public void TestNetworkVariableTemplateBehaviourClassNotReferencedElsewhere([Values(true, false)] bool useHost)
972+
public void TestNetworkVariableTemplateBehaviourClassNotReferencedElsewhere([Values] HostOrServer useHost)
943973
{
944974
InitializeServerAndClients(useHost);
945975

@@ -957,7 +987,7 @@ bool VerifyClass()
957987
}
958988

959989
[Test]
960-
public void TestNetworkVariableTemplateBehaviourStruct([Values(true, false)] bool useHost)
990+
public void TestNetworkVariableTemplateBehaviourStruct([Values] HostOrServer useHost)
961991
{
962992
InitializeServerAndClients(useHost);
963993

@@ -975,7 +1005,7 @@ bool VerifyClass()
9751005
}
9761006

9771007
[Test]
978-
public void TestNetworkVariableEnum([Values(true, false)] bool useHost)
1008+
public void TestNetworkVariableEnum([Values] HostOrServer useHost)
9791009
{
9801010
InitializeServerAndClients(useHost);
9811011

@@ -992,7 +1022,7 @@ bool VerifyStructure()
9921022
}
9931023

9941024
[Test]
995-
public void TestINetworkSerializableClassCallsNetworkSerialize([Values(true, false)] bool useHost)
1025+
public void TestINetworkSerializableClassCallsNetworkSerialize([Values] HostOrServer useHost)
9961026
{
9971027
InitializeServerAndClients(useHost);
9981028
TestClass.NetworkSerializeCalledOnWrite = false;
@@ -1010,7 +1040,7 @@ public void TestINetworkSerializableClassCallsNetworkSerialize([Values(true, fal
10101040
}
10111041

10121042
[Test]
1013-
public void TestINetworkSerializableStructCallsNetworkSerialize([Values(true, false)] bool useHost)
1043+
public void TestINetworkSerializableStructCallsNetworkSerialize([Values] HostOrServer useHost)
10141044
{
10151045
InitializeServerAndClients(useHost);
10161046
TestStruct.NetworkSerializeCalledOnWrite = false;
@@ -1023,41 +1053,6 @@ public void TestINetworkSerializableStructCallsNetworkSerialize([Values(true, fa
10231053
Assert.True(WaitForConditionOrTimeOutWithTimeTravel(VerifyCallback));
10241054
}
10251055

1026-
[Test]
1027-
[Ignore("This is used several times already in the NetworkListPredicate")]
1028-
// TODO: If we end up using the new suggested pattern, then delete this
1029-
public void NetworkListArrayOperator([Values(true, false)] bool useHost)
1030-
{
1031-
NetworkListAdd(useHost);
1032-
}
1033-
1034-
[Test]
1035-
[Ignore("This is used several times already in the NetworkListPredicate")]
1036-
// TODO: If we end up using the new suggested pattern, then delete this
1037-
public void NetworkListIEnumerator([Values(true, false)] bool useHost)
1038-
{
1039-
InitializeServerAndClients(useHost);
1040-
var correctVals = new int[3];
1041-
correctVals[0] = k_TestVal1;
1042-
correctVals[1] = k_TestVal2;
1043-
correctVals[2] = k_TestVal3;
1044-
1045-
m_Player1OnServer.TheList.Add(correctVals[0]);
1046-
m_Player1OnServer.TheList.Add(correctVals[1]);
1047-
m_Player1OnServer.TheList.Add(correctVals[2]);
1048-
1049-
Assert.IsTrue(m_Player1OnServer.TheList.Count == 3);
1050-
1051-
int index = 0;
1052-
foreach (var val in m_Player1OnServer.TheList)
1053-
{
1054-
if (val != correctVals[index++])
1055-
{
1056-
Assert.Fail();
1057-
}
1058-
}
1059-
}
1060-
10611056
[Test]
10621057
public void TestUnsupportedManagedTypesThrowExceptions()
10631058
{

0 commit comments

Comments
 (0)