UniRxに入っているAsyncMessageBrokerのTaskバージョン
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
namespace Extensions
{
public interface ITaskMessagePublisher
{
UniTask PublishAsync<T>(T message);
}
public interface ITaskMessageReceiver
{
IDisposable Subscribe<T>(Func<T, UniTask> asyncMessageReceiver);
}
public interface ITaskMessageBroker : ITaskMessagePublisher, ITaskMessageReceiver
{
}
public class TaskMessageBroker : ITaskMessageBroker, IDisposable
{
/// <summary>
/// AsyncMessageBroker in Global scope.
/// </summary>
public static readonly ITaskMessageBroker Default = new TaskMessageBroker();
bool isDisposed = false;
readonly Dictionary<Type, object> notifiers = new Dictionary<Type, object>();
public UniTask PublishAsync<T>(T message)
{
List<Func<T, UniTask>> notifier;
lock (notifiers)
{
if (isDisposed) throw new ObjectDisposedException("TaskMessageBroker");
object _notifier;
if (notifiers.TryGetValue(typeof(T), out _notifier))
{
notifier = (List<Func<T, UniTask>>)_notifier;
}
else
{
return UniTask.CompletedTask;
}
}
return UniTask.WhenAll(notifier.Select(x => x.Invoke(message)));
}
public IDisposable Subscribe<T>(Func<T, UniTask> asyncMessageReceiver)
{
lock (notifiers)
{
if (isDisposed) throw new ObjectDisposedException("TaskMessageBroker");
object _notifier;
if (!notifiers.TryGetValue(typeof(T), out _notifier))
{
var notifier = new List<Func<T, UniTask>>();
notifier.Add(asyncMessageReceiver);
notifiers.Add(typeof(T), notifier);
}
else
{
var notifier = (List<Func<T, UniTask>>)_notifier;
notifier.Add(asyncMessageReceiver);
notifiers[typeof(T)] = notifier;
}
}
return new Subscription<T>(this, asyncMessageReceiver);
}
public void Dispose()
{
lock (notifiers)
{
if (!isDisposed)
{
isDisposed = true;
notifiers.Clear();
}
}
}
class Subscription<T> : IDisposable
{
readonly TaskMessageBroker parent;
readonly Func<T, UniTask> asyncMessageReceiver;
public Subscription(TaskMessageBroker parent, Func<T, UniTask> asyncMessageReceiver)
{
this.parent = parent;
this.asyncMessageReceiver = asyncMessageReceiver;
}
public void Dispose()
{
lock (parent.notifiers)
{
object _notifier;
if (parent.notifiers.TryGetValue(typeof(T), out _notifier))
{
var notifier = (List<Func<T, UniTask>>)_notifier;
notifier.Remove(asyncMessageReceiver);
parent.notifiers[typeof(T)] = notifier;
}
}
}
}
}
}