Files
gpw_next/GPW.CORE/Services/RouteModeService.cs
2026-05-13 10:41:10 +02:00

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;
}
}
}
}