5.Eric-MVVM-Framework-资源管理器

  1. 创建解析器解析分包名和资源路径
    因为之前设计了分包管理器,所以默认资源加载是分包处理。
    这里创建一个解析分包名和路径名的工具类。
/**

 * 解析器

 * 提供路径解析功能。

 */

export class Parser {

    /**

     * 解析资源路径并将其分解为包名和路径

     *

     * @param resPath - 要解析的资源路径

     * @returns 返回包含 bundleName 和 path 的对象

     */

    public static path(resPath: string): { bundleName: string; path: string } {

        const [bundleName, ...pathParts] = resPath.split('/');

        return {

            bundleName,

            path: pathParts.join('/')

        };

    }

}


  1. 创建资源管理类ResMgr
/**

 * 资源管理器

 * 提供资源加载、释放功能。

 */

import { Asset, AssetManager, assetManager } from "cc";
import { Parser } from "../Utils/Parser";

class ResMgr {

    /** 私有构造函数,确保外部无法直接通过new创建实例 */

    private constructor() {}

    /** 单例实例 */

    public static readonly instance: ResMgr = new ResMgr();

    /**

     * 加载资源

     * @param resPath 资源路径

     * @param progressFun 进度回调函数

     * @param completeFun 完成回调函数

     * @returns Promise<T> 加载完成后的Promise

     */

    public async loadRes<T extends Asset>(

        resPath: string,

        progressFun?: (completedCount: number, totalCount: number, item: any) => void,

        completeFun?: (err: Error | null, asset: T) => void

    ): Promise<T> {

        try {

            const { bundleName, path } = Parser.path(resPath);

            const bundle = await eric.bundle.getBundle(bundleName);

            return await this.loadAsset<T>(bundle, path, progressFun, completeFun);

        } catch (error) {

            eric.log.err(`加载资源失败: ${resPath}`, error.message);

            throw error;

        }

    }

    /**

     * 加载目录下的所有资源

     * @param resPath 资源路径

     * @param progressFun 进度回调函数

     * @param completeFun 完成回调函数

     * @returns Promise<Array<Asset>> 加载完成后的Promise

     */

    public async loadResDir(

        resPath: string,

        progressFun?: (completedCount: number, totalCount: number, item: any) => void,

        completeFun?: (err: Error | null, assets: Array<Asset>) => void

    ): Promise<Array<Asset>> {

        try {

            const { bundleName, path } = Parser.path(resPath);

            const bundle = await eric.bundle.getBundle(bundleName);

            return await this.loadAssetDir(bundle, path, progressFun, completeFun);

        } catch (error) {

            eric.log.err(`加载目录失败: ${resPath}`, error.message);

            throw error;

        }

    }

    /**

     * 释放指定分包单个资源

     * @param resPath 资源路径

     */

    public releaseRes(resPath: string): void {

        const { bundleName, path } = Parser.path(resPath);

        const bundle = assetManager.getBundle(bundleName);

        if (bundle) {

            bundle.release(path);

        } else {

            eric.log.err(`分包 ${bundleName} 未找到,无法释放资源 ${path}。`);

        }

    }

    /**

     * 释放指定分包全部资源

     * @param bundleName 分包名称

     */

    public releaseBundle(bundleName: string): void {

        const bundle = assetManager.getBundle(bundleName);

        if (bundle) {

            bundle.releaseAll();

            assetManager.removeBundle(bundle);

        } else {

            eric.log.err(`分包 ${bundleName} 未找到,无法移除。`);

        }

    }

    /** 移除所有分包 */

    public releaseAll(): void {

        assetManager.releaseAll();

    }

    /**

     * 加载单个资源的辅助方法

     * @param bundle 资源所在的分包

     * @param path 资源路径

     * @param progressFun 进度回调函数

     * @param completeFun 完成回调函数

     * @returns Promise<T> 加载完成后的Promise

     */

    private loadAsset<T extends Asset>(

        bundle: AssetManager.Bundle,

        path: string,

        progressFun?: (completedCount: number, totalCount: number, item: any) => void,

        completeFun?: (err: Error | null, asset: T) => void

    ): Promise<T> {

        return new Promise<T>((resolve, reject) => {

            bundle.load(

                path,

                (completedCount, totalCount, item) => progressFun?.(completedCount, totalCount, item),

                (err, asset) => {

                    completeFun?.(err, asset as T);

                    if (err) {

                        eric.log.err(`从分包加载资源 ${path} 失败`, err.message);

                        reject(err);

                    } else {

                        resolve(asset as T);

                    }

                }

            );

        });

    }

    /**

     * 加载目录下所有资源的辅助方法

     * @param bundle 资源所在的分包

     * @param path 目录路径

     * @param progressFun 进度回调函数

     * @param completeFun 完成回调函数

     * @returns Promise<Array<Asset>> 加载完成后的Promise

     */

    private loadAssetDir(

        bundle: AssetManager.Bundle,

        path: string,

        progressFun?: (completedCount: number, totalCount: number, item: any) => void,

        completeFun?: (err: Error | null, assets: Array<Asset>) => void

    ): Promise<Array<Asset>> {

        return new Promise<Array<Asset>>((resolve, reject) => {

            bundle.loadDir(

                path,

                (completedCount, totalCount, item) => progressFun?.(completedCount, totalCount, item),

                (err, assets) => {

                    completeFun?.(err, assets);

                    if (err) {

                        eric.log.err(`从分包加载目录 ${path} 失败`, err.message);

                        reject(err);

                    } else {

                        resolve(assets);

                    }

                }

            );

        });

    }

}

  1. 建立映射

  2. 测试
    /**

  • 源码作者:
    */
    import { _decorator, Component, Node, Prefab } from 'cc';
    const { ccclass, property } = _decorator;

@ccclass('Test')
export class Test extends Component {
protected onLoad(): void {
const onProgress = (completedCount: number, totalCount: number,item:any) => {
eric.log.info("加载进度",${(completedCount/totalCount*100).toFixed(2)}%);
}
const onComplete = (error: Error | null, asset: any) => {
if (error) {
eric.log.info("加载完成", "失败");
} else {
eric.log.info("加载完成", "成功");
}
};

    eric.res.loadRes<Prefab>("Prefab/Test", onProgress, onComplete)
    .then((asset)=>{
        console.log("测试资源加载完成",asset);
    })
}

}

posted @ 2024-11-22 18:22  EricShx  阅读(22)  评论(0)    收藏  举报