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