From 96606f208defb66e2ea752db004c68dec2a71f8d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 26 Nov 2021 14:24:01 +0100 Subject: [PATCH] Enable fast paths for IRecipient recipients --- .../Messaging/IMessengerExtensions.cs | 18 ++++++++- .../Messaging/WeakReferenceMessenger.cs | 40 ++++++++++++++++++- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/CommunityToolkit.Mvvm/Messaging/IMessengerExtensions.cs b/CommunityToolkit.Mvvm/Messaging/IMessengerExtensions.cs index cce5b277..67aa89ae 100644 --- a/CommunityToolkit.Mvvm/Messaging/IMessengerExtensions.cs +++ b/CommunityToolkit.Mvvm/Messaging/IMessengerExtensions.cs @@ -226,7 +226,14 @@ public static class IMessengerExtensions public static void Register(this IMessenger messenger, IRecipient recipient) where TMessage : class { - messenger.Register, TMessage, Unit>(recipient, default, static (r, m) => r.Receive(m)); + if (messenger is WeakReferenceMessenger weakReferenceMessenger) + { + weakReferenceMessenger.Register(recipient, default); + } + else + { + messenger.Register, TMessage, Unit>(recipient, default, static (r, m) => r.Receive(m)); + } } /// @@ -243,7 +250,14 @@ public static class IMessengerExtensions where TMessage : class where TToken : IEquatable { - messenger.Register, TMessage, TToken>(recipient, token, static (r, m) => r.Receive(m)); + if (messenger is WeakReferenceMessenger weakReferenceMessenger) + { + weakReferenceMessenger.Register(recipient, token); + } + else + { + messenger.Register, TMessage, TToken>(recipient, token, static (r, m) => r.Receive(m)); + } } /// diff --git a/CommunityToolkit.Mvvm/Messaging/WeakReferenceMessenger.cs b/CommunityToolkit.Mvvm/Messaging/WeakReferenceMessenger.cs index e9f57d1c..3688b66a 100644 --- a/CommunityToolkit.Mvvm/Messaging/WeakReferenceMessenger.cs +++ b/CommunityToolkit.Mvvm/Messaging/WeakReferenceMessenger.cs @@ -118,6 +118,42 @@ public sealed class WeakReferenceMessenger : IMessenger where TRecipient : class where TMessage : class where TToken : IEquatable + { + Register(recipient, token, new MessageHandlerDispatcher.For(handler)); + } + + /// + /// Registers a recipient for a given type of message. + /// + /// The type of message to receive. + /// The type of token to use to pick the messages to receive. + /// The recipient that will receive the messages. + /// A token used to determine the receiving channel to use. + /// Thrown when trying to register the same message twice. + /// + /// This method is a variation of + /// that is specialized for recipients implementing . See more comments at the top of this type, as well as + /// within and in the types. + /// + internal void Register(IRecipient recipient, TToken token) + where TMessage : class + where TToken : IEquatable + { + Register(recipient, token, MessageHandlerDispatcher.IRecipient.Instance); + } + + /// + /// Registers a recipient for a given type of message. + /// + /// The type of message to receive. + /// The type of token to use to pick the messages to receive. + /// The recipient that will receive the messages. + /// A token used to determine the receiving channel to use. + /// The input instance to register. + /// Thrown when trying to register the same message twice. + private void Register(object recipient, TToken token, MessageHandlerDispatcher dispatcher) + where TMessage : class + where TToken : IEquatable { lock (this.recipientsMap) { @@ -131,7 +167,7 @@ public sealed class WeakReferenceMessenger : IMessenger // Fast path for unit tokens if (typeof(TToken) == typeof(Unit)) { - if (!mapping.TryAdd(recipient, new MessageHandlerDispatcher.For(handler))) + if (!mapping.TryAdd(recipient, dispatcher)) { ThrowInvalidOperationExceptionForDuplicateRegistration(); } @@ -150,7 +186,7 @@ public sealed class WeakReferenceMessenger : IMessenger } // Store the input handler - registeredHandler = new MessageHandlerDispatcher.For(handler); + registeredHandler = dispatcher; } } }