Files
FlowScope/Packages/com.flowscope.gamecore/Runtime/Save/SaveMigrationRegistry.cs
2026-06-04 14:54:49 +08:00

75 lines
2.1 KiB
C#

using System;
using System.Collections.Generic;
namespace FlowScope.Save
{
public sealed class SaveMigrationRegistry
{
private readonly Dictionary<MigrationKey, ISaveMigration> _migrations = new();
public void Register(ISaveMigration migration)
{
if (migration == null)
{
throw new ArgumentNullException(nameof(migration));
}
_migrations[new MigrationKey(migration.Key, migration.FromVersion)] = migration;
}
public string Migrate(
string key,
int fromVersion,
int currentVersion,
string json)
{
var current = fromVersion;
var payload = json;
while (current < currentVersion)
{
if (!_migrations.TryGetValue(new MigrationKey(key, current), out var migration) ||
migration.ToVersion != current + 1)
{
throw new InvalidOperationException(
$"Missing save migration for key '{key}' from version {current}.");
}
payload = migration.Migrate(payload);
current = migration.ToVersion;
}
return payload;
}
private readonly struct MigrationKey : IEquatable<MigrationKey>
{
private readonly string _key;
private readonly int _fromVersion;
public MigrationKey(string key, int fromVersion)
{
_key = key ?? string.Empty;
_fromVersion = fromVersion;
}
public bool Equals(MigrationKey other)
{
return _key == other._key && _fromVersion == other._fromVersion;
}
public override bool Equals(object obj)
{
return obj is MigrationKey other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
return ((_key != null ? _key.GetHashCode() : 0) * 397) ^ _fromVersion;
}
}
}
}
}