ProSol.Html.TagsProvider/src/Messaging/Broadcaster.cs
Alexander Kozachenko fc19e6e4e1 Release v1.0.2
- moved folders around
- provided readme
2023-11-07 16:51:25 +03:00

66 lines
1.8 KiB
C#

using ProSol.Html.Contracts.Data;
namespace ProSol.Html.Messaging;
internal class Broadcaster
{
readonly HashSet<TagObserver> observers = [];
internal void OnNext(TagsProviderMessage message, string tagName)
{
var candidates = observers.Where(x => x.TagName == tagName || x.TagName == null);
foreach (var observer in candidates)
{
observer.Observer.OnNext(message);
}
}
internal void OnCompleted()
{
foreach (var observer in observers)
{
observer.Observer.OnCompleted();
}
}
internal IDisposable Subscribe(IObserver<TagsProviderMessage> observer)
{
var tagObserver = new TagObserver(observer, null);
observers.Add(tagObserver);
return new Unsubscriber<TagsProviderMessage>(observers, [tagObserver]);
}
internal IDisposable Subscribe(IObserver<TagsProviderMessage> observer, params string[] tagNames)
{
if (tagNames == null)
{
return Subscribe(observer);
}
var tagObservers = new List<TagObserver>();
foreach (var tagName in tagNames)
{
var tagObserver = new TagObserver(observer, tagName);
observers.Add(tagObserver);
tagObservers.Add(tagObserver);
}
return new Unsubscriber<TagsProviderMessage>(observers, tagObservers);
}
private sealed class Unsubscriber<T>(
ICollection<TagObserver> observers,
List<TagObserver> targets)
: IDisposable
{
private readonly ICollection<TagObserver> observers = observers;
private readonly List<TagObserver> targets = targets;
public void Dispose()
{
foreach (var target in targets)
{
observers.Remove(target);
}
}
}
}