Code refactoring to WeakReferenceMessenger

This commit is contained in:
Sergio Pedri
2020-10-01 19:15:05 +02:00
parent 056b414853
commit e91ed46bb8
2 changed files with 11 additions and 47 deletions
@@ -1,41 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.CompilerServices;
namespace Microsoft.Toolkit.Mvvm.Messaging.Internals
{
/// <summary>
/// A simple type representing an immutable pair of objects.
/// </summary>
/// <remarks>
/// This type replaces a simple <see cref="ValueTuple{T1,T2}"/> when specifically dealing with a
/// pair of handler and recipient. Unlike <see cref="ValueTuple{T1,T2}"/>, this type is readonly.
/// </remarks>
internal readonly struct Object2
{
/// <summary>
/// Initializes a new instance of the <see cref="Object2"/> struct.
/// </summary>
/// <param name="handler">The input handler.</param>
/// <param name="recipient">The input recipient.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Object2(object handler, object recipient)
{
Handler = handler;
Recipient = recipient;
}
/// <summary>
/// The current handler (which is actually some <see cref="MessageHandler{TRecipient,TMessage}"/> instance.
/// </summary>
public readonly object Handler;
/// <summary>
/// The current recipient (guaranteed to match the type constraints for <see cref="MessageHandler{TRecipient,TMessage}"/>.
/// </summary>
public readonly object Recipient;
}
}
@@ -169,7 +169,8 @@ namespace Microsoft.Toolkit.Mvvm.Messaging
where TMessage : class
where TToken : IEquatable<TToken>
{
ArrayPoolBufferWriter<Object2> pairs;
ArrayPoolBufferWriter<object> bufferWriter;
int i = 0;
lock (this.recipientsMap)
{
@@ -181,7 +182,7 @@ namespace Microsoft.Toolkit.Mvvm.Messaging
return message;
}
pairs = ArrayPoolBufferWriter<Object2>.Create();
bufferWriter = ArrayPoolBufferWriter<object>.Create();
// We need a local, temporary copy of all the pending recipients and handlers to
// invoke, to avoid issues with handlers unregistering from messages while we're
@@ -195,26 +196,30 @@ namespace Microsoft.Toolkit.Mvvm.Messaging
if (map.TryGetValue(token, out object? handler))
{
pairs.Add(new Object2(handler!, pair.Key));
bufferWriter.Add(handler!);
bufferWriter.Add(pair.Key);
i++;
}
}
}
try
{
foreach (ref readonly Object2 pair in pairs.Span)
ReadOnlySpan<object> pairs = bufferWriter.Span;
for (int j = 0; j < i; j++)
{
// Just like in the other messenger, here we need an unsafe cast to be able to
// invoke a generic delegate with a contravariant input argument, with a less
// derived reference, without reflection. This is guaranteed to work by how the
// messenger tracks registered recipients and their associated handlers, so the
// type conversion will always be valid (the recipients are the rigth instances).
Unsafe.As<MessageHandler<object, TMessage>>(pair.Handler)(pair.Recipient, message);
Unsafe.As<MessageHandler<object, TMessage>>(pairs[2 * j])(pairs[(2 * j) + 1], message);
}
}
finally
{
pairs.Dispose();
bufferWriter.Dispose();
}
return message;