Files
oops-plugin-framework/assets/libs/collection/AsyncQueue.ts
dgflash f2fe9d47b6 1. 存储模块全面优化,修复跨平台兼容性问题,完美支持所有Unicode字符
2. 存储模块性能提升,添加LRU缓存、批量操作支持,优化内存使用
3. 多语言模块性能与内存管理优化,组件查询性能提升
4. 时间模块类型安全与性能优化,使用泛型替代any,对象池机制减少内存分配
5. 事件系统修复双重注册、重复注册等严重问题,实现EventData对象池减少GC压力
6. RandomManager修复4个逻辑BUG,包括边界问题和越界问题
7. 音频模块内存与性能优化,避免重复加载,优化数据结构,添加完整清理机制
8. CCView与CCViewVM合并,支持按需启用MVVM
9. Collection模块优化,AsyncQueue添加队列容量限制,Collection查询性能提升
10. ECS系统全面优化,对象池复用减少内存分配,循环性能提升
11. 优化MVVM组件性能
2026-01-09 21:54:05 +08:00

287 lines
7.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { log, warn } from 'cc';
export type NextFunction = (nextArgs?: any) => void;
export type AsyncCallback = (next: NextFunction, params: any, args: any) => void;
interface AsyncTask {
/**
* 任务uuid
*/
uuid: number;
/**
* 任务开始执行的回调
* params: push时传入的参数
* args: 上个任务传来的参数
*/
callbacks: Array<AsyncCallback>;
/**
* 任务参数
*/
params: any
}
/**
* 异步队列处理
* @example
var queue: AsyncQueue = new AsyncQueue();
queue.push((next: NextFunction, params: any, args: any) => {
oops.res.load("language/font/" + oops.language.current, next);
});
queue.push((next: NextFunction, params: any, args: any) => {
oops.res.loadDir("common", next);
});
queue.complete = () => {
console.log("处理完成");
};
queue.play();
*/
export class AsyncQueue {
// 任务task的唯一标识
private static _$uuid_count = 1;
// 正在运行的任务
private _runningAsyncTask: AsyncTask | null = null;
private _queues: Array<AsyncTask> = [];
/** 任务队列 */
get queues(): Array<AsyncTask> {
return this._queues;
}
// 正在执行的异步任务标识
private _isProcessingTaskUUID = 0;
private _enable = true;
/** 最大任务队列长度,防止内存泄漏 */
private static readonly MAX_QUEUE_SIZE = 1000;
/** 是否开启可用 */
get enable() {
return this._enable;
}
/** 是否开启可用 */
set enable(val: boolean) {
if (this._enable === val) {
return;
}
this._enable = val;
if (val && this.size > 0) {
this.play();
}
}
/**
* 任务队列完成回调
*/
complete: Function | null = null;
/**
* 添加一个异步任务到队列中
* @param callback 回调
* @param params 参数
*/
push(callback: AsyncCallback, params: any = null): number {
// 防止队列无限增长
if (this._queues.length >= AsyncQueue.MAX_QUEUE_SIZE) {
warn(`AsyncQueue 队列已满 (${AsyncQueue.MAX_QUEUE_SIZE}),无法添加新任务`);
return -1;
}
const uuid = AsyncQueue._$uuid_count++;
this._queues.push({
uuid: uuid,
callbacks: [callback],
params: params
});
return uuid;
}
/**
* 添加多个任务,多个任务函数会同时执行
* @param params 参数据
* @param callbacks 回调
* @returns
*/
pushMulti(params: any, ...callbacks: AsyncCallback[]): number {
// 防止队列无限增长
if (this._queues.length >= AsyncQueue.MAX_QUEUE_SIZE) {
warn(`AsyncQueue 队列已满 (${AsyncQueue.MAX_QUEUE_SIZE}),无法添加新任务`);
return -1;
}
const uuid = AsyncQueue._$uuid_count++;
this._queues.push({
uuid: uuid,
callbacks: callbacks,
params: params
});
return uuid;
}
/**
* 移除一个还未执行的异步任务
* @param uuid 任务唯一编号
*/
remove(uuid: number) {
if (this._runningAsyncTask?.uuid === uuid) {
warn('正在执行的任务不可以移除');
return;
}
// 优化:使用标准 for 循环,缓存长度
const len = this._queues.length;
for (let i = 0; i < len; i++) {
if (this._queues[i].uuid === uuid) {
this._queues.splice(i, 1);
break;
}
}
}
/** 队列长度 */
get size(): number {
return this._queues.length;
}
/** 是否有正在处理的任务 */
get isProcessing(): boolean {
return this._isProcessingTaskUUID > 0;
}
/** 队列是否已停止 */
get isStop(): boolean {
if (this._queues.length > 0) {
return false;
}
if (this.isProcessing) {
return false;
}
return true;
}
/** 正在执行的任务参数 */
get runningParams() {
if (this._runningAsyncTask) {
return this._runningAsyncTask.params;
}
return null;
}
/** 清空队列 */
clear() {
// 优化:使用 length = 0 而不是创建新数组,更高效
this._queues.length = 0;
this._isProcessingTaskUUID = 0;
this._runningAsyncTask = null;
}
/** 跳过当前正在执行的任务 */
step() {
if (this.isProcessing) {
this.next(this._isProcessingTaskUUID);
}
}
/**
* 开始运行队列
* @param args 参数
*/
play(args: any = null) {
if (this.isProcessing) {
return;
}
if (!this._enable) {
return;
}
const actionData: AsyncTask = this._queues.shift()!;
if (actionData) {
this._runningAsyncTask = actionData;
const taskUUID: number = actionData.uuid;
this._isProcessingTaskUUID = taskUUID;
const callbacks: Array<AsyncCallback> = actionData.callbacks;
const callbackLen = callbacks.length;
if (callbackLen === 1) {
const nextFunc: NextFunction = (nextArgs: any = null) => {
this.next(taskUUID, nextArgs);
};
callbacks[0](nextFunc, actionData.params, args);
}
else {
// 多个任务函数同时执行
let fnum: number = callbackLen;
const nextArgsArr: any[] = [];
const nextFunc: NextFunction = (nextArgs: any = null) => {
--fnum;
nextArgsArr.push(nextArgs || null);
if (fnum === 0) {
this.next(taskUUID, nextArgsArr);
}
};
// 使用标准 for 循环,性能更好
for (let i = 0; i < callbackLen; i++) {
callbacks[i](nextFunc, actionData.params, args);
}
}
}
else {
this._isProcessingTaskUUID = 0;
this._runningAsyncTask = null;
if (this.complete) {
this.complete(args);
}
}
}
/**
* 往队列中push一个延时任务
* @param time 毫秒时间
* @param callback (可选参数)时间到了之后回调
*/
yieldTime(time: number, callback: Function | null = null) {
const task = function (next: Function, params: any, args: any) {
const _t = setTimeout(() => {
clearTimeout(_t);
if (callback) {
callback();
}
next(args);
}, time);
};
this.push(task, { des: 'AsyncQueue.yieldTime' });
}
protected next(taskUUID: number, args: any = null) {
if (this._isProcessingTaskUUID === taskUUID) {
this._isProcessingTaskUUID = 0;
this._runningAsyncTask = null;
this.play(args);
}
else {
if (this._runningAsyncTask) {
log(this._runningAsyncTask);
}
}
}
/**
* 返回一个执行函数执行函数调用count次后next将触发
* @param count
* @param next
* @return 返回一个匿名函数
*/
static excuteTimes(count: number, next: Function | null = null): Function {
let fnum: number = count;
const call = () => {
--fnum;
if (fnum === 0) {
next && next();
}
};
return call;
}
}