import { isEqual } from 'lodash-es'; import { SaveCompression } from '@user/data-common'; import { ISpecial, SpecialCreation } from './types'; export interface ICommonSpecialConfig { /** 获取特殊属性的名称 */ name: string | ((special: ISpecial) => string); /** 获取特殊属性的描述 */ desc: string | ((special: ISpecial) => string); /** 获取特殊属性的名称显示颜色 */ color: string | ((special: ISpecial) => string); } export class CommonSerializableSpecial implements ISpecial { constructor( readonly code: number, public value: T, readonly config: ICommonSpecialConfig ) {} setValue(value: T): void { this.value = value; } getValue(): T { return this.value; } /** * 获取配置数据的值,是字面量则直接返回,是函数则返回其调用结果 * @param config 配置源数据 */ private getConfigValue( config: string | ((special: ISpecial) => string) ) { if (typeof config === 'string') { return config; } else { return config(this); } } getSpecialName(): string { return this.getConfigValue(this.config.name); } getDescription(): string { return this.getConfigValue(this.config.desc); } getNameColor(): string { return this.getConfigValue(this.config.color); } clone(): ISpecial { return new CommonSerializableSpecial( this.code, structuredClone(this.value), this.config ); } saveState(_compression: SaveCompression): T { return structuredClone(this.value); } loadState(state: T, _compression: SaveCompression): void { this.setValue(state); } deepEqualsTo(other: ISpecial): boolean { if (this.code !== other.code) return false; return isEqual(this.value, other.getValue()); } } export class NonePropertySpecial implements ISpecial { value: void = undefined; constructor( readonly code: number, readonly config: ICommonSpecialConfig ) {} setValue(_value: void): void { // unneeded } getValue(): void { return void 0; } /** * 获取配置数据的值,是字面量则直接返回,是函数则返回其调用结果 * @param config 配置源数据 */ private getConfigValue( config: string | ((special: ISpecial) => string) ) { if (typeof config === 'string') { return config; } else { return config(this); } } getSpecialName(): string { return this.getConfigValue(this.config.name); } getDescription(): string { return this.getConfigValue(this.config.desc); } getNameColor(): string { return this.getConfigValue(this.config.color); } clone(): ISpecial { return new NonePropertySpecial(this.code, this.config); } saveState(): void { return undefined; } loadState(): void { // 无属性,无需操作 } deepEqualsTo(other: ISpecial): boolean { return this.code === other.code; } } export function defineCommonSerializableSpecial( code: number, value: T, config: ICommonSpecialConfig ): SpecialCreation { return () => new CommonSerializableSpecial(code, structuredClone(value), config); } export function defineNonePropertySpecial( code: number, config: ICommonSpecialConfig ): SpecialCreation { return () => new NonePropertySpecial(code, config); }