JD2022-TU1/main/tools/framework/JD.Remoting/Details/HandlerDictionary.cs

88 lines
No EOL
2.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using JD.Interfaces.Remoting;
namespace JD.Remoting.Details
{
/// <summary>
/// Helper class that helps to provide a specific handler for a given message.
/// </summary>
public class HandlerDictionary
{
private readonly Dictionary<string, List<Handler>> m_handlers = new Dictionary<string, List<Handler>>();
public Action<Action> DispatchOnMainThread = action => action();
public bool Handle(IMessage message)
{
bool handled = false;
foreach (var handler in GetHandlers(message.CommandName))
{
Execute(handler, message);
handled = true;
}
return handled;
}
public void Register(string messageName, Action<IBlob> handler, bool dispatchOnMainThread = true)
{
lock (m_handlers)
{
if (!m_handlers.TryGetValue(messageName, out List<Handler> handlers))
{
handlers = new List<Handler>();
m_handlers.Add(messageName, handlers);
}
handlers.Add(new Handler(dispatchOnMainThread, handler));
}
}
public void Unregister(string messageName, Action<IBlob> handler)
{
lock (m_handlers)
{
if (m_handlers.TryGetValue(messageName, out List<Handler> handlers))
{
handlers.RemoveAll(toRemove => toRemove.Action == handler);
}
}
}
private void Execute(Handler handler, IMessage message)
{
if (handler.DispatchOnMainThread)
{
DispatchOnMainThread(() => handler.Action(message.Content.ConvertToRead()));
}
else
{
handler.Action(message.Content.ConvertToRead());
}
}
private Handler[] GetHandlers(string commandName)
{
lock (m_handlers)
{
if (m_handlers.TryGetValue(commandName, out List<Handler> handlers))
{
// A copy so that is can be read outside the lock.
return handlers.ToArray();
}
}
return new Handler[0];
}
private class Handler
{
public bool DispatchOnMainThread { get; private set; }
public Action<IBlob> Action { get; private set; }
public Handler(bool dispatchOnMainThread, Action<IBlob> handler)
{
DispatchOnMainThread = dispatchOnMainThread;
Action = handler;
}
}
}
}