172 lines
3.9 KiB
TypeScript
172 lines
3.9 KiB
TypeScript
import { Asset } from 'cc';
|
|
import { BundleProxy } from './BundleProxy';
|
|
|
|
/**
|
|
* 资源代理类
|
|
* 职责:
|
|
* - 封装单个资源的异步加载逻辑
|
|
* - 管理资源的缓存状态
|
|
* - 提供资源的加载、预加载、释放接口
|
|
*/
|
|
export class ResProxy<T extends Asset> {
|
|
private _bundleProxy: BundleProxy;
|
|
private _path: string;
|
|
private _type: new (...args: any[]) => T;
|
|
private _asset: T | null = null;
|
|
private _loading: Promise<T> | null = null;
|
|
private _preloading: Promise<void> | null = null;
|
|
|
|
constructor(
|
|
bundleProxy: BundleProxy,
|
|
path: string,
|
|
type: new (...args: any[]) => T
|
|
) {
|
|
this._bundleProxy = bundleProxy;
|
|
this._path = path;
|
|
this._type = type;
|
|
}
|
|
|
|
/**
|
|
* 获取资源路径
|
|
*/
|
|
get path(): string {
|
|
return this._path;
|
|
}
|
|
|
|
/**
|
|
* 获取Bundle名称
|
|
*/
|
|
get bundleName(): string {
|
|
return this._bundleProxy.bundleName;
|
|
}
|
|
|
|
/**
|
|
* 获取资源实例(同步)
|
|
*/
|
|
get asset(): T | null {
|
|
return this._asset;
|
|
}
|
|
|
|
/**
|
|
* 是否已加载
|
|
*/
|
|
get isLoaded(): boolean {
|
|
return this._asset !== null;
|
|
}
|
|
|
|
/**
|
|
* 是否正在加载中
|
|
*/
|
|
get isLoading(): boolean {
|
|
return this._loading !== null;
|
|
}
|
|
|
|
/**
|
|
* 是否正在预加载中
|
|
*/
|
|
get isPreloading(): boolean {
|
|
return this._preloading !== null;
|
|
}
|
|
|
|
/**
|
|
* 加载资源
|
|
* @returns Promise<资源>
|
|
*/
|
|
async load(): Promise<T> {
|
|
// 如果已经加载完成,直接返回
|
|
if (this._asset) {
|
|
console.log(`[ResProxy] 从缓存获取资源: ${this.bundleName}/${this._path}`);
|
|
return this._asset;
|
|
}
|
|
|
|
// 如果正在加载中,返回加载Promise
|
|
if (this._loading) {
|
|
return this._loading;
|
|
}
|
|
|
|
// 开始加载
|
|
this._loading = this._bundleProxy.loadRes(this._path, this._type);
|
|
|
|
try {
|
|
this._asset = await this._loading;
|
|
return this._asset;
|
|
} finally {
|
|
this._loading = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 预加载资源
|
|
* @param onProgress 进度回调
|
|
* @returns Promise<void>
|
|
*/
|
|
async preload(onProgress?: (finished: number, total: number) => void): Promise<void> {
|
|
// 如果已经加载完成,直接返回
|
|
if (this._asset) {
|
|
console.log(`[ResProxy] 资源已加载,无需预加载: ${this.bundleName}/${this._path}`);
|
|
return;
|
|
}
|
|
|
|
// 如果正在预加载中,返回预加载Promise
|
|
if (this._preloading) {
|
|
return this._preloading;
|
|
}
|
|
|
|
// 如果正在加载中,等待加载完成
|
|
if (this._loading) {
|
|
await this._loading;
|
|
return;
|
|
}
|
|
|
|
// 开始预加载
|
|
this._preloading = this._bundleProxy.preload(this._path, this._type, onProgress);
|
|
|
|
try {
|
|
await this._preloading;
|
|
} finally {
|
|
this._preloading = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 释放资源
|
|
*/
|
|
release(): void {
|
|
if (!this._asset) {
|
|
console.warn(`[ResProxy] 资源未加载,无法释放: ${this.bundleName}/${this._path}`);
|
|
return;
|
|
}
|
|
|
|
this._bundleProxy.release(this._path);
|
|
this._asset = null;
|
|
console.log(`[ResProxy] 释放资源: ${this.bundleName}/${this._path}`);
|
|
}
|
|
|
|
/**
|
|
* 清除缓存(不释放资源)
|
|
*/
|
|
clearCache(): void {
|
|
this._asset = null;
|
|
this._loading = null;
|
|
this._preloading = null;
|
|
}
|
|
|
|
/**
|
|
* 重新加载资源
|
|
* @returns Promise<资源>
|
|
*/
|
|
async reload(): Promise<T> {
|
|
if (this._asset) {
|
|
this.release();
|
|
}
|
|
return this.load();
|
|
}
|
|
|
|
/**
|
|
* 获取完整路径
|
|
*/
|
|
getFullPath(): string {
|
|
return `${this.bundleName}/${this._path}`;
|
|
}
|
|
}
|