mirror of
https://github.com/CommunityToolkit/dotnet.git
synced 2026-10-22 15:16:24 +08:00
Code refactoring to WeakReferenceMessenger
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user