Files
rougelike-demo/client/assets/scripts/Framework/ResMgr/ResProxy.ts

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}`;
}
}