You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
AdLike2048/assets/script/game/FrameFlowHost.ts

61 lines
1.6 KiB

import { director, Director } from 'cc';
type PendingWait = {
framesLeft: number;
done: () => void;
};
/**
* 业务层帧等待:走 Director 帧事件,不受 Component.unscheduleAllCallbacks 影响;
* 支持并发排队,避免后一次 waitFrames 覆盖前一次回调。
*/
export class FrameFlowHost {
private _pending: PendingWait[] = [];
private _listening = false;
private readonly _onFrame: () => void;
constructor() {
this._onFrame = this._tick.bind(this);
}
waitFrames(frames: number, done: () => void): void {
if (frames <= 0) {
done();
return;
}
this._pending.push({ framesLeft: frames, done });
if (!this._listening) {
this._listening = true;
director.on(Director.EVENT_AFTER_UPDATE, this._onFrame, this);
}
}
dispose(): void {
if (this._listening) {
director.off(Director.EVENT_AFTER_UPDATE, this._onFrame, this);
this._listening = false;
}
this._pending.length = 0;
}
private _tick(): void {
if (this._pending.length === 0) {
this.dispose();
return;
}
const current = this._pending;
this._pending = [];
for (let i = 0; i < current.length; i++) {
const item = current[i];
item.framesLeft--;
if (item.framesLeft <= 0) {
item.done();
} else {
this._pending.push(item);
}
}
if (this._pending.length === 0) {
this.dispose();
}
}
}