Skip to content

fix: Refactored DeferredMessagingTests to not use coroutines and increased the slush value for the two timing-based tests... #2248

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

Merged
merged 4 commits into from
Oct 11, 2022
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@ namespace Unity.Netcode.TestHelpers.Runtime
internal class MessageHooks : INetworkHooks
{
public bool IsWaiting = true;
public delegate bool MessageReceiptCheck(object receivedMessage);
public delegate bool MessageReceiptCheck(Type receivedMessageType);
public MessageReceiptCheck ReceiptCheck;
public delegate bool MessageHandleCheck(object receivedMessage);
public MessageHandleCheck HandleCheck;

public static bool CurrentMessageHasTriggerdAHook = false;

public static bool CheckForMessageOfType<T>(object receivedMessage) where T : INetworkMessage
public static bool CheckForMessageOfTypeHandled<T>(object receivedMessage) where T : INetworkMessage
{
return receivedMessage is T;
}
public static bool CheckForMessageOfTypeReceived<T>(Type receivedMessageType) where T : INetworkMessage
{
return receivedMessageType == typeof(T);
}

public void OnBeforeSendMessage<T>(ulong clientId, ref T message, NetworkDelivery delivery) where T : INetworkMessage
{
Expand All @@ -25,10 +31,24 @@ public void OnAfterSendMessage<T>(ulong clientId, ref T message, NetworkDelivery

public void OnBeforeReceiveMessage(ulong senderId, Type messageType, int messageSizeBytes)
{
// The way the system works, it goes through all hooks and calls OnBeforeHandleMessage, then handles the message,
// then goes thorugh all hooks and calls OnAfterHandleMessage.
// This ensures each message only manages to activate a single message hook - because we know that only
// one message will ever be handled between OnBeforeHandleMessage and OnAfterHandleMessage,
// we can reset the flag here, and then in OnAfterHandleMessage, the moment the message matches a hook,
// it'll flip this flag back on, and then other hooks will stop checking that message.
// Without this flag, waiting for 10 messages of the same type isn't possible - all 10 hooks would get
// tripped by the first message.
CurrentMessageHasTriggerdAHook = false;
}

public void OnAfterReceiveMessage(ulong senderId, Type messageType, int messageSizeBytes)
{
if (!CurrentMessageHasTriggerdAHook && IsWaiting && (HandleCheck == null || HandleCheck.Invoke(messageType)))
{
IsWaiting = false;
CurrentMessageHasTriggerdAHook = true;
}
}

public void OnBeforeSendBatch(ulong clientId, int messageCount, int batchSizeInBytes, NetworkDelivery delivery)
Expand Down Expand Up @@ -72,7 +92,7 @@ public void OnBeforeHandleMessage<T>(ref T message, ref NetworkContext context)

public void OnAfterHandleMessage<T>(ref T message, ref NetworkContext context) where T : INetworkMessage
{
if (!CurrentMessageHasTriggerdAHook && IsWaiting && (ReceiptCheck == null || ReceiptCheck.Invoke(message)))
if (!CurrentMessageHasTriggerdAHook && IsWaiting && (HandleCheck == null || HandleCheck.Invoke(message)))
{
IsWaiting = false;
CurrentMessageHasTriggerdAHook = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,42 +64,76 @@ public MessageHooksConditional(List<MessageHookEntry> messageHookEntries)
}
}

public enum ReceiptType
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😻
Love this update!

{
Received,
Handled
}

public class MessageHookEntry
{
internal MessageHooks MessageHooks;
protected NetworkManager m_NetworkManager;
private MessageHooks.MessageReceiptCheck m_MessageReceiptCheck;
private MessageHooks.MessageHandleCheck m_MessageHandleCheck;
internal string MessageType;
private ReceiptType m_ReceiptType;

public void Initialize()
{
Assert.IsNotNull(m_MessageReceiptCheck, $"{nameof(m_MessageReceiptCheck)} is null, did you forget to initialize?");
MessageHooks = new MessageHooks();
MessageHooks.ReceiptCheck = m_MessageReceiptCheck;
if (m_ReceiptType == ReceiptType.Handled)
{
Assert.IsNotNull(m_MessageHandleCheck, $"{nameof(m_MessageHandleCheck)} is null, did you forget to initialize?");
MessageHooks.HandleCheck = m_MessageHandleCheck;
}
else
{
Assert.IsNotNull(m_MessageReceiptCheck, $"{nameof(m_MessageReceiptCheck)} is null, did you forget to initialize?");
MessageHooks.ReceiptCheck = m_MessageReceiptCheck;
}
Assert.IsNotNull(m_NetworkManager.MessagingSystem, $"{nameof(NetworkManager.MessagingSystem)} is null! Did you forget to start first?");
m_NetworkManager.MessagingSystem.Hook(MessageHooks);
}

internal void AssignMessageType<T>() where T : INetworkMessage
{
MessageType = typeof(T).Name;
m_MessageReceiptCheck = MessageHooks.CheckForMessageOfType<T>;
if (m_ReceiptType == ReceiptType.Handled)
{
m_MessageHandleCheck = MessageHooks.CheckForMessageOfTypeHandled<T>;
}
else
{
m_MessageReceiptCheck = MessageHooks.CheckForMessageOfTypeReceived<T>;
}
Initialize();
}

internal void AssignMessageType(Type type)
{
MessageType = type.Name;
m_MessageReceiptCheck = (message) =>
if (m_ReceiptType == ReceiptType.Handled)
{
return message.GetType() == type;
};
m_MessageHandleCheck = (message) =>
{
return message.GetType() == type;
};
}
else
{
m_MessageReceiptCheck = (messageType) =>
{
return messageType == type;
};
}
Initialize();
}

public MessageHookEntry(NetworkManager networkManager)
public MessageHookEntry(NetworkManager networkManager, ReceiptType type = ReceiptType.Handled)
{
m_NetworkManager = networkManager;
m_ReceiptType = type;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -762,37 +762,39 @@ protected IEnumerator WaitForClientsConnectedOrTimeOut()
yield return WaitForClientsConnectedOrTimeOut(m_ClientNetworkManagers);
}

internal IEnumerator WaitForMessageReceived<T>(List<NetworkManager> wiatForReceivedBy) where T : INetworkMessage
internal IEnumerator WaitForMessageReceived<T>(List<NetworkManager> wiatForReceivedBy, ReceiptType type = ReceiptType.Handled) where T : INetworkMessage
{
// Build our message hook entries tables so we can determine if all clients received spawn or ownership messages
var messageHookEntriesForSpawn = new List<MessageHookEntry>();
foreach (var clientNetworkManager in wiatForReceivedBy)
{
var messageHook = new MessageHookEntry(clientNetworkManager);
var messageHook = new MessageHookEntry(clientNetworkManager, type);
messageHook.AssignMessageType<T>();
messageHookEntriesForSpawn.Add(messageHook);
}
// Used to determine if all clients received the CreateObjectMessage
var hooks = new MessageHooksConditional(messageHookEntriesForSpawn);
yield return WaitForConditionOrTimeOut(hooks);
Assert.False(s_GlobalTimeoutHelper.TimedOut);
}

internal IEnumerator WaitForMessagesReceived(List<Type> messagesInOrder, List<NetworkManager> wiatForReceivedBy)
internal IEnumerator WaitForMessagesReceived(List<Type> messagesInOrder, List<NetworkManager> wiatForReceivedBy, ReceiptType type = ReceiptType.Handled)
{
// Build our message hook entries tables so we can determine if all clients received spawn or ownership messages
var messageHookEntriesForSpawn = new List<MessageHookEntry>();
foreach (var clientNetworkManager in wiatForReceivedBy)
{
foreach (var message in messagesInOrder)
{
var messageHook = new MessageHookEntry(clientNetworkManager);
var messageHook = new MessageHookEntry(clientNetworkManager, type);
messageHook.AssignMessageType(message);
messageHookEntriesForSpawn.Add(messageHook);
}
}
// Used to determine if all clients received the CreateObjectMessage
var hooks = new MessageHooksConditional(messageHookEntriesForSpawn);
yield return WaitForConditionOrTimeOut(hooks);
Assert.False(s_GlobalTimeoutHelper.TimedOut);
}

/// <summary>
Expand Down
Loading