mirror of
https://github.com/motajs/template.git
synced 2026-05-02 20:31:11 +08:00
5.2 KiB
5.2 KiB
需求综述
当前勇士属性修饰器 IHeroModifier 是非注册式的,无法直接存档。
目标是将其改为注册式,每种修饰器在使用前需先在属性对象上注册,
并实现 ISaveableContent 接口以支持存档读档。
注册接口签名:registerModifier(identifier: string, cons: () => IHeroModifier): void
实现思路
1. 修改 IHeroModifier 接口
- 将
identifier改为type:一类修饰器可能被添加多次,type比identifier更准确地表达"修饰器类型"的含义。 - 新增泛型参数
S = unknown作为存档类型,让接口继承ISaveableContent<S>:IHeroModifier<T, V, S = unknown> - 大多数修饰器的可变状态只有
value,因此BaseHeroModifier将S默认为V。 若修饰器需要特殊存储结构,可以不继承BaseHeroModifier,自行编写实现类。
2. 新增 IModifierStateSave 类型
IModifierStateSave 记录单条修饰器的存档信息:
interface IModifierStateSave {
readonly name: PropertyKey; // 属性名,如 'atk'
readonly type: string; // 修饰器类型(与注册时的 key 对应)
readonly state: unknown; // 修饰器 saveState 结果
}
3. 修改 IHeroStateSave,新增 modifiers 字段
attribute 字段维持原来的 THero 只保存基础属性值,
修饰器列表单独作为顶层字段:
readonly modifiers: readonly IModifierStateSave[];
4. 修改 IHeroAttribute,新增 iterateModifiers 方法
HeroAttribute 不再继承 ISaveableContent,也不负责存读档,
保留现有的 toStructured(): THero。
新增 iterateModifiers 方法,供 HeroState 在存档时遍历所有已挂载的修饰器:
iterateModifiers(): Iterable<[keyof THero, IHeroModifier]>;
5. 修改 BaseHeroModifier,新增 S 泛型并实现 ISaveableContent<V>
- 改为
BaseHeroModifier<T, V>隐式以S = V实现ISaveableContent<V> - 将
abstract readonly identifier: string改为abstract readonly type: string saveState()直接返回this.currentValueloadState(state)调用this.setValue(state)恢复值
6. 修改 HeroState
修饰器注册表移至 HeroState:
- 新增
private readonly registry: Map<string, () => IHeroModifier>存储工厂函数 - 实现
registerModifier(type, cons):向registry写入工厂, 并同步注册到接口签名中 - 实现
createModifier<V>(type):从registry取出对应工厂, 调用工厂函数创建并返回修饰器实例,类型为IHeroModifier<unknown, V> - 实现
createAndInsertModifier<K, V>(type, name): 调用createModifier创建实例后,自动调用this.attribute.addModifier(name, modifier)插入属性对象, 返回该修饰器实例,类型与createModifier一致 - 修改
saveState():attribute字段调用this.attribute.toStructured()获取基础属性值(与现在一致)- 遍历
this.attribute.iterateModifiers(),对每个修饰器调用modifier.saveState(compression)并拼装IModifierStateSave[], 写入modifiers字段
- 修改
loadState():- 创建新的
HeroAttribute实例(使用state.attribute还原基础属性值,与现在一致) - 遍历
state.modifiers,通过registry.get(type)创建修饰器实例, 调用modifier.loadState(state)恢复值,再addModifier(name, modifier)挂载
- 创建新的
涉及文件
需要修改的文件
@user/data-base/hero/types.ts
- 修改
IHeroModifier<T, V>接口: 改为IHeroModifier<T, V, S = unknown>,identifier改名为type, 继承ISaveableContent<S> - 新增
IModifierStateSave接口:单条修饰器的存档格式 - 修改
IHeroStateSave<THero>:新增readonly modifiers: readonly IModifierStateSave[]字段 - 修改
IReadonlyHeroAttribute<THero>:新增iterateModifiers()方法签名 - 修改
IHeroState<THero>:新增以下方法签名 -registerModifier(type: string, cons: () => IHeroModifier): void-createModifier<V>(type: string): IHeroModifier<unknown, V>-createAndInsertModifier<K extends keyof THero, V>(type: string, name: K): IHeroModifier<unknown, V>
@user/data-base/hero/attribute.ts
- 修改
BaseHeroModifier<T, V>: 将abstract readonly identifier改为abstract readonly type; 实现saveState/loadState - 修改
HeroAttribute<THero>:实现iterateModifiers()
@user/data-base/hero/state.ts
- 修改
HeroState<THero>:新增private readonly registry: Map<string, () => IHeroModifier>成员 - 实现
HeroState.registerModifier:将工厂函数写入registry - 实现
HeroState.createModifier:从registry取出工厂并调用,返回新实例; 若type未注册则抛出错误 - 实现
HeroState.createAndInsertModifier:调用createModifier后, 再调用this.attribute.addModifier(name, modifier),返回同一实例 - 修改
HeroState.saveState:遍历iterateModifiers()写入modifiers字段 - 修改
HeroState.loadState:遍历state.modifiers重建修饰器并挂载