Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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 { nextSentence } 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 @@ -118,7 +126,7 @@ export class PerformController {
return this.performList.some((e) => !e.isHoldOn && !e.skipNextCollect);
}

public settleNonHoldPerforms() {
public settleNonHoldPerforms(commitOptions: IStageCommitOptions = {}) {
let isGoNext = false;
for (let i = 0; i < this.performList.length; i++) {
const e = this.performList[i];
Expand All @@ -129,24 +137,26 @@ 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) {
nextSentence();
nextSentence(commitOptions);
}
}

public clearNonHoldPerformsFromStageState() {
stageStateManager.clearUncommittedNonHoldPerforms();
}

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 @@ -184,6 +194,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 会调用 nextSentence,而 nextSentence 会清除目前未结束的演出
Expand All @@ -195,7 +206,7 @@ export class PerformController {
i--;
if (e.goNextWhenOver) {
// nextSentence();
this.goNextWhenOver();
this.goNextWhenOver(commitOptions);
}
this.erasePerformFromState(name);
}
Expand All @@ -206,14 +217,15 @@ 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) {
// nextSentence();
this.goNextWhenOver();
this.goNextWhenOver(commitOptions);
}
/**
* 从状态表里清除演出
Expand Down Expand Up @@ -242,10 +254,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 @@ -265,11 +278,12 @@ 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) {
// nextSentence();
this.goNextWhenOver();
this.goNextWhenOver(commitOptions);
}
}

Expand All @@ -282,6 +296,7 @@ export class PerformController {
for (const e of this.performList) {
this.clearPerformTimeout(e);
this.stopStartedPerform(e);
this.performCommitOptions.delete(e);
}
this.performList = [];
}
Expand All @@ -300,7 +315,13 @@ export class PerformController {
perform.isStarted = false;
}

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

private goNextWhenOver = (commitOptions: IStageCommitOptions = {}) => {
let isBlockingNext = false;
this.performList?.forEach((e) => {
if (e.blockingNext())
Expand All @@ -309,9 +330,9 @@ export class PerformController {
});
if (isBlockingNext) {
// 有阻塞,提前结束
setTimeout(this.goNextWhenOver, 100);
setTimeout(() => this.goNextWhenOver(commitOptions), 100);
} else {
nextSentence();
nextSentence(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
28 changes: 18 additions & 10 deletions packages/webgal/src/Core/Modules/stage/stageStateManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ export interface IStageCommitOptions {
syncPixiStage?: boolean;
applyPixiEffects?: boolean;
notifyReact?: boolean;
autoFastSave?: boolean;
}

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

type StageCommitHandler = (stageState: IStageState, options: IResolvedStageCommitOptions) => void;
Expand Down Expand Up @@ -104,35 +106,39 @@ 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) {
public replaceAllStageState(stageState: IStageState, options: IStageCommitOptions = {}) {
this.calculationStageState = cloneDeep(stageState);
this.commit();
this.commit(options);
}

public resetCalculationStageState(stageState: IStageState) {
this.replaceCalculationStageState(stageState);
}

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

public updateEffect(payload: IEffect) {
Expand Down Expand Up @@ -169,9 +175,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,6 +363,7 @@ export class StageStateManager {
syncPixiStage: options.syncPixiStage ?? true,
applyPixiEffects: options.applyPixiEffects ?? true,
notifyReact: options.notifyReact ?? true,
autoFastSave: options.autoFastSave ?? true,
};
Comment thread
A-kirami marked this conversation as resolved.
this.viewStageState = cloneDeep(this.calculationStageState);
this.commitHandler?.(this.viewStageState, resolvedOptions);
Expand All @@ -370,6 +377,7 @@ export class StageStateManager {
syncPixiStage: false,
applyPixiEffects: true,
notifyReact: false,
autoFastSave: false,
});
}

Expand Down
21 changes: 11 additions & 10 deletions packages/webgal/src/Core/controller/gamePlay/nextSentence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { logger } from '../../util/logger';
import { webgalStore } from '@/store/store';

import { WebGAL } from '@/Core/WebGAL';
import type { IStageCommitOptions } from '@/Core/Modules/stage/stageStateManager';
import { stageStateManager } from '@/Core/Modules/stage/stageStateManager';

/**
* 步进前工作:检查阻塞,并在当前演出未完成时提前结束普通演出。
*/
export const preForward = () => {
export const preForward = (commitOptions: IStageCommitOptions = {}) => {
if (WebGAL.sceneManager.lockSceneWrite) {
logger.warn('next 被场景切换阻塞!');
return false;
Expand All @@ -22,7 +23,7 @@ export const preForward = () => {
const hasUnsettledNonHoldPerform = WebGAL.gameplay.performController.hasUnsettledNonHoldPerform();
if (hasUnsettledNonHoldPerform) {
logger.debug('提前结束被触发,现在清除普通演出');
WebGAL.gameplay.performController.settleNonHoldPerforms();
WebGAL.gameplay.performController.settleNonHoldPerforms(commitOptions);
return false;
}

Expand All @@ -32,7 +33,7 @@ export const preForward = () => {
/**
* 执行一条语句或由 -next 连接的语句序列,只修改演算状态并收集演出。
*/
export const forward = () => {
export const forward = (commitOptions: IStageCommitOptions = {}) => {
if (WebGAL.sceneManager.lockSceneWrite) {
logger.warn('forward 被场景切换阻塞!');
return false;
Expand All @@ -47,7 +48,7 @@ export const forward = () => {
WebGAL.gameplay.performController.clearNonHoldPerformsFromStageState();
WebGAL.gameplay.performController.beginCollectingPerforms();
try {
scriptExecutor();
scriptExecutor(0, commitOptions);
} finally {
WebGAL.gameplay.performController.endCollectingPerforms();
}
Expand All @@ -57,27 +58,27 @@ export const forward = () => {
/**
* 将演算状态提交到当前视图状态,并启动本序列收集到的演出。
*/
export const commitForward = () => {
stageStateManager.commit({ applyPixiEffects: false });
export const commitForward = (options: IStageCommitOptions = {}) => {
stageStateManager.commit({ ...options, applyPixiEffects: false });
WebGAL.gameplay.performController.commitPendingPerforms();
stageStateManager.applyCommittedPixiEffects();
};

/**
* 用户操作步进。
*/
export const nextSentence = () => {
export const nextSentence = (commitOptions: IStageCommitOptions = {}) => {
WebGAL.events.userInteractNext.emit();

const GUIState = webgalStore.getState().GUI;
if (GUIState.showTitle) {
return;
}

if (!preForward()) {
if (!preForward(commitOptions)) {
return;
}

forward();
commitForward();
forward(commitOptions);
commitForward(commitOptions);
};
Loading
Loading