using System.Collections.Generic;
using RR.Common.UI;
using UnityEngine;
namespace RR.Common.Settings
{
///
/// Диспетчер для связи кнопок настроек с объектами на сцене.
/// Позволяет объектам сцены подписываться на нажатия кнопок по ключу.
///
public static class SettingsButtonDispatcher
{
private static readonly Dictionary> bindings = new();
///
/// Регистрирует биндер для указанного ключа кнопки
///
public static void Register(string buttonKey, SettingsButtonBinder binder)
{
if (string.IsNullOrWhiteSpace(buttonKey) || binder == null) return;
if (!bindings.TryGetValue(buttonKey, out var list))
{
list = new List();
bindings[buttonKey] = list;
}
if (!list.Contains(binder))
{
list.Add(binder);
}
}
///
/// Удаляет биндер для указанного ключа кнопки
///
public static void Unregister(string buttonKey, SettingsButtonBinder binder)
{
if (string.IsNullOrWhiteSpace(buttonKey) || binder == null) return;
if (bindings.TryGetValue(buttonKey, out var list))
{
list.Remove(binder);
if (list.Count == 0)
{
bindings.Remove(buttonKey);
}
}
}
///
/// Вызывает все зарегистрированные биндеры для указанного ключа кнопки
///
/// True если хотя бы один биндер был вызван
public static bool Dispatch(string buttonKey)
{
if (string.IsNullOrWhiteSpace(buttonKey))
{
return false;
}
// Пробуем найти в зарегистрированных биндерах
if (bindings.TryGetValue(buttonKey, out var list) && list.Count > 0)
{
return InvokeBinders(list);
}
// Fallback: ищем ВСЕ биндеры в сцене (включая на неактивных объектах)
var allBinders = Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None);
var matchingBinders = new List();
foreach (var binder in allBinders)
{
// Проверяем что биндер имеет нужный ключ и компонент enabled
if (binder.enabled && binder.Key == buttonKey)
{
matchingBinders.Add(binder);
// Регистрируем для будущих вызовов
Register(buttonKey, binder);
}
}
if (matchingBinders.Count > 0)
{
return InvokeBinders(matchingBinders);
}
return false;
}
private static bool InvokeBinders(List binders)
{
bool anyInvoked = false;
// Копируем список чтобы избежать проблем при модификации во время итерации
var copy = new List(binders);
foreach (var binder in copy)
{
if (binder != null)
{
binder.Invoke();
anyInvoked = true;
}
}
return anyInvoked;
}
///
/// Очищает все регистрации (вызывать при смене сцены если нужно)
///
public static void Clear()
{
bindings.Clear();
}
}
}