import { Asset, AssetManager, assetManager } from "cc"; import { bundleMgr } from "./BundleMgr"; /** * 资源管理器 * 提供资源加载、释放功能。 */ class ResMgr { /** 私有构造函数 */ private constructor() { } /** 单例实例 */ public static readonly instance: ResMgr = new ResMgr(); /** * 加载资源 * @param resPath 资源路径 * @param onProgress 进度回调函数 * @param onComplete 完成回调函数 * @returns Promise 加载完成后的Promise */ public async loadRes( resPath: string, onProgress?: (completedCount: number, totalCount: number, item: any) => void, onComplete?: (err: Error | null, asset: T) => void ): Promise { try { const { bundleName, path } = this.path(resPath); const bundle = await bundleMgr.getBundle(bundleName); return await this.loadAsset(bundle, path, onProgress, onComplete); } catch (error) { console.error(`加载资源失败: ${resPath}`, error.message); throw error; } } /** * 加载目录下的所有资源 * @param resPath 资源路径 * @param onProgress 进度回调函数 * @param onComplete 完成回调函数 * @returns Promise> 加载完成后的Promise */ public async loadResDir( resPath: string, onProgress?: (completedCount: number, totalCount: number, item: any) => void, onComplete?: (err: Error | null, assets: Array) => void ): Promise> { try { const { bundleName, path } = this.path(resPath); const bundle = await bundleMgr.getBundle(bundleName); return await this.loadAssetDir(bundle, path, onProgress, onComplete); } catch (error) { console.error(`加载目录失败: ${resPath}`, error.message); throw error; } } /** * 释放指定分包单个资源 * @param resPath 资源路径 */ public releaseRes(resPath: string): void { const { bundleName, path } = this.path(resPath); const bundle = assetManager.getBundle(bundleName); if (bundle) { bundle.release(path); } else { console.error(`分包 ${bundleName} 未找到,无法释放资源 ${path}。`); } } /** * 释放指定分包全部资源 * @param bundleName 分包名称 */ public releaseBundle(bundleName: string): void { const bundle = assetManager.getBundle(bundleName); if (bundle) { bundle.releaseAll(); assetManager.removeBundle(bundle); } else { console.error(`分包 ${bundleName} 未找到,无法移除。`); } } /** 移除所有分包 */ public releaseAll(): void { assetManager.releaseAll(); } /** * 加载单个资源的辅助方法 * @param bundle 资源所在的分包 * @param path 资源路径 * @param onProgress 进度回调函数 * @param onComplete 完成回调函数 * @returns Promise 加载完成后的Promise */ private loadAsset( bundle: AssetManager.Bundle, path: string, onProgress?: (completedCount: number, totalCount: number, item: any) => void, onComplete?: (err: Error | null, asset: T) => void ): Promise { return new Promise((resolve, reject) => { bundle.load( path, (completedCount, totalCount, item) => onProgress?.(completedCount, totalCount, item), (err, asset) => { onComplete?.(err, asset as T); if (err) { console.error(`从分包加载资源 ${path} 失败`, err.message); reject(err); } else { resolve(asset as T); } } ); }); } /** * 加载目录下所有资源的辅助方法 * @param bundle 资源所在的分包 * @param path 目录路径 * @param onProgress 进度回调函数 * @param onComplete 完成回调函数 * @returns Promise> 加载完成后的Promise */ private loadAssetDir( bundle: AssetManager.Bundle, path: string, onProgress?: (completedCount: number, totalCount: number, item: any) => void, onComplete?: (err: Error | null, assets: Array) => void ): Promise> { return new Promise>((resolve, reject) => { bundle.loadDir( path, (completedCount, totalCount, item) => onProgress?.(completedCount, totalCount, item), (err, assets) => { onComplete?.(err, assets); if (err) { console.error(`从分包加载目录 ${path} 失败`, err.message); reject(err); } else { resolve(assets); } } ); }); } /** * 解析资源路径并将其分解为包名和路径 * * @param resPath - 要解析的资源路径 * @returns 返回包含 bundleName 和 path 的对象 */ private path(resPath: string): { bundleName: string; path: string } { const [bundleName, ...pathParts] = resPath.split('/'); return { bundleName, path: pathParts.join('/') }; } } /** 资源管理器实例 */ export const resMgr = ResMgr.instance;