import { Asset, AssetManager, assetManager } from 'cc'; import { ResProxy } from './ResProxy'; /** * Bundle代理类 * 职责: * - 异步加载Bundle * - 管理Bundle的生命周期 * - 提供从Bundle加载资源的统一接口 */ export class BundleProxy { private _bundleName: string; private _bundle: AssetManager.Bundle | null = null; private _loading: Promise | null = null; constructor(bundleName: string, bundle?: AssetManager.Bundle) { this._bundleName = bundleName; this._bundle = bundle || null; } /** * 获取Bundle名称 */ get bundleName(): string { return this._bundleName; } /** * 获取Bundle实例(同步) */ get bundle(): AssetManager.Bundle | null { return this._bundle; } /** * 异步加载Bundle * @returns Promise */ async loadBundle(): Promise { // 如果已经加载完成,直接返回 if (this._bundle) { return this._bundle; } // 如果正在加载中,返回加载Promise if (this._loading) { return this._loading; } // 开始加载 this._loading = new Promise((resolve, reject) => { console.log(`[BundleProxy] 开始加载Bundle: ${this._bundleName}`); assetManager.loadBundle(this._bundleName, (err, bundle) => { if (err) { console.error(`[BundleProxy] 加载Bundle失败: ${this._bundleName}`, err); this._loading = null; reject(err); return; } this._bundle = bundle; this._loading = null; console.log(`[BundleProxy] Bundle加载成功: ${this._bundleName}`); resolve(bundle); }); }); return this._loading; } /** * 创建资源代理 * @param path 资源路径 * @param type 资源类型 * @returns ResProxy */ createResProxy( path: string, type: new (...args: any[]) => T ): ResProxy { return new ResProxy(this, path, type); } /** * 加载资源 * @param path 资源路径 * @param type 资源类型 * @returns Promise<资源> */ async loadRes( path: string, type: new (...args: any[]) => T ): Promise { const bundle = await this.loadBundle(); return new Promise((resolve, reject) => { console.log(`[BundleProxy] 开始加载资源: ${this._bundleName}/${path}`); bundle.load(path, type, (err, asset) => { if (err) { console.error(`[BundleProxy] 加载资源失败: ${this._bundleName}/${path}`, err); reject(err); return; } console.log(`[BundleProxy] 资源加载成功: ${this._bundleName}/${path}`); resolve(asset as T); }); }); } /** * 预加载资源 * @param path 资源路径 * @param type 资源类型 * @param onProgress 进度回调 * @returns Promise */ async preload( path: string, type: new (...args: any[]) => T, onProgress?: (finished: number, total: number) => void ): Promise { const bundle = await this.loadBundle(); return new Promise((resolve, reject) => { console.log(`[BundleProxy] 开始预加载资源: ${this._bundleName}/${path}`); bundle.preload( path, type, (finished, total) => { if (onProgress) { onProgress(finished, total); } }, (err) => { if (err) { console.error(`[BundleProxy] 预加载资源失败: ${this._bundleName}/${path}`, err); reject(err); return; } console.log(`[BundleProxy] 资源预加载成功: ${this._bundleName}/${path}`); resolve(); } ); }); } /** * 加载目录 * @param dir 目录路径 * @param type 资源类型 * @param onProgress 进度回调 * @returns Promise<资源数组> */ async loadDir( dir: string, type: new (...args: any[]) => T, onProgress?: (finished: number, total: number) => void ): Promise { const bundle = await this.loadBundle(); return new Promise((resolve, reject) => { console.log(`[BundleProxy] 开始加载目录: ${this._bundleName}/${dir}`); bundle.loadDir( dir, type, (finished, total) => { if (onProgress) { onProgress(finished, total); } }, (err, assets) => { if (err) { console.error(`[BundleProxy] 加载目录失败: ${this._bundleName}/${dir}`, err); reject(err); return; } console.log(`[BundleProxy] 目录加载成功: ${this._bundleName}/${dir}, 共 ${assets.length} 个资源`); resolve(assets as T[]); } ); }); } /** * 预加载目录 * @param dir 目录路径 * @param type 资源类型 * @param onProgress 进度回调 * @returns Promise */ async preloadDir( dir: string, type: new (...args: any[]) => T, onProgress?: (finished: number, total: number) => void ): Promise { const bundle = await this.loadBundle(); return new Promise((resolve, reject) => { console.log(`[BundleProxy] 开始预加载目录: ${this._bundleName}/${dir}`); bundle.preloadDir( dir, type, (finished, total) => { if (onProgress) { onProgress(finished, total); } }, (err) => { if (err) { console.error(`[BundleProxy] 预加载目录失败: ${this._bundleName}/${dir}`, err); reject(err); return; } console.log(`[BundleProxy] 目录预加载成功: ${this._bundleName}/${dir}`); resolve(); } ); }); } /** * 释放资源 * @param path 资源路径 */ release(path: string): void { if (!this._bundle) { console.warn(`[BundleProxy] Bundle未加载,无法释放资源: ${this._bundleName}/${path}`); return; } this._bundle.release(path); console.log(`[BundleProxy] 释放资源: ${this._bundleName}/${path}`); } /** * 释放目录资源 * @param dir 目录路径 */ releaseDir(dir: string): void { if (!this._bundle) { console.warn(`[BundleProxy] Bundle未加载,无法释放目录: ${this._bundleName}/${dir}`); return; } // Cocos没有直接的releaseDir方法,需要手动释放目录下的资源 // 这里简化处理,实际使用时可能需要追踪加载的资源 console.log(`[BundleProxy] 释放目录资源: ${this._bundleName}/${dir}`); } /** * 释放所有资源 */ releaseAll(): void { if (!this._bundle) { console.warn(`[BundleProxy] Bundle未加载,无法释放所有资源: ${this._bundleName}`); return; } this._bundle.releaseAll(); console.log(`[BundleProxy] 释放所有资源: ${this._bundleName}`); } /** * 销毁Bundle */ destroy(): void { if (this._bundle) { this.releaseAll(); this._bundle = null; } this._loading = null; } }