using System; using System.Collections.Generic; namespace S3.Core; /// /// Holds every registered module and enables the ones flagged on at load. /// One failing module must never take down the rest, so each enable is guarded. /// public sealed class ModuleRegistry { private readonly List _modules = new(); private readonly HashSet _active = new(); public IReadOnlyList Modules => _modules; public void Register(IModule module) => _modules.Add(module); /// Call on every module currently enabled. public void EnableConfigured() { foreach (IModule m in _modules) { if (!m.Enabled) { Log.Info($"[{m.Id}] disabled — skipping."); continue; } try { m.OnEnable(); _active.Add(m); Log.Info($"[{m.Id}] enabled."); } catch (Exception e) { Log.Error($"[{m.Id}] failed to enable: {e}"); } } } public bool IsActive(IModule module) => _active.Contains(module); public bool IsActive(string id) { IModule? module = Find(id); return module != null && _active.Contains(module); } public IModule? Find(string id) { foreach (IModule module in _modules) if (string.Equals(module.Id, id, StringComparison.OrdinalIgnoreCase)) return module; return null; } /// /// Changes a module's live state without changing its persisted Enabled setting. /// Callers that want the change persisted must update Enabled and SaveSettings. /// public bool TrySetActive(string id, bool active, out string message) { IModule? module = Find(id); if (module == null) { message = "unknown module: " + id; return false; } bool current = _active.Contains(module); if (current == active) { message = $"{module.Id} active={active} (unchanged)"; return true; } try { if (active) { module.OnEnable(); _active.Add(module); } else { module.OnDisable(); _active.Remove(module); } message = $"{module.Id} active={active}"; Log.Info($"[{module.Id}] live active={active}."); return true; } catch (Exception e) { message = $"{module.Id} active={current}; transition failed: {e.Message}"; Log.Error($"[{module.Id}] live transition to active={active} failed: {e}"); return false; } } /// Persist every module's settings (called from UMM's OnSaveGUI). public void SaveAll() { foreach (IModule m in _modules) { try { m.SaveSettings(); } catch (Exception e) { Log.Error($"[{m.Id}] failed to save settings: {e}"); } } } }