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