import { IAnyObject } from "./Renderer"; import { Emitter, EventType } from "./Emitter"; import type { Individual } from "./Individual"; import type { Group } from "./Group"; import type { Model } from "./Model"; import type { Range } from "./Range"; import type { Label } from "./Label"; /** * 参数类型 */ type IMapBasicParamTypeKeyToType = { "number": number; "string": string; "boolean": boolean; } type IMapObjectParamTypeKeyToType = { "R"?: Range; "G"?: Group; "GR"?: Group | Range; "LR"?: Label | Range; "LG"?: Label | Group; "LGR"?: Label | Group | Range; } type IMapVectorParamTypeKeyToType = { "vec": number[]; } /** * 参数类型映射 */ type AllMapType = IMapBasicParamTypeKeyToType & IMapObjectParamTypeKeyToType & IMapVectorParamTypeKeyToType; type IParamType = keyof AllMapType; type IObjectType = keyof IMapObjectParamTypeKeyToType; type IVectorType = keyof IMapVectorParamTypeKeyToType; type IParamValue = AllMapType[K]; /** * 特殊对象类型判定 */ const objectTypeListEnumSet = new Set(["R", "G", "GR", "LR", "LG", "LGR"]); /** * 对象断言表达式 */ function isObjectType(key: IParamType): key is IVectorType { return objectTypeListEnumSet.has(key); } /** * 向量断言表达式 */ function isVectorType(key: IParamType): key is IObjectType { return key === "vec"; } /** * 模型参数类型 */ interface IBehaviorParameterOptionItem { /** * 参数类型 */ type: T | string; /** * 参数默认值 */ defaultValue?: IParamValue; /** * 数值变化回调 */ onChange?: (value: IParamValue) => any; /** * 名字 */ name: string; /** * 字符长度 */ stringLength?: number; /** * 数字步长 */ numberStep?: number; /** * 最大值最小值 */ numberMax?: number; numberMin?: number; /** * 图标名字 */ iconName?: string; } interface IBehaviorParameter { [x: string]: IParamType; } /** * 参数类型列表 */ type IBehaviorParameterOption

= { [X in keyof P]: IBehaviorParameterOptionItem; } /** * 参数类型列表映射到参数对象 */ type IBehaviorParameterValue

= { [X in keyof P]: IParamValue } /** * 行为构造函数类型 */ type IBehaviorConstructor< P extends IBehaviorParameter = {}, E extends Record = {} > = new (id: string, parameter: IBehaviorParameterValue

) => Behavior; type IAnyBehavior = Behavior; type IAnyBehaviorRecorder = BehaviorRecorder; type Language = "ZH_CN" | "EN_US"; /** * 行为的基础信息 */ class BehaviorInfo = {}> extends Emitter { /** * 图标名字 */ public iconName: string = "" /** * 行为 ID */ public behaviorId: string = ""; /** * 行为名称 */ public behaviorName: string = ""; /** * 行为描述 */ public describe: string = ""; /** * 类别 */ public category: string = ""; /** * 提条列表 */ public terms: Record> = {}; /** * 获取词条翻译 */ public getTerms(key: string, language?: Language | string): string { if (key[0] === "$" && this.terms[key]) { let res: string = ""; if (language) { res = this.terms[key][language]; } else { res = this.terms[key]["EN_US"]; } if (res) { return res; } } return key; } } class BehaviorRecorder< P extends IBehaviorParameter = {}, E extends Record = {} > extends BehaviorInfo<{}> { /** * 命名序号 */ public nameIndex: number = 0; /** * 获取下一个 ID */ public getNextId() { return `B-${this.behaviorId}-${this.nameIndex ++}`; } /** * 行为类型 */ public behavior: IBehaviorConstructor; /** * 行为实例 */ public behaviorInstance: Behavior; /** * 对象参数列表 */ public parameterOption: IBehaviorParameterOption

; /** * 获取参数列表的默认值 */ public getDefaultValue(): IBehaviorParameterValue

{ let defaultObj = {} as IBehaviorParameterValue

; for (let key in this.parameterOption) { let defaultVal = this.parameterOption[key].defaultValue; defaultObj[key] = defaultVal as any; if (defaultObj[key] === undefined) { switch (this.parameterOption[key].type) { case "string": defaultObj[key] = "" as any; break; case "number": defaultObj[key] = 0 as any; break; case "boolean": defaultObj[key] = false as any; break; case "vec": defaultObj[key] = [0, 0, 0] as any; break; } } } return defaultObj; } /** * 创建一个新的行为实例 */ public new(): Behavior { return new this.behavior(this.getNextId(), this.getDefaultValue()); } public constructor(behavior: IBehaviorConstructor) { super(); this.behavior = behavior; this.behaviorInstance = new this.behavior(this.getNextId(), {} as any); this.parameterOption = this.behaviorInstance.parameterOption; this.iconName = this.behaviorInstance.iconName; this.behaviorId = this.behaviorInstance.behaviorId; this.behaviorName = this.behaviorInstance.behaviorName; this.describe = this.behaviorInstance.describe; this.category = this.behaviorInstance.category; this.terms = this.behaviorInstance.terms; } } /** * 群体的某种行为 */ class Behavior< P extends IBehaviorParameter = {}, E extends Record = {} > extends BehaviorInfo { /** * 用户自定义名字 */ public name: string = ""; /** * 实例 ID */ public id: string = ""; /** * 颜色 */ public color: string = ""; /** * 优先级 * 值越大执行顺序越靠后 */ public priority: number = 0; /** * 行为参数 */ public parameter: IBehaviorParameterValue

; /** * 对象参数列表 */ public parameterOption: IBehaviorParameterOption

= {} as any; public constructor(id: string, parameter: IBehaviorParameterValue

) { super(); this.id = id; this.parameter = parameter; } /** * 相等校验 */ public equal(behavior: Behavior): boolean { return this === behavior || this.id === behavior.id; }; /** * 删除标记 */ private deleteFlag: boolean = false; /** * 标记对象被删除 */ public markDelete() { this.deleteFlag = true; }; /** * 是否被删除 */ public isDeleted(): boolean { return this.deleteFlag; } /** * 加载时调用 */ public load(model: Model): void {} /** * 卸载时调用 */ public unload(model: Model): void {} /** * 挂载时调用 */ public mount(group: Group, model: Model): void {} /** * 挂载时调用 */ public unmount(group: Group, model: Model): void {} /** * 全部影响作用前 * @param individual 影响个体 * @param group 影响组 * @param model 模型 * @param t 经过时间 */ public effect(individual: Individual, group: Group, model: Model, t: number): void {}; /** * 作用影响于个体 * @param individual 影响个体 * @param group 影响组 * @param model 模型 * @param t 经过时间 */ public afterEffect(individual: Individual, group: Group, model: Model, t: number): void {}; /** * 全部影响作用后 * @param individual 影响个体 * @param group 影响组 * @param model 模型 * @param t 经过时间 */ public finalEffect(individual: Individual, group: Group, model: Model, t: number): void {}; } type IRenderBehavior = BehaviorInfo | Behavior; export { Behavior, BehaviorRecorder, IBehaviorParameterOption, IBehaviorParameterOptionItem, IAnyBehavior, IAnyBehaviorRecorder, BehaviorInfo, IRenderBehavior }; export default { Behavior };