forked from 77media/video-flow
165 lines
3.6 KiB
TypeScript
165 lines
3.6 KiB
TypeScript
/**不同类型 将有不同元数据 */
|
||
|
||
export enum ScriptSliceType {
|
||
/** 文本 */
|
||
text = "text",
|
||
/**角色 */
|
||
role = "role",
|
||
/** 场景 */
|
||
scene = "scene",
|
||
}
|
||
|
||
/**
|
||
* 剧本片段值对象
|
||
* @description 代表剧本中的一个片段,按值相等判断,不可变
|
||
*/
|
||
export class ScriptSlice {
|
||
/**唯一标识符 - 仅作为局部唯一性标识,不作为全局Entity id */
|
||
readonly id: string;
|
||
/** 类型 */
|
||
readonly type: ScriptSliceType;
|
||
/** 剧本内容 */
|
||
readonly text: string;
|
||
/** 元数据 */
|
||
metaData: any;
|
||
|
||
constructor(
|
||
id: string,
|
||
type: ScriptSliceType,
|
||
text: string,
|
||
metaData: any = {}
|
||
) {
|
||
this.id = id;
|
||
this.type = type;
|
||
this.text = text;
|
||
this.metaData = metaData;
|
||
}
|
||
|
||
/**
|
||
* 值对象相等性比较
|
||
* @param other 另一个ScriptSlice实例
|
||
* @returns 是否相等
|
||
*/
|
||
equals(other: ScriptSlice): boolean {
|
||
return (
|
||
this.type === other.type &&
|
||
this.text === other.text &&
|
||
JSON.stringify(this.metaData) === JSON.stringify(other.metaData)
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 对话内容项值对象
|
||
* @description 代表对话中的一个内容项,按值相等判断,不可变
|
||
*/
|
||
export class ContentItem {
|
||
/** 角色ID */
|
||
readonly roleId: string;
|
||
/** 对话内容 */
|
||
readonly content: string;
|
||
|
||
constructor(roleId: string, content: string) {
|
||
this.roleId = roleId;
|
||
this.content = content;
|
||
}
|
||
|
||
/**
|
||
* 值对象相等性比较
|
||
* @param other 另一个ContentItem实例
|
||
* @returns 是否相等
|
||
*/
|
||
equals(other: ContentItem): boolean {
|
||
return this.roleId === other.roleId && this.content === other.content;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 镜头值对象
|
||
* @description 代表镜头信息,按值相等判断,不可变
|
||
*/
|
||
export class LensType {
|
||
/** 镜头名称 */
|
||
readonly name: string;
|
||
/** 镜头描述 */
|
||
readonly content: string;
|
||
/**运镜描述 */
|
||
readonly movement: string;
|
||
|
||
constructor(name: string, content: string, movement: string) {
|
||
this.name = name;
|
||
this.content = content;
|
||
this.movement = movement;
|
||
}
|
||
|
||
/**
|
||
* 值对象相等性比较
|
||
* @param other 另一个LensType实例
|
||
* @returns 是否相等
|
||
*/
|
||
equals(other: LensType): boolean {
|
||
return (
|
||
this.name === other.name &&
|
||
this.content === other.content &&
|
||
this.movement === other.movement
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 剧本聚合根
|
||
* @description 作为聚合根,封装ScriptSlice的管理与行为
|
||
*/
|
||
export class ScriptValueObject {
|
||
/** 剧本片段数组 - 值对象数组 */
|
||
private readonly _scriptSlices: ScriptSlice[] = [];
|
||
|
||
/**
|
||
* 获取剧本片段数组的只读副本
|
||
*/
|
||
get scriptSlices(): readonly ScriptSlice[] {
|
||
return [...this._scriptSlices];
|
||
}
|
||
|
||
/**
|
||
* @description: 构造函数,初始化剧本
|
||
* @param scriptText 剧本文本字符串
|
||
*/
|
||
constructor(scriptText?: string) {
|
||
if (scriptText) {
|
||
this.parseFromString(scriptText);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @description: 从字符串解析剧本片段
|
||
* @param scriptText 剧本文本字符串
|
||
*/
|
||
parseFromString(scriptText: string): void {
|
||
console.log('scriptText', scriptText)
|
||
}
|
||
/**
|
||
* @description: 将剧本片段转换为字符串
|
||
* @returns string
|
||
*/
|
||
toString(): string {
|
||
return this._scriptSlices.map((slice) => slice.text).join("");
|
||
}
|
||
|
||
|
||
/**
|
||
* 聚合根相等性比较
|
||
* @param other 另一个ScriptValueObject实例
|
||
* @returns 是否相等
|
||
*/
|
||
equals(other: ScriptValueObject): boolean {
|
||
if (this._scriptSlices.length !== other._scriptSlices.length) {
|
||
return false;
|
||
}
|
||
|
||
return this._scriptSlices.every((slice, index) =>
|
||
slice.equals(other._scriptSlices[index])
|
||
);
|
||
}
|
||
}
|