using GFramework.Core.Abstractions.versioning;
using GFramework.Core.extensions;
using GFramework.Core.model;
using GFramework.Game.Abstractions.setting;
namespace GFramework.Game.setting;
///
/// 设置模型类,用于管理不同类型的应用程序设置部分
///
public class SettingsModel : AbstractModel, ISettingsModel
{
private readonly Dictionary _applicators = new();
private readonly Dictionary _dataSettings = new();
private readonly Dictionary<(Type type, int from), ISettingsMigration> _migrations = new();
private ISettingsPersistence? _persistence;
// -----------------------------
// Data
// -----------------------------
///
/// 获取指定类型的设置数据实例,如果不存在则创建新的实例
///
/// 设置数据类型,必须实现ISettingsData接口并提供无参构造函数
/// 指定类型的设置数据实例
public T GetData() where T : class, ISettingsData, new()
{
var type = typeof(T);
if (_dataSettings.TryGetValue(type, out var data))
return (T)data;
var created = new T();
_dataSettings[type] = created;
return created;
}
///
/// 获取所有设置数据的枚举集合
///
/// 所有设置数据的枚举集合
public IEnumerable AllData()
=> _dataSettings.Values;
// -----------------------------
// Applicator
// -----------------------------
///
/// 获取所有设置应用器的枚举集合
///
/// 所有设置应用器的枚举集合
public IEnumerable AllApplicators()
=> _applicators.Values;
///
/// 注册设置应用器到模型中
///
/// 设置应用器类型,必须实现IApplyAbleSettings接口
/// 要注册的设置应用器实例
/// 当前设置模型实例,支持链式调用
public ISettingsModel RegisterApplicator(T applicator)
where T : class, IApplyAbleSettings
{
_applicators[typeof(T)] = applicator;
return this;
}
///
/// 获取指定类型的设置应用器实例
///
/// 设置应用器类型,必须实现IApplyAbleSettings接口
/// 指定类型的设置应用器实例,如果不存在则返回null
public T? GetApplicator() where T : class, IApplyAbleSettings
{
return _applicators.TryGetValue(typeof(T), out var app)
? (T)app
: null;
}
// -----------------------------
// Section lookup
// -----------------------------
///
/// 尝试获取指定类型的设置节
///
/// 要查找的设置类型
/// 输出参数,找到的设置节实例
/// 如果找到对应类型的设置节则返回true,否则返回false
public bool TryGet(Type type, out ISettingsSection section)
{
if (_dataSettings.TryGetValue(type, out var data))
{
section = data;
return true;
}
if (_applicators.TryGetValue(type, out var applicator))
{
section = applicator;
return true;
}
section = null!;
return false;
}
// -----------------------------
// Migration
// -----------------------------
///
/// 注册设置迁移器到模型中
///
/// 要注册的设置迁移器实例
/// 当前设置模型实例,支持链式调用
public ISettingsModel RegisterMigration(ISettingsMigration migration)
{
_migrations[(migration.SettingsType, migration.FromVersion)] = migration;
return this;
}
///
/// 如果需要的话,对设置节进行版本迁移
///
/// 待检查和迁移的设置节
/// 迁移后的设置节
private ISettingsSection MigrateIfNeeded(ISettingsSection section)
{
if (section is not IVersioned versioned)
return section;
var type = section.GetType();
var current = section;
while (_migrations.TryGetValue((type, versioned.Version), out var migration))
{
current = migration.Migrate(current);
versioned = (IVersioned)current;
}
return current;
}
// -----------------------------
// Load / Init
// -----------------------------
///
/// 异步初始化设置模型,加载指定类型的设置数据
///
/// 要初始化的设置类型数组
public async Task InitializeAsync(params Type[] settingTypes)
{
foreach (var type in settingTypes)
{
if (!typeof(ISettingsData).IsAssignableFrom(type) ||
!type.IsClass ||
type.GetConstructor(Type.EmptyTypes) == null)
continue;
// Load()
var method = typeof(ISettingsPersistence)
.GetMethod(nameof(ISettingsPersistence.LoadAsync))!
.MakeGenericMethod(type);
var task = (Task)method.Invoke(_persistence, null)!;
await task;
var loaded = (ISettingsSection)((dynamic)task).Result;
// ★ 关键:迁移
var migrated = MigrateIfNeeded(loaded);
_dataSettings[type] = (ISettingsData)migrated;
}
}
///
/// 初始化方法,用于获取设置持久化服务
///
protected override void OnInit()
{
_persistence = this.GetUtility();
}
}