b451f83174
Captures the pre-Godot-port state of the codebase. This is the rollback anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md). All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
50 lines
1.7 KiB
C#
50 lines
1.7 KiB
C#
namespace Theriapolis.Core.Persistence.SaveMigrations;
|
|
|
|
/// <summary>
|
|
/// 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 <see cref="Register"/> them at startup.
|
|
/// </summary>
|
|
public static class Migrations
|
|
{
|
|
private static readonly List<ISaveMigration> _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());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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).
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|