282 lines
8.2 KiB
TypeScript
282 lines
8.2 KiB
TypeScript
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<AssetManager.Bundle> | 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<AssetManager.Bundle>
|
|
*/
|
|
async loadBundle(): Promise<AssetManager.Bundle> {
|
|
// 如果已经加载完成,直接返回
|
|
if (this._bundle) {
|
|
return this._bundle;
|
|
}
|
|
|
|
// 如果正在加载中,返回加载Promise
|
|
if (this._loading) {
|
|
return this._loading;
|
|
}
|
|
|
|
// 开始加载
|
|
this._loading = new Promise<AssetManager.Bundle>((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<T extends Asset>(
|
|
path: string,
|
|
type: new (...args: any[]) => T
|
|
): ResProxy<T> {
|
|
return new ResProxy<T>(this, path, type);
|
|
}
|
|
|
|
/**
|
|
* 加载资源
|
|
* @param path 资源路径
|
|
* @param type 资源类型
|
|
* @returns Promise<资源>
|
|
*/
|
|
async loadRes<T extends Asset>(
|
|
path: string,
|
|
type: new (...args: any[]) => T
|
|
): Promise<T> {
|
|
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<void>
|
|
*/
|
|
async preload<T extends Asset>(
|
|
path: string,
|
|
type: new (...args: any[]) => T,
|
|
onProgress?: (finished: number, total: number) => void
|
|
): Promise<void> {
|
|
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<T extends Asset>(
|
|
dir: string,
|
|
type: new (...args: any[]) => T,
|
|
onProgress?: (finished: number, total: number) => void
|
|
): Promise<T[]> {
|
|
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<void>
|
|
*/
|
|
async preloadDir<T extends Asset>(
|
|
dir: string,
|
|
type: new (...args: any[]) => T,
|
|
onProgress?: (finished: number, total: number) => void
|
|
): Promise<void> {
|
|
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;
|
|
}
|
|
}
|