namespace Theriapolis.Core.Persistence.SaveMigrations; /// /// Registry + chain runner for SaveBody migrations. Phase 4 is the v4 baseline; /// older versions are not supported because nothing earlier shipped. As we /// bump the schema in Phase 5+, register migrations here. /// /// The registry seeds itself with every built-in migration on first use, so /// callers don't need to remember to them at startup. /// public static class Migrations { private static readonly List _registry = new(); private static bool _seeded; public static void Register(ISaveMigration m) { EnsureSeeded(); _registry.Add(m); } private static void EnsureSeeded() { if (_seeded) return; _seeded = true; // Built-in migrations registered in version order: _registry.Add(new V5ToV6Migration()); _registry.Add(new V6ToV7Migration()); _registry.Add(new V7ToV8Migration()); } /// /// Walk migrations from header.Version up to C.SAVE_SCHEMA_VERSION. Returns /// false if no chain exists; the caller decides whether to hard-block or /// best-effort the load (see SaveCodec docs). /// public static bool MigrateUp(SaveHeader header, SaveBody body) { EnsureSeeded(); while (header.Version < C.SAVE_SCHEMA_VERSION) { var step = _registry.FirstOrDefault(m => m.FromVersion == header.Version); if (step is null) return false; step.Apply(header, body); header.Version = step.ToVersion; } return header.Version == C.SAVE_SCHEMA_VERSION; } }