88 lines
2.7 KiB
C#
88 lines
2.7 KiB
C#
namespace GPW.CORE.Services
|
|
{
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
|
|
// RouteModeService.cs
|
|
public class RouteModeService
|
|
{
|
|
private readonly ConcurrentDictionary<string, RouteMode> _map = new();
|
|
private readonly ConcurrentDictionary<Guid, Action> _subscribers = new();
|
|
|
|
public bool IsClientActive { get; private set; }
|
|
|
|
public void SetMode(string route, RouteMode mode)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(route)) return;
|
|
_map[Normalize(route)] = mode;
|
|
|
|
// Notifica tutti i subscriber in modo sincrono; i subscriber devono essere responsabili
|
|
// di eseguire InvokeAsync(StateHasChanged) se necessario.
|
|
foreach (var kv in _subscribers)
|
|
{
|
|
try
|
|
{
|
|
kv.Value?.Invoke();
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
//Console.WriteLine($"SetMode {route} => {mode} (Thread: {Environment.CurrentManagedThreadId})");
|
|
}
|
|
|
|
public RouteMode? GetModeFor(string route)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(route)) return null;
|
|
_map.TryGetValue(Normalize(route), out var mode);
|
|
return _map.ContainsKey(Normalize(route)) ? mode : (RouteMode?)null;
|
|
}
|
|
|
|
public IDisposable Subscribe(Action callback)
|
|
{
|
|
if (callback == null) throw new ArgumentNullException(nameof(callback));
|
|
var id = Guid.NewGuid();
|
|
_subscribers[id] = callback;
|
|
return new Unsubscriber(_subscribers, id);
|
|
}
|
|
public void NotifyClientActive()
|
|
{
|
|
IsClientActive = true;
|
|
foreach (var kv in _subscribers)
|
|
{
|
|
try
|
|
{
|
|
kv.Value?.Invoke();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine("[RouteModeService] subscriber error: " + ex.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private static string Normalize(string route)
|
|
=> route.Trim().TrimStart('/').ToLowerInvariant();
|
|
|
|
private sealed class Unsubscriber : IDisposable
|
|
{
|
|
private readonly ConcurrentDictionary<Guid, Action> _dict;
|
|
private readonly Guid _id;
|
|
private bool _disposed;
|
|
|
|
public Unsubscriber(ConcurrentDictionary<Guid, Action> dict, Guid id)
|
|
{
|
|
_dict = dict;
|
|
_id = id;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_disposed) return;
|
|
_dict.TryRemove(_id, out _);
|
|
_disposed = true;
|
|
}
|
|
}
|
|
}
|
|
}
|