@@ -15,27 +15,30 @@ namespace Unity.Netcode.RuntimeTests
15
15
public static class MultiInstanceHelpers
16
16
{
17
17
public const int DefaultMinFrames = 1 ;
18
- public const int DefaultMaxFrames = 64 ;
18
+ public const float DefaultTimeout = 1f ;
19
19
private static List < NetworkManager > s_NetworkManagerInstances = new List < NetworkManager > ( ) ;
20
20
private static Dictionary < NetworkManager , MultiInstanceHooks > s_Hooks = new Dictionary < NetworkManager , MultiInstanceHooks > ( ) ;
21
21
private static bool s_IsStarted ;
22
22
private static int s_ClientCount ;
23
23
private static int s_OriginalTargetFrameRate = - 1 ;
24
24
25
- public delegate bool MessageReceiptCheck ( object receivedMessage ) ;
25
+ public delegate bool MessageHandleCheck ( object receivedMessage ) ;
26
26
27
- private class MultiInstanceHooks : INetworkHooks
27
+ internal class MessageHandleCheckWithResult
28
28
{
29
- public bool IsWaiting ;
29
+ public MessageHandleCheck Check ;
30
+ public bool Result ;
31
+ }
30
32
31
- public MessageReceiptCheck ReceiptCheck ;
33
+ private class MultiInstanceHooks : INetworkHooks
34
+ {
35
+ public Dictionary < Type , List < MessageHandleCheckWithResult > > HandleChecks = new Dictionary < Type , List < MessageHandleCheckWithResult > > ( ) ;
32
36
33
37
public static bool CheckForMessageOfType < T > ( object receivedMessage ) where T : INetworkMessage
34
38
{
35
- return receivedMessage is T ;
39
+ return receivedMessage . GetType ( ) == typeof ( T ) ;
36
40
}
37
41
38
-
39
42
public void OnBeforeSendMessage < T > ( ulong clientId , ref T message , NetworkDelivery delivery ) where T : INetworkMessage
40
43
{
41
44
}
@@ -84,9 +87,17 @@ public void OnBeforeHandleMessage<T>(ref T message, ref NetworkContext context)
84
87
85
88
public void OnAfterHandleMessage < T > ( ref T message , ref NetworkContext context ) where T : INetworkMessage
86
89
{
87
- if ( IsWaiting && ( ReceiptCheck == null || ReceiptCheck . Invoke ( message ) ) )
90
+ if ( HandleChecks . ContainsKey ( typeof ( T ) ) )
88
91
{
89
- IsWaiting = false ;
92
+ foreach ( var check in HandleChecks [ typeof ( T ) ] )
93
+ {
94
+ if ( check . Check ( message ) )
95
+ {
96
+ check . Result = true ;
97
+ HandleChecks [ typeof ( T ) ] . Remove ( check ) ;
98
+ break ;
99
+ }
100
+ }
90
101
}
91
102
}
92
103
}
@@ -471,9 +482,9 @@ public static void MarkAsSceneObjectRoot(GameObject networkObjectRoot, NetworkMa
471
482
/// <param name="client">The client</param>
472
483
/// <param name="result">The result. If null, it will automatically assert</param>
473
484
/// <param name="maxFrames">The max frames to wait for</param>
474
- public static IEnumerator WaitForClientConnected ( NetworkManager client , CoroutineResultWrapper < bool > result = null , int maxFrames = DefaultMaxFrames )
485
+ public static IEnumerator WaitForClientConnected ( NetworkManager client , CoroutineResultWrapper < bool > result = null , float timeout = DefaultTimeout )
475
486
{
476
- yield return WaitForClientsConnected ( new NetworkManager [ ] { client } , result , maxFrames ) ;
487
+ yield return WaitForClientsConnected ( new NetworkManager [ ] { client } , result , timeout ) ;
477
488
}
478
489
479
490
/// <summary>
@@ -483,7 +494,7 @@ public static IEnumerator WaitForClientConnected(NetworkManager client, Coroutin
483
494
/// <param name="result">The result. If null, it will automatically assert<</param>
484
495
/// <param name="maxFrames">The max frames to wait for</param>
485
496
/// <returns></returns>
486
- public static IEnumerator WaitForClientsConnected ( NetworkManager [ ] clients , CoroutineResultWrapper < bool > result = null , int maxFrames = DefaultMaxFrames )
497
+ public static IEnumerator WaitForClientsConnected ( NetworkManager [ ] clients , CoroutineResultWrapper < bool > result = null , float timeout = DefaultTimeout )
487
498
{
488
499
// Make sure none are the host client
489
500
foreach ( var client in clients )
@@ -494,9 +505,10 @@ public static IEnumerator WaitForClientsConnected(NetworkManager[] clients, Coro
494
505
}
495
506
}
496
507
497
- var startFrameNumber = Time . frameCount ;
498
508
var allConnected = true ;
499
- while ( Time . frameCount - startFrameNumber <= maxFrames )
509
+ var startTime = Time . realtimeSinceStartup ;
510
+
511
+ while ( Time . realtimeSinceStartup - startTime < timeout )
500
512
{
501
513
allConnected = true ;
502
514
foreach ( var client in clients )
@@ -537,9 +549,9 @@ public static IEnumerator WaitForClientsConnected(NetworkManager[] clients, Coro
537
549
/// <param name="server">The server</param>
538
550
/// <param name="result">The result. If null, it will automatically assert</param>
539
551
/// <param name="maxFrames">The max frames to wait for</param>
540
- public static IEnumerator WaitForClientConnectedToServer ( NetworkManager server , CoroutineResultWrapper < bool > result = null , int maxFrames = DefaultMaxFrames )
552
+ public static IEnumerator WaitForClientConnectedToServer ( NetworkManager server , CoroutineResultWrapper < bool > result = null , float timeout = DefaultTimeout )
541
553
{
542
- yield return WaitForClientsConnectedToServer ( server , server . IsHost ? s_ClientCount + 1 : s_ClientCount , result , maxFrames ) ;
554
+ yield return WaitForClientsConnectedToServer ( server , server . IsHost ? s_ClientCount + 1 : s_ClientCount , result , timeout ) ;
543
555
}
544
556
545
557
/// <summary>
@@ -548,16 +560,16 @@ public static IEnumerator WaitForClientConnectedToServer(NetworkManager server,
548
560
/// <param name="server">The server</param>
549
561
/// <param name="result">The result. If null, it will automatically assert</param>
550
562
/// <param name="maxFrames">The max frames to wait for</param>
551
- public static IEnumerator WaitForClientsConnectedToServer ( NetworkManager server , int clientCount = 1 , CoroutineResultWrapper < bool > result = null , int maxFrames = DefaultMaxFrames )
563
+ public static IEnumerator WaitForClientsConnectedToServer ( NetworkManager server , int clientCount = 1 , CoroutineResultWrapper < bool > result = null , float timeout = DefaultTimeout )
552
564
{
553
565
if ( ! server . IsServer )
554
566
{
555
567
throw new InvalidOperationException ( "Cannot wait for connected as client" ) ;
556
568
}
557
569
558
- var startFrameNumber = Time . frameCount ;
570
+ var startTime = Time . realtimeSinceStartup ;
559
571
560
- while ( Time . frameCount - startFrameNumber <= maxFrames && server . ConnectedClients . Count != clientCount )
572
+ while ( Time . realtimeSinceStartup - startTime < timeout && server . ConnectedClients . Count != clientCount )
561
573
{
562
574
var nextFrameNumber = Time . frameCount + 1 ;
563
575
yield return new WaitUntil ( ( ) => Time . frameCount >= nextFrameNumber ) ;
@@ -583,16 +595,16 @@ public static IEnumerator WaitForClientsConnectedToServer(NetworkManager server,
583
595
/// <param name="result">The result</param>
584
596
/// <param name="failIfNull">Whether or not to fail if no object is found and result is null</param>
585
597
/// <param name="maxFrames">The max frames to wait for</param>
586
- public static IEnumerator GetNetworkObjectByRepresentation ( ulong networkObjectId , NetworkManager representation , CoroutineResultWrapper < NetworkObject > result , bool failIfNull = true , int maxFrames = DefaultMaxFrames )
598
+ public static IEnumerator GetNetworkObjectByRepresentation ( ulong networkObjectId , NetworkManager representation , CoroutineResultWrapper < NetworkObject > result , bool failIfNull = true , float timeout = DefaultTimeout )
587
599
{
588
600
if ( result == null )
589
601
{
590
602
throw new ArgumentNullException ( "Result cannot be null" ) ;
591
603
}
592
604
593
- var startFrameNumber = Time . frameCount ;
605
+ var startTime = Time . realtimeSinceStartup ;
594
606
595
- while ( Time . frameCount - startFrameNumber <= maxFrames && representation . SpawnManager . SpawnedObjects . All ( x => x . Value . NetworkObjectId != networkObjectId ) )
607
+ while ( Time . realtimeSinceStartup - startTime < timeout && representation . SpawnManager . SpawnedObjects . All ( x => x . Value . NetworkObjectId != networkObjectId ) )
596
608
{
597
609
var nextFrameNumber = Time . frameCount + 1 ;
598
610
yield return new WaitUntil ( ( ) => Time . frameCount >= nextFrameNumber ) ;
@@ -614,7 +626,7 @@ public static IEnumerator GetNetworkObjectByRepresentation(ulong networkObjectId
614
626
/// <param name="result">The result</param>
615
627
/// <param name="failIfNull">Whether or not to fail if no object is found and result is null</param>
616
628
/// <param name="maxFrames">The max frames to wait for</param>
617
- public static IEnumerator GetNetworkObjectByRepresentation ( Func < NetworkObject , bool > predicate , NetworkManager representation , CoroutineResultWrapper < NetworkObject > result , bool failIfNull = true , int maxFrames = DefaultMaxFrames )
629
+ public static IEnumerator GetNetworkObjectByRepresentation ( Func < NetworkObject , bool > predicate , NetworkManager representation , CoroutineResultWrapper < NetworkObject > result , bool failIfNull = true , float timeout = DefaultTimeout )
618
630
{
619
631
if ( result == null )
620
632
{
@@ -626,9 +638,9 @@ public static IEnumerator GetNetworkObjectByRepresentation(Func<NetworkObject, b
626
638
throw new ArgumentNullException ( "Predicate cannot be null" ) ;
627
639
}
628
640
629
- var startFrame = Time . frameCount ;
641
+ var startTime = Time . realtimeSinceStartup ;
630
642
631
- while ( Time . frameCount - startFrame <= maxFrames && ! representation . SpawnManager . SpawnedObjects . Any ( x => predicate ( x . Value ) ) )
643
+ while ( Time . realtimeSinceStartup - startTime < timeout && ! representation . SpawnManager . SpawnedObjects . Any ( x => predicate ( x . Value ) ) )
632
644
{
633
645
var nextFrameNumber = Time . frameCount + 1 ;
634
646
yield return new WaitUntil ( ( ) => Time . frameCount >= nextFrameNumber ) ;
@@ -648,15 +660,15 @@ public static IEnumerator GetNetworkObjectByRepresentation(Func<NetworkObject, b
648
660
/// <param name="workload">Action / code to run</param>
649
661
/// <param name="predicate">The predicate to wait for</param>
650
662
/// <param name="maxFrames">The max frames to wait for</param>
651
- public static IEnumerator RunAndWaitForCondition ( Action workload , Func < bool > predicate , int maxFrames = DefaultMaxFrames , int minFrames = DefaultMinFrames )
663
+ public static IEnumerator RunAndWaitForCondition ( Action workload , Func < bool > predicate , float timeout = DefaultTimeout , int minFrames = DefaultMinFrames )
652
664
{
653
665
var waitResult = new CoroutineResultWrapper < bool > ( ) ;
654
666
workload ( ) ;
655
667
656
668
yield return Run ( WaitForCondition (
657
669
predicate ,
658
670
waitResult ,
659
- maxFrames : maxFrames ,
671
+ timeout : timeout ,
660
672
minFrames : minFrames ) ) ;
661
673
662
674
if ( ! waitResult . Result )
@@ -672,33 +684,26 @@ public static IEnumerator RunAndWaitForCondition(Action workload, Func<bool> pre
672
684
/// <param name="result">The result. If null, it will fail if the predicate is not met</param>
673
685
/// <param name="minFrames">The min frames to wait for</param>
674
686
/// <param name="maxFrames">The max frames to wait for</param>
675
- public static IEnumerator WaitForCondition ( Func < bool > predicate , CoroutineResultWrapper < bool > result = null , int maxFrames = DefaultMaxFrames , int minFrames = DefaultMinFrames )
687
+ public static IEnumerator WaitForCondition ( Func < bool > predicate , CoroutineResultWrapper < bool > result = null , float timeout = DefaultTimeout , int minFrames = DefaultMinFrames )
676
688
{
677
689
if ( predicate == null )
678
690
{
679
691
throw new ArgumentNullException ( "Predicate cannot be null" ) ;
680
692
}
681
693
682
- var startFrameNumber = Time . frameCount ;
694
+ var startTime = Time . realtimeSinceStartup ;
683
695
684
696
if ( minFrames > 0 )
685
697
{
686
- yield return new WaitUntil ( ( ) =>
687
- {
688
- return Time . frameCount >= minFrames ;
689
- } ) ;
698
+ yield return new WaitUntil ( ( ) => Time . frameCount >= minFrames ) ;
690
699
}
691
700
692
- while ( Time . frameCount - startFrameNumber <= maxFrames &&
693
- ! predicate ( ) )
701
+ while ( Time . realtimeSinceStartup - startTime < timeout && ! predicate ( ) )
694
702
{
695
703
// Changed to 2 frames to avoid the scenario where it would take 1+ frames to
696
704
// see a value change (i.e. discovered in the NetworkTransformTests)
697
705
var nextFrameNumber = Time . frameCount + 2 ;
698
- yield return new WaitUntil ( ( ) =>
699
- {
700
- return Time . frameCount >= nextFrameNumber ;
701
- } ) ;
706
+ yield return new WaitUntil ( ( ) => Time . frameCount >= nextFrameNumber ) ;
702
707
}
703
708
704
709
var res = predicate ( ) ;
@@ -721,12 +726,17 @@ public static IEnumerator WaitForCondition(Func<bool> predicate, CoroutineResult
721
726
internal static IEnumerator WaitForMessageOfType < T > ( NetworkManager toBeReceivedBy , CoroutineResultWrapper < bool > result = null , float timeout = 0.5f ) where T : INetworkMessage
722
727
{
723
728
var hooks = s_Hooks [ toBeReceivedBy ] ;
724
- hooks . ReceiptCheck = MultiInstanceHooks . CheckForMessageOfType < T > ;
729
+ if ( ! hooks . HandleChecks . ContainsKey ( typeof ( T ) ) )
730
+ {
731
+ hooks . HandleChecks . Add ( typeof ( T ) , new List < MessageHandleCheckWithResult > ( ) ) ;
732
+ }
733
+ var check = new MessageHandleCheckWithResult { Check = MultiInstanceHooks . CheckForMessageOfType < T > } ;
734
+ hooks . HandleChecks [ typeof ( T ) ] . Add ( check ) ;
725
735
if ( result == null )
726
736
{
727
737
result = new CoroutineResultWrapper < bool > ( ) ;
728
738
}
729
- yield return ExecuteWaitForHook ( hooks , result , timeout ) ;
739
+ yield return ExecuteWaitForHook ( check , result , timeout ) ;
730
740
731
741
Assert . True ( result . Result , $ "Expected message { typeof ( T ) . Name } was not received within { timeout } s.") ;
732
742
}
@@ -737,33 +747,34 @@ internal static IEnumerator WaitForMessageOfType<T>(NetworkManager toBeReceivedB
737
747
/// <param name="requirement">Called for each received message to check if it's the right one</param>
738
748
/// <param name="result">The result. If null, it will fail if the predicate is not met</param>
739
749
/// <param name="timeout">The max time in seconds to wait for</param>
740
- internal static IEnumerator WaitForMessageMeetingRequirement ( NetworkManager toBeReceivedBy , MessageReceiptCheck requirement , CoroutineResultWrapper < bool > result = null , float timeout = 0.5f )
750
+ internal static IEnumerator WaitForMessageMeetingRequirement < T > ( NetworkManager toBeReceivedBy , MessageHandleCheck requirement , CoroutineResultWrapper < bool > result = null , float timeout = DefaultTimeout )
741
751
{
742
752
var hooks = s_Hooks [ toBeReceivedBy ] ;
743
- hooks . ReceiptCheck = requirement ;
753
+ if ( ! hooks . HandleChecks . ContainsKey ( typeof ( T ) ) )
754
+ {
755
+ hooks . HandleChecks . Add ( typeof ( T ) , new List < MessageHandleCheckWithResult > ( ) ) ;
756
+ }
757
+ var check = new MessageHandleCheckWithResult { Check = requirement } ;
758
+ hooks . HandleChecks [ typeof ( T ) ] . Add ( check ) ;
744
759
if ( result == null )
745
760
{
746
761
result = new CoroutineResultWrapper < bool > ( ) ;
747
762
}
748
- yield return ExecuteWaitForHook ( hooks , result , timeout ) ;
763
+ yield return ExecuteWaitForHook ( check , result , timeout ) ;
749
764
750
765
Assert . True ( result . Result , $ "Expected message meeting user requirements was not received within { timeout } s.") ;
751
766
}
752
767
753
- private static IEnumerator ExecuteWaitForHook ( MultiInstanceHooks hooks , CoroutineResultWrapper < bool > result , float timeout )
768
+ private static IEnumerator ExecuteWaitForHook ( MessageHandleCheckWithResult check , CoroutineResultWrapper < bool > result , float timeout )
754
769
{
755
- hooks . IsWaiting = true ;
756
-
757
770
var startTime = Time . realtimeSinceStartup ;
758
771
759
- while ( hooks . IsWaiting && Time . realtimeSinceStartup - startTime < timeout )
772
+ while ( ! check . Result && Time . realtimeSinceStartup - startTime < timeout )
760
773
{
761
774
yield return null ;
762
775
}
763
776
764
- var res = ! hooks . IsWaiting ;
765
- hooks . IsWaiting = false ;
766
- hooks . ReceiptCheck = null ;
777
+ var res = check . Result ;
767
778
result . Result = res ;
768
779
}
769
780
0 commit comments