Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 40 additions & 19 deletions packages/webgal/src/Core/Modules/perform/performController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ISentence } from '@/Core/controller/scene/sceneInterface';
import { continueSentence } from '@/Core/controller/gamePlay/nextSentence';
import { WEBGAL_NONE } from '@/Core/constants';
import { getBooleanArgByKey } from '@/Core/util/getSentenceArg';
import type { IStageCommitOptions } from '@/Core/Modules/stage/stageStateManager';
import { stageStateManager } from '@/Core/Modules/stage/stageStateManager';

/**
Expand All @@ -15,14 +16,15 @@ export const getRandomPerformName = (): string => {
interface IPendingPerform {
perform: IPerform;
script: ISentence;
syncPerformState: boolean;
commitOptions: IStageCommitOptions;
}

export class PerformController {
public performList: Array<IPerform> = [];
private pendingPerformList: Array<IPendingPerform> = [];
private isCollectingPerforms = false;
private stopTimeoutMap = new WeakMap<IPerform, ReturnType<typeof setTimeout>>();
private performCommitOptions = new WeakMap<IPerform, IStageCommitOptions>();

/**
* 判断 perform 名称是否匹配(支持前缀匹配,用于清理并行演出)
Expand All @@ -40,7 +42,12 @@ export class PerformController {
this.isCollectingPerforms = false;
}

public arrangeNewPerform(perform: IPerform, script: ISentence, syncPerformState = true) {
public arrangeNewPerform(
perform: IPerform,
script: ISentence,
syncPerformState = true,
commitOptions: IStageCommitOptions = {},
) {
// 检查演出列表内是否有相同的演出,如果有,一定是出了什么问题
// 并行演出的 performName 带有唯一后缀,因此不会命中去重
const dupPerformIndex = this.performList.findIndex((p) => p.performName === perform.performName);
Expand All @@ -51,6 +58,7 @@ export class PerformController {
if (e.performName === perform.performName) {
this.stopStartedPerform(e);
this.clearPerformTimeout(e);
this.performCommitOptions.delete(e);
this.performList.splice(i, 1);
i--;
}
Expand All @@ -71,16 +79,16 @@ export class PerformController {
stageStateManager.addPerform(performToAdd);
} else {
stageStateManager.addPerform(performToAdd);
stageStateManager.commit({ applyPixiEffects: false });
stageStateManager.commit({ ...commitOptions, applyPixiEffects: false });
}
}

if (this.isCollectingPerforms) {
this.pendingPerformList.push({ perform, script, syncPerformState });
this.pendingPerformList.push({ perform, script, commitOptions });
return;
}

this.startPerform(perform, script);
this.startPerform(perform, script, commitOptions);
if (!this.isCollectingPerforms) {
stageStateManager.applyCommittedPixiEffects();
}
Expand All @@ -89,8 +97,8 @@ export class PerformController {
public commitPendingPerforms() {
const performsToStart = this.pendingPerformList;
this.pendingPerformList = [];
performsToStart.forEach(({ perform, script }) => {
this.startPerform(perform, script);
performsToStart.forEach(({ perform, script, commitOptions }) => {
this.startPerform(perform, script, commitOptions);
});
}

Expand Down Expand Up @@ -140,7 +148,7 @@ export class PerformController {
*
* @param goNextWhenOver 是否消费被结算演出的 goNextWhenOver 标记。
*/
public settleNonHoldPerforms(goNextWhenOver = true) {
public settleNonHoldPerforms(goNextWhenOver = true, commitOptions: IStageCommitOptions = {}) {
let isGoNext = false;
for (let i = 0; i < this.performList.length; i++) {
const e = this.performList[i];
Expand All @@ -151,15 +159,16 @@ export class PerformController {
if (!e.skipNextCollect) {
this.stopStartedPerform(e);
this.clearPerformTimeout(e);
this.performCommitOptions.delete(e);
this.performList.splice(i, 1);
i--;
this.erasePerformFromState(e.performName);
}
}
}
stageStateManager.commit();
stageStateManager.commit(commitOptions);
if (isGoNext && goNextWhenOver) {
continueSentence();
continueSentence(commitOptions);
}
}

Expand All @@ -173,8 +182,9 @@ export class PerformController {
* startFunction 只会在 commitPendingPerforms 之后运行,因此可以依赖已提交的 stage state。
* 这里同时把脚本层的 -continue 转成 perform.goNextWhenOver。
*/
private startPerform(perform: IPerform, script: ISentence) {
private startPerform(perform: IPerform, script: ISentence, commitOptions: IStageCommitOptions = {}) {
perform.isStarted = true;
this.performCommitOptions.set(perform, commitOptions);
perform.startFunction?.();

// 时间到后自动清理演出
Expand Down Expand Up @@ -212,6 +222,7 @@ export class PerformController {
if (!e.isHoldOn && this.matchPerformName(e.performName, name)) {
this.stopStartedPerform(e);
this.clearPerformTimeout(e);
const commitOptions = this.takeCommitOptions(e);
/**
* 在演出列表里删除演出对象的操作必须在调用 goNextWhenOver 之前
* 因为 goNextWhenOver 会触发继续推进,而继续推进会清除目前未结束的演出
Expand All @@ -222,7 +233,7 @@ export class PerformController {
this.performList.splice(i, 1);
i--;
if (e.goNextWhenOver) {
this.goNextWhenOver();
this.goNextWhenOver(commitOptions);
}
this.erasePerformFromState(name);
}
Expand All @@ -233,13 +244,14 @@ export class PerformController {
if (this.matchPerformName(e.performName, name)) {
this.stopStartedPerform(e);
this.clearPerformTimeout(e);
const commitOptions = this.takeCommitOptions(e);
/**
* 在演出列表里删除演出对象的操作必须在调用 goNextWhenOver 之前(同上)
*/
this.performList.splice(i, 1);
i--;
if (e.goNextWhenOver) {
this.goNextWhenOver();
this.goNextWhenOver(commitOptions);
}
/**
* 从状态表里清除演出
Expand Down Expand Up @@ -268,10 +280,11 @@ export class PerformController {
if (e.performName.startsWith(prefix) && (force || !e.isHoldOn)) {
this.stopStartedPerform(e);
this.clearPerformTimeout(e);
const commitOptions = this.takeCommitOptions(e);
this.performList.splice(i, 1);
i--;
if (e.goNextWhenOver) {
this.goNextWhenOver();
this.goNextWhenOver(commitOptions);
}
this.erasePerformFromState(e.performName);
}
Expand All @@ -291,10 +304,11 @@ export class PerformController {
* 此问题对所有 goNextWhenOver 属性为真的演出都有影响,但只有 2 个演出有此问题
*/
this.performList.splice(idx, 1);
const commitOptions = this.takeCommitOptions(perform);
this.erasePerformFromState(perform.performName);
stageStateManager.commit();
stageStateManager.commit(commitOptions);
if (perform.goNextWhenOver) {
this.goNextWhenOver();
this.goNextWhenOver(commitOptions);
}
}

Expand All @@ -307,6 +321,7 @@ export class PerformController {
for (const e of this.performList) {
this.clearPerformTimeout(e);
this.stopStartedPerform(e);
this.performCommitOptions.delete(e);
}
this.performList = [];
}
Expand All @@ -325,13 +340,19 @@ export class PerformController {
perform.isStarted = false;
}

private takeCommitOptions(perform: IPerform): IStageCommitOptions {
const commitOptions = this.performCommitOptions.get(perform) ?? {};
this.performCommitOptions.delete(perform);
return commitOptions;
}

/**
* perform 结束后的内部继续推进。
*
* goNextWhenOver 不等于无条件跳下一句;它仍然必须等待所有 blockingNext 演出结束。
* 等待完成后使用 continueSentence,避免触发 userInteractNext,也避免把自然结束误当成用户点击。
*/
private goNextWhenOver = () => {
private goNextWhenOver = (commitOptions: IStageCommitOptions = {}) => {
let isBlockingNext = false;
this.performList?.forEach((e) => {
if (e.blockingNext())
Expand All @@ -340,9 +361,9 @@ export class PerformController {
});
if (isBlockingNext) {
// 有阻塞,提前结束
setTimeout(this.goNextWhenOver, 100);
setTimeout(() => this.goNextWhenOver(commitOptions), 100);
} else {
continueSentence();
continueSentence(commitOptions);
}
};
}
5 changes: 3 additions & 2 deletions packages/webgal/src/Core/Modules/readHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import { webgalStore } from "@/store/store";
import { SceneManager } from "./scene";
import { setReadHistory } from "@/store/userDataReducer";
import { setStorage } from "../controller/storage/storageController";
import type { IStageCommitOptions } from '@/Core/Modules/stage/stageStateManager';
import { stageStateManager } from '@/Core/Modules/stage/stageStateManager';

let debugTextReadMode: boolean | null = null;

export function setDebugTextReadMode(isRead: boolean | null) {
export function setDebugTextReadMode(isRead: boolean | null, commitOptions: IStageCommitOptions = {}) {
debugTextReadMode = isRead;
if (isRead !== null) {
stageStateManager.setStageAndCommit('isRead', isRead);
stageStateManager.setStageAndCommit('isRead', isRead, commitOptions);
}
}

Expand Down
27 changes: 18 additions & 9 deletions packages/webgal/src/Core/Modules/stage/stageStateManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ export interface IStageCommitOptions {
syncPixiStage?: boolean;
applyPixiEffects?: boolean;
notifyReact?: boolean;
autoFastSave?: boolean;
skipAnimation?: boolean;
}

export interface IResolvedStageCommitOptions {
syncPixiStage: boolean;
applyPixiEffects: boolean;
notifyReact: boolean;
autoFastSave: boolean;
skipAnimation: boolean;
}

Expand Down Expand Up @@ -106,25 +108,29 @@ export class StageStateManager {
this.calculationStageState[key] = value;
}

public setStageAndCommit<K extends keyof IStageState>(key: K, value: IStageState[K]) {
public setStageAndCommit<K extends keyof IStageState>(
key: K,
value: IStageState[K],
options: IStageCommitOptions = {},
) {
this.setStage(key, value);
this.commit();
this.commit(options);
}

public setStageVar(payload: ISetGameVar) {
this.calculationStageState.GameVar[payload.key] = payload.value;
}

public setStageVarAndCommit(payload: ISetGameVar) {
public setStageVarAndCommit(payload: ISetGameVar, options: IStageCommitOptions = {}) {
this.setStageVar(payload);
this.commit();
this.commit(options);
}

public replaceCalculationStageState(stageState: IStageState) {
this.calculationStageState = cloneDeep(stageState);
}

public replaceAllStageState(stageState: IStageState, options?: IStageCommitOptions) {
public replaceAllStageState(stageState: IStageState, options: IStageCommitOptions = {}) {
this.calculationStageState = cloneDeep(stageState);
this.commit(options);
}
Expand All @@ -133,7 +139,7 @@ export class StageStateManager {
this.replaceCalculationStageState(stageState);
}

public resetAllStageState(stageState: IStageState, options?: IStageCommitOptions) {
public resetAllStageState(stageState: IStageState, options: IStageCommitOptions = {}) {
this.replaceAllStageState(stageState, options);
}

Expand Down Expand Up @@ -171,9 +177,9 @@ export class StageStateManager {
}
}

public updateEffectAndCommit(payload: IEffect) {
public updateEffectAndCommit(payload: IEffect, options: IStageCommitOptions = {}) {
this.updateEffect(payload);
this.commit();
this.commit(options);
}

public removeEffectByTargetId(target: string) {
Expand Down Expand Up @@ -357,10 +363,12 @@ export class StageStateManager {
}

public commit(options: IStageCommitOptions = {}) {
const notifyReact = options.notifyReact ?? true;
const resolvedOptions: IResolvedStageCommitOptions = {
syncPixiStage: options.syncPixiStage ?? true,
applyPixiEffects: options.applyPixiEffects ?? true,
notifyReact: options.notifyReact ?? true,
notifyReact,
autoFastSave: options.autoFastSave ?? notifyReact,
skipAnimation: options.skipAnimation ?? false,
};
Comment thread
A-kirami marked this conversation as resolved.
this.viewStageState = cloneDeep(this.calculationStageState);
Expand All @@ -375,6 +383,7 @@ export class StageStateManager {
syncPixiStage: false,
applyPixiEffects: true,
notifyReact: false,
autoFastSave: false,
skipAnimation: false,
});
}
Expand Down
Loading
Loading