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(); } }