using System;
using System.Collections.Generic;
namespace Cthangover.Validator
{
///
/// Registry of all implementations, served
/// in deterministic execution order. It discovers nothing itself:
/// delivers the strategies of every
/// mod as the kernel registers its assembly and takes them back when the mod
/// unloads (game switch, hot reload), so a validation run never executes a
/// strategy of a dead assembly. Adding a new strategy (for example scenario
/// validation) is just shipping a new public class with a parameterless
/// constructor in any mod.
///
public static class ValidationStrategyRegistry
{
private static readonly object sync = new();
private static readonly List strategies = new();
/// Returns a snapshot of the registered strategies sorted by phase and order.
public static IReadOnlyList GetStrategies()
{
lock (sync)
return strategies.ToArray();
}
/// Adds a strategy and keeps the execution order.
public static void Register(IValidationStrategy strategy)
{
if (strategy == null)
return;
lock (sync)
{
strategies.Add(strategy);
strategies.Sort(Compare);
}
}
/// Removes exactly (its mod is being unloaded).
public static void Unregister(IValidationStrategy strategy)
{
lock (sync)
strategies.Remove(strategy);
}
private static int Compare(IValidationStrategy a, IValidationStrategy b)
{
var phase = a.Phase.CompareTo(b.Phase);
if (phase != 0)
return phase;
var order = a.Order.CompareTo(b.Order);
if (order != 0)
return order;
return string.Compare(a.Id, b.Id, StringComparison.OrdinalIgnoreCase);
}
}
}