CocosCreator 源码-CCAssetManager.js详解

断更了几天,主要是梳理整个和CCAssetManager相关的类。CCAssetManager作为整个引擎的核心资源管理器。需要特别仔细的分析。


const preprocess = require('./preprocess');//正常加载管线里面的加载任务function

const fetch = require('./fetch');//下载管线里面的请求任务

const Cache = require('./cache');//容器类

const helper = require('./helper');//核心长uid和短uid的转换,判断是scene还是prefab等function

const releaseManager = require('./releaseManager');//资源释放控制类

const dependUtil = require('./depend-util');//资源依赖管理类,单例

const load = require('./load');//正常加载管线里面的任务function

const Pipeline = require('./pipeline');//任务管线类

const Task = require('./task');//管线中的任务function

const RequestItem = require('./request-item');//加载任务里面的具体信息,uid,url,isNative等信息

const downloader = require('./downloader');//管理所有下载过程,downloader 是个单例,比如下载次数等

const parser = require('./parser');//解析已下载的文件,parser 是一个单例

const packManager = require('./pack-manager');//处理打包资源,包括拆包,加载,缓存等等,这是一个单例

const Bundle = require('./bundle');//一个包含一定数量资源(包括场景)的包,你可以加载,预加载,释放此包内的资源

const builtins = require('./builtins');//此模块包含内建资源,这是一个单例,

const factory = require('./factory');//一个工厂模式类,批量创建了加载jpg,audio等不同方式的handler function

const { parse, combine } = require('./urlTransformer');//加载资源的info数据的转换

const { parseParameters, asyncify } = require('./utilities');//公用函数eg,获取依赖等

/*

以下是新建的几个容器 变量,在shared.js文件创建的实例

bundles 一个类map 存储bundle//默认会存储 internal main resources 三个bundle

有远程加载的,也会存储到这个里面

*/

const { assets, files, parsed, pipeline, transformPipeline,

    fetchPipeline, RequestType, bundles, BuiltinBundleName } = require('./shared');

/**

* @module cc

*/

/**

* !#en

* This module controls asset's behaviors and information, include loading, releasing etc. it is a singleton

* All member can be accessed with `cc.assetManager`.

*

* !#zh

* 此模块管理资源的行为和信息,包括加载,释放等,这是一个单例,所有成员能够通过 `cc.assetManager` 调用

*

* @class AssetManager

*/

function AssetManager () {

    this._preprocessPipe = preprocess;//没发现有地方调用_preprocessPipe这个变量

    this._fetchPipe = fetch;//没发现有地方调用_fetchPipe这个变量

    this._loadPipe = load;//没发现有地方调用_loadPipe这个变量

    /**

    * !#en

    * Normal loading pipeline

    *

    * !#zh

    * 正常加载管线

    * 将两个function添加到 pipeline实例里面的pipes数组里面

    * @property pipeline

    * @type {Pipeline}

    */

    this.pipeline = pipeline.append(preprocefss).append(load);


    /**

    * !#en

    * Fetching pipeline

    *

    * !#zh

    * 下载管线

    * 将两个function添加到 pipeline实例里面的pipes数组里面

    * @property fetchPipeline

    * @type {Pipeline}

    */

    this.fetchPipeline = fetchPipeline.append(preprocess).append(fetch);

    /**

    * !#en

    * Url transformer

    *

    * !#zh

    * Url 转换器

    * 将两个function添加到 pipeline实例里面的pipes数组里面

    * @property transformPipeline

    * @type {Pipeline}

    */

    this.transformPipeline = transformPipeline.append(parse).append(combine);

    /**

    * !#en

    * The collection of bundle which is already loaded, you can remove cache with {{#crossLink "AssetManager/removeBundle:method"}}{{/crossLink}}

    *

    * !#zh

    * 已加载 bundle 的集合, 你能通过 {{#crossLink "AssetManager/removeBundle:method"}}{{/crossLink}} 来移除缓存

    *

    * @property bundles

    * @type {Cache}

    * @typescript

    * bundles: AssetManager.Cache<AssetManager.Bundle>

    */

    this.bundles = bundles;

    /**

    * !#en

    * The collection of asset which is already loaded, you can remove cache with {{#crossLink "AssetManager/releaseAsset:method"}}{{/crossLink}}

    *

    * !#zh

    * 已加载资源的集合, 你能通过 {{#crossLink "AssetManager/releaseAsset:method"}}{{/crossLink}} 来移除缓存

    * assets 存储 texture2d等资源集合

    * @property assets

    * @type {Cache}

    * @typescript

    * assets: AssetManager.Cache<cc.Asset>

    */

    this.assets = assets;


    /*

    没找到有调用_files的地方,直接看shares的file注解

    */

    this._files = files;


    /*

    没找到对_parsed的引用和操作,直接看shared.js

    parsed 是针对load资源的解析后存储的 容器。

    */

    this._parsed = parsed;

    /*

        importBase: 'assets/others/import',

        nativeBase: 'assets/others/native'

        */

    this.generalImportBase = '';

    this.generalNativeBase = '';

    /**

    * !#en

    * Manage relationship between asset and its dependencies

    *

    * !#zh

    * 管理资源依赖关系

    *

    * @property dependUtil

    * @type {DependUtil}

    */

    this.dependUtil = dependUtil;

    /*

    释放的管理类

    */

    this._releaseManager = releaseManager;

    /**

    * !#en

    * Whether or not cache the loaded asset

    *

    * !#zh

    * 是否缓存已加载的资源

    *

    * @property cacheAsset

    * @type {boolean}

    */

    this.cacheAsset = true;

    /**

    * !#en

    * Whether or not load asset forcely, if it is true, asset will be loaded regardless of error

    *

    * !#zh

    * 是否强制加载资源, 如果为 true ,加载资源将会忽略报错

    * 【这个参数很有用,具体项目很容易遇到加载报错的情况】

    * @property force

    * @type {boolean}

    */

    this.force = false;

    /**

    * !#en

    * Some useful function

    *

    * !#zh

    * 一些有用的方法

    * 包括uuid的长短转换,通过url返回uuid,

    * 判断asset 是scene 还是prefab等公用方法

    * @property utils

    * @type {Helper}

    */

    this.utils = helper;

    /**

    * !#en

    * Manage all downloading task

    *

    * !#zh

    * 管理所有下载任务

    *

    * @property downloader

    * @type {Downloader}

    */

    this.downloader = downloader;

    /**

    * !#en

    * Manage all parsing task

    *

    * !#zh

    * 管理所有解析任务

    *

    * @property parser

    * @type {Parser}

    */

    this.parser = parser;

    /**

    * !#en

    * Manage internal asset

    *

    * !#zh

    * 管理内置资源

    *

    * @property builtins

    * @type {Builtins}

    */

    this.builtins = builtins;

    /**

    * !#en

    * Manage all packed asset

    *

    * !#zh

    * 管理所有合并后的资源

    *

    * @property packManager

    * @type {PackManager}

    */

    this.packManager = packManager;

    this.factory = factory;

    /**

    * !#en

    * Cache manager is a module which controls all caches downloaded from server in non-web platform.

    *

    * !#zh

    * 缓存管理器是一个模块,在非 WEB 平台上,用于管理所有从服务器上下载下来的缓存

    *

    * @property cacheManager

    * @type {cc.AssetManager.CacheManager}

    * @typescript

    * cacheManager: cc.AssetManager.CacheManager|null

    */

    this.cacheManager = null;

    /**

    * !#en

    * The preset of options

    *

    * !#zh

    * 可选参数的预设集

    *

    * @property presets

    * @type {Object}

    * @typescript

    * presets: Record<string, Record<string, any>>

    */

    this.presets = {

        'default': {

            priority: 0,

        },

        'preload': {

            maxConcurrency: 2,

            maxRequestsPerFrame: 2,

            priority: -1,

        },

        'scene': {

            maxConcurrency: 8,

            maxRequestsPerFrame: 8,

            priority: 1,

        },

        'bundle': {

            maxConcurrency: 8,

            maxRequestsPerFrame: 8,

            priority: 2,

        },

        'remote': {

            maxRetryCount: 4

        },

        'script': {

            priority: 2

        }

    }

}

/*

静态类的引用

*/

AssetManager.Pipeline = Pipeline;

AssetManager.Task = Task;

AssetManager.Cache = Cache;

AssetManager.RequestItem = RequestItem;

AssetManager.Bundle = Bundle;

AssetManager.BuiltinBundleName = BuiltinBundleName;

AssetManager.prototype = {

    constructor: AssetManager,

    /**

    * !#en

    * The builtin 'main' bundle

    *

    * !#zh

    * 内置 main 包

    *

    * @property main

    * @readonly

    * @type {Bundle}

    */

    get main () {

        return bundles.get(BuiltinBundleName.MAIN);

    },

    /**

    * !#en

    * The builtin 'resources' bundle

    *

    * !#zh

    * 内置 resources 包

    *

    * @property resources

    * @readonly

    * @type {Bundle}

    */

    get resources () {

        return bundles.get(BuiltinBundleName.RESOURCES);////获取到的是 resources目录针对的bundle对象

    },

    /**

    * !#en

    * The builtin 'internal' bundle

    *

    * !#zh

    * 内置 internal 包

    *

    * @property internal

    * @readonly

    * @type {Bundle}

    */

    get internal () {

        return bundles.get(BuiltinBundleName.INTERNAL);

    },

    /**

    * !#en

    * Initialize assetManager with options

    *

    * !#zh

    * 初始化资源管理器

    *

    * @method init

    * @param {Object} options

    *

    * @typescript

    * init(options: Record<string, any>): void

    */

    init (options) {

        options = options || Object.create(null);//创建一个类似map的容器

        this._files.clear();

        this._parsed.clear();

        this._releaseManager.init();//释放资源管理器初始化

        /*

        assets 存储 texture2d等asset资源

        */

        this.assets.clear();

        /*

        bundles存储的一个包,里面是集成的很多内容,比如可以把代码和资源集成为一个bundle

        */

        this.bundles.clear();

        this.packManager.init();

        /*

        /* 这个是md5的后缀

    bundleVers: { internal: "f1413", resources: "d99d6", main: "d3b73" }//Bundle 的 md5 值

      */ */

        this.downloader.init(options.bundleVers);//

        this.parser.init();

        this.dependUtil.init();

        /*

        查看 urlTransformer.js 为了转换ttf路径名称 设置的这两个个参数

        预览的时候这两个参数的默认值

        importBase: 'assets/others/import',

        nativeBase: 'assets/others/native'


        web运行--"assets/internal/import"

            */

        this.generalImportBase = options.importBase;

        this.generalNativeBase = options.nativeBase;

    },

    /**

    * !#en

    * Get the bundle which has been loaded

    *

    * !#zh

    * 获取已加载的分包

    *

    * @method getBundle

    * @param {String} name - The name of bundle

    * @return {Bundle} - The loaded bundle

    *

    * @example

    * // ${project}/assets/test1

    * cc.assetManager.getBundle('test1');

    *

    * cc.assetManager.getBundle('resources');

    *

    * @typescript

    * getBundle (name: string): cc.AssetManager.Bundle

    */

    getBundle (name) {

        return bundles.get(name);

    },

    /**

    * !#en

    * Remove this bundle. NOTE: The asset whthin this bundle will not be released automatically, you can call {{#crossLink "Bundle/releaseAll:method"}}{{/crossLink}} manually before remove it if you need

    *

    * !#zh

    * 移除此包, 注意:这个包内的资源不会自动释放, 如果需要的话你可以在摧毁之前手动调用 {{#crossLink "Bundle/releaseAll:method"}}{{/crossLink}} 进行释放

    *

    * @method removeBundle

    * @param {Bundle} bundle - The bundle to be removed

    *

    * @typescript

    * removeBundle(bundle: cc.AssetManager.Bundle): void

    */

    removeBundle (bundle) {

        bundle._destroy();

        bundles.remove(bundle.name);

    },

    /**

    * !#en

    * General interface used to load assets with a progression callback and a complete callback. You can achieve almost all effect you want with combination of `requests` and `options`.

    * It is highly recommended that you use more simple API, such as `load`, `loadDir` etc. Every custom parameter in `options` will be distribute to each of `requests`.

    * if request already has same one, the parameter in request will be given priority. Besides, if request has dependencies, `options` will distribute to dependencies too.

    * Every custom parameter in `requests` will be tranfered to handler of `downloader` and `parser` as `options`.

    * You can register you own handler downloader or parser to collect these custom parameters for some effect.

    *

    * Reserved Keyword: `uuid`, `url`, `path`, `dir`, `scene`, `type`, `priority`, `preset`, `audioLoadMode`, `ext`, `bundle`, `onFileProgress`, `maxConcurrency`, `maxRequestsPerFrame`

    * `maxRetryCount`, `version`, `responseType`, `withCredentials`, `mimeType`, `timeout`, `header`, `reload`, `cacheAsset`, `cacheEnabled`,

    * Please DO NOT use these words as custom options!

    *

    * !#zh

    * 通用加载资源接口,可传入进度回调以及完成回调,通过组合 `request` 和 `options` 参数,几乎可以实现和扩展所有想要的加载效果。非常建议你使用更简单的API,例如 `load`、`loadDir` 等。

    * `options` 中的自定义参数将会分发到 `requests` 的每一项中,如果request中已存在同名的参数则以 `requests` 中为准,同时如果有其他

    * 依赖资源,则 `options` 中的参数会继续向依赖项中分发。request中的自定义参数都会以 `options` 形式传入加载流程中的 `downloader`, `parser` 的方法中, 你可以

    * 扩展 `downloader`, `parser` 收集参数完成想实现的效果。

    *

    * 保留关键字: `uuid`, `url`, `path`, `dir`, `scene`, `type`, `priority`, `preset`, `audioLoadMode`, `ext`, `bundle`, `onFileProgress`, `maxConcurrency`, `maxRequestsPerFrame`

    * `maxRetryCount`, `version`, `responseType`, `withCredentials`, `mimeType`, `timeout`, `header`, `reload`, `cacheAsset`, `cacheEnabled`,

    * 请不要使用这些字段为自定义参数!

    *

    * @method loadAny

    * @param {string|string[]|Object|Object[]} requests - The request you want to load

    * @param {Object} [options] - Optional parameters

    * @param {Function} [onProgress] - Callback invoked when progression change

    * @param {Number} onProgress.finished - The number of the items that are already completed

    * @param {Number} onProgress.total - The total number of the items

    * @param {RequestItem} onProgress.item - The current request item

    * @param {Function} [onComplete] - Callback invoked when finish loading

    * @param {Error} onComplete.err - The error occured in loading process.

    * @param {Object} onComplete.data - The loaded content

    *

    * @example

    * cc.assetManager.loadAny({url: 'http://example.com/a.png'}, (err, img) => cc.log(img));

    * cc.assetManager.loadAny(['60sVXiTH1D/6Aft4MRt9VC'], (err, assets) => cc.log(assets));

    * cc.assetManager.loadAny([{ uuid: '0cbZa5Y71CTZAccaIFluuZ'}, {url: 'http://example.com/a.png'}], (err, assets) => cc.log(assets));

    * cc.assetManager.downloader.register('.asset', (url, options, onComplete) => {

    *      url += '?userName=' + options.userName + "&password=" + options.password;

    *      cc.assetManager.downloader.downloadFile(url, null, onComplete);

    * });

    * cc.assetManager.parser.register('.asset', (file, options, onComplete) => {

    *      var json = JSON.parse(file);

    *      var skin = json[options.skin];

    *      var model = json[options.model];

    *      onComplete(null, {skin, model});

    * });

    * cc.assetManager.loadAny({ url: 'http://example.com/my.asset', skin: 'xxx', model: 'xxx', userName: 'xxx', password: 'xxx' });

    *

    * @typescript

    * loadAny(requests: string | string[] | Record<string, any> | Record<string, any>[], options: Record<string, any>, onProgress: (finished: number, total: number, item: cc.AssetManager.RequestItem) => void, onComplete: (err: Error, data: any) => void): void

    * loadAny(requests: string | string[] | Record<string, any> | Record<string, any>[], options: Record<string, any>, onComplete: (err: Error, data: any) => void): void

    * loadAny(requests: string | string[] | Record<string, any> | Record<string, any>[], options: Record<string, any>): void

    * loadAny(requests: string | string[] | Record<string, any> | Record<string, any>[], onProgress: (finished: number, total: number, item: cc.AssetManager.RequestItem) => void, onComplete: (err: Error, data: any) => void): void

    * loadAny(requests: string | string[] | Record<string, any> | Record<string, any>[], onComplete: (err: Error, data: any) => void): void

    * loadAny(requests: string | string[] | Record<string, any> | Record<string, any>[]): void

    */

    /*

    requests参数: load任务的源

    eg:load插件script的时候这里就是个array

    [

    "/plugins/ccservices-scripts/cocos-analytics-init.js",

    "/plugins/ccservices-scripts/cocosAnalytics.min.2.2.1.js",

    "/plugins/assets/script/Lib/news.js"

    ]

    option: {preset: "script"__requestType__:"url"}

    */

    loadAny (requests, options, onProgress, onComplete) {

        var { options, onProgress, onComplete } = parseParameters(options, onProgress, onComplete);


        options.preset = options.preset || 'default';//加载的类型 比如uid url dir path

        //新建一个任务,

        let task = new Task({input: requests, onProgress, onComplete: asyncify(onComplete), options});

    //    添加到normal任务管线 【一共三个管线,这个是normal】,异步执行任务

        pipeline.async(task);//pipeline里面的pipes数组 有具体的pipe,

    },

    /**

    * !#en

    * General interface used to preload assets with a progression callback and a complete callback.It is highly recommended that you use more simple API, such as `preloadRes`, `preloadResDir` etc.

    * Everything about preload is just likes `cc.assetManager.loadAny`, the difference is `cc.assetManager.preloadAny` will only download asset but not parse asset. You need to invoke `cc.assetManager.loadAny(preloadTask)`

    * to finish loading asset

    *

    * !#zh

    * 通用预加载资源接口,可传入进度回调以及完成回调,非常建议你使用更简单的 API ,例如 `preloadRes`, `preloadResDir` 等。`preloadAny` 和 `loadAny` 几乎一样,区别在于 `preloadAny` 只会下载资源,不会去解析资源,你需要调用 `cc.assetManager.loadAny(preloadTask)`

    * 来完成资源加载。

    *

    * @method preloadAny

    * @param {string|string[]|Object|Object[]} requests - The request you want to preload

    * @param {Object} [options] - Optional parameters

    * @param {Function} [onProgress] - Callback invoked when progression change

    * @param {Number} onProgress.finished - The number of the items that are already completed

    * @param {Number} onProgress.total - The total number of the items

    * @param {RequestItem} onProgress.item - The current request item

    * @param {Function} [onComplete] - Callback invoked when finish preloading

    * @param {Error} onComplete.err - The error occured in preloading process.

    * @param {RequestItem[]} onComplete.items - The preloaded content

    *

    * @example

    * cc.assetManager.preloadAny('0cbZa5Y71CTZAccaIFluuZ', (err) => cc.assetManager.loadAny('0cbZa5Y71CTZAccaIFluuZ'));

    *

    * @typescript

    * preloadAny(requests: string | string[] | Record<string, any> | Record<string, any>[], options: Record<string, any>, onProgress: (finished: number, total: number, item: cc.AssetManager.RequestItem) => void, onComplete: (err: Error, items: cc.AssetManager.RequestItem[]) => void): void

    * preloadAny(requests: string | string[] | Record<string, any> | Record<string, any>[], options: Record<string, any>, onComplete: (err: Error, items: cc.AssetManager.RequestItem[]) => void): void

    * preloadAny(requests: string | string[] | Record<string, any> | Record<string, any>[], onProgress: (finished: number, total: number, item: cc.AssetManager.RequestItem) => void, onComplete: (err: Error, items: cc.AssetManager.RequestItem[]) => void): void

    * preloadAny(requests: string | string[] | Record<string, any> | Record<string, any>[], onComplete: (err: Error, items: cc.AssetManager.RequestItem[]) => void): void

    * preloadAny(requests: string | string[] | Record<string, any> | Record<string, any>[], options: Record<string, any>): void

    * preloadAny(requests: string | string[] | Record<string, any> | Record<string, any>[]): void

    */

    preloadAny (requests, options, onProgress, onComplete) {

        var { options, onProgress, onComplete } = parseParameters(options, onProgress, onComplete);


        options.preset = options.preset || 'preload';

        var task = new Task({input: requests, onProgress, onComplete: asyncify(onComplete), options});

        fetchPipeline.async(task);

    },

    /**

    * !#en

    * Load native file of asset, if you check the option 'Async Load Assets', you may need to load native file with this before you use the asset

    *

    * !#zh

    * 加载资源的原生文件,如果你勾选了'延迟加载资源'选项,你可能需要在使用资源之前调用此方法来加载原生文件

    *

    * @method postLoadNative

    * @param {Asset} asset - The asset

    * @param {Object} [options] - Some optional parameters

    * @param {Function} [onComplete] - Callback invoked when finish loading

    * @param {Error} onComplete.err - The error occured in loading process.

    *

    * @example

    * cc.assetManager.postLoadNative(texture, (err) => console.log(err));

    *

    * @typescript

    * postLoadNative(asset: cc.Asset, options: Record<string, any>, onComplete: (err: Error) => void): void

    * postLoadNative(asset: cc.Asset, options: Record<string, any>): void

    * postLoadNative(asset: cc.Asset, onComplete: (err: Error) => void): void

    * postLoadNative(asset: cc.Asset): void

    */

    postLoadNative (asset, options, onComplete) {

        if (!(asset instanceof cc.Asset)) throw new Error('input is not asset');

        var { options, onComplete } = parseParameters(options, undefined, onComplete);

        if (!asset._native || asset._nativeAsset) {

            return asyncify(onComplete)(null);

        }

        var depend = dependUtil.getNativeDep(asset._uuid);

        if (depend) {

            if (!bundles.has(depend.bundle)) {

                var bundle = bundles.find(function (bundle) {

                    return bundle.getAssetInfo(asset._uuid);

                });

                if (bundle) {

                    depend.bundle = bundle.name;

                }

            }


            this.loadAny(depend, options, function (err, native) {

                if (!err) {

                    !asset._nativeAsset && (asset._nativeAsset = native);

                }

                else {

                    cc.error(err.message, err.stack);

                }

                onComplete && onComplete(err);

            });

        }

    },

    /**

    * !#en

    * Load remote asset with url, such as audio, image, text and so on.

    *

    * !#zh

    * 使用 url 加载远程资源,例如音频,图片,文本等等。

    *

    * @method loadRemote

    * @param {string} url - The url of asset

    * @param {Object} [options] - Some optional parameters

    * @param {cc.AudioClip.LoadMode} [options.audioLoadMode] - Indicate which mode audio you want to load

    * @param {Function} [onComplete] - Callback invoked when finish loading

    * @param {Error} onComplete.err - The error occured in loading process.

    * @param {Asset} onComplete.asset - The loaded texture

    *

    * @example

    * cc.assetManager.loadRemote('http://www.cloud.com/test1.jpg', (err, texture) => console.log(err));

    * cc.assetManager.loadRemote('http://www.cloud.com/test2.mp3', (err, audioClip) => console.log(err));

    *

    * @typescript

    * loadRemote<T extends cc.Asset>(url: string, options: Record<string, any>, onComplete: (err: Error, asset: T) => void): void

    * loadRemote<T extends cc.Asset>(url: string, options: Record<string, any>): void

    * loadRemote<T extends cc.Asset>(url: string, onComplete: (err: Error, asset: T) => void): void

    * loadRemote<T extends cc.Asset>(url: string): void

    */

    loadRemote (url, options, onComplete) {

        var { options, onComplete } = parseParameters(options, undefined, onComplete);

        options.__isNative__ = true;

        options.preset = options.preset || 'remote';

        this.loadAny({url}, options, null, function (err, data) {

            if (err) {

                cc.error(err.message, err.stack);

                onComplete && onComplete(err, null);

            }

            else {

                factory.create(url, data, options.ext || cc.path.extname(url), options, onComplete);

            }

        });

    },

    /**

    * !#en

    * Load script

    *

    * !#zh

    * 加载脚本

    *

    * @method loadScript

    * @param {string|string[]} url - Url of the script

    * @param {Object} [options] - Some optional paramters

    * @param {boolean} [options.isAsync] - Indicate whether or not loading process should be async

    * @param {Function} [onComplete] - Callback when script loaded or failed

    * @param {Error} onComplete.err - The occurred error, null indicetes success

    *

    * @example

    * loadScript('http://localhost:8080/index.js', null, (err) => console.log(err));

    *

    * @typescript

    * loadScript(url: string|string[], options: Record<string, any>, onComplete: (err: Error) => void): void;

    * loadScript(url: string|string[], options: Record<string, any>): void;

    * loadScript(url: string|string[], onComplete: (err: Error) => void): void;

    * loadScript(url: string|string[]): void;

    */

    /*

    eg:url 是个string 数组

    [

    "/plugins/ccservices-scripts/cocos-analytics-init.js",

    "/plugins/ccservices-scripts/cocosAnalytics.min.2.2.1.js",

    "/plugins/assets/script/Lib/news.js"

    ]

    options 是cb

    onComplete 是 undefined

    */

    loadScript (url, options, onComplete) {

        /*

        交换参数,当第二个参数不是progress func的时候重新定义obj进行交叉互换

        */

        var { options, onComplete } = parseParameters(options, undefined, onComplete);

        /*

        执行转换后 options为一个空对象了,onComplete 变成了cb,传入的第二个参数 */

        options.__requestType__ = RequestType.URL;//静态变量 'url'

        options.preset = options.preset || 'script';

        this.loadAny(url, options, onComplete);

    },

    /**

    * !#en

    * load bundle

    *

    * !#zh

    * 加载资源包

    *

    * @method loadBundle

    * @param {string} nameOrUrl - The name or root path of bundle

    * @param {Object} [options] - Some optional paramter, same like downloader.downloadFile

    * @param {string} [options.version] - The version of this bundle, you can check config.json in this bundle

    * @param {Function} [onComplete] - Callback when bundle loaded or failed

    * @param {Error} onComplete.err - The occurred error, null indicetes success

    * @param {Bundle} onComplete.bundle - The loaded bundle

    *

    * @example

    * loadBundle('http://localhost:8080/test', null, (err, bundle) => console.log(err));

    *

    * @typescript

    * loadBundle(nameOrUrl: string, options: Record<string, any>, onComplete: (err: Error, bundle: cc.AssetManager.Bundle) => void): void

    * loadBundle(nameOrUrl: string, options: Record<string, any>): void

    * loadBundle(nameOrUrl: string, onComplete: (err: Error, bundle: cc.AssetManager.Bundle) => void): void

    * loadBundle(nameOrUrl: string): void

    */

    loadBundle (nameOrUrl, options, onComplete) {

        var { options, onComplete } = parseParameters(options, undefined, onComplete);

        let bundleName = cc.path.basename(nameOrUrl);

        if (this.bundles.has(bundleName)) {

            return asyncify(onComplete)(null, this.getBundle(bundleName));

        }

        options.preset = options.preset || 'bundle';

        options.ext = 'bundle';

        this.loadRemote(nameOrUrl, options, onComplete);

    },

    /**

    * !#en

    * Release asset and it's dependencies.

    * This method will not only remove the cache of the asset in assetManager, but also clean up its content.

    * For example, if you release a texture, the texture asset and its gl texture data will be freed up.

    * Notice, this method may cause the texture to be unusable, if there are still other nodes use the same texture, they may turn to black and report gl errors.

    *

    * !#zh

    * 释放资源以及其依赖资源, 这个方法不仅会从 assetManager 中删除资源的缓存引用,还会清理它的资源内容。

    * 比如说,当你释放一个 texture 资源,这个 texture 和它的 gl 贴图数据都会被释放。

    * 注意,这个函数可能会导致资源贴图或资源所依赖的贴图不可用,如果场景中存在节点仍然依赖同样的贴图,它们可能会变黑并报 GL 错误。

    *

    * @method releaseAsset

    * @param {Asset} asset - The asset to be released

    *

    * @example

    * // release a texture which is no longer need

    * cc.assetManager.releaseAsset(texture);

    *

    * @typescript

    * releaseAsset(asset: cc.Asset): void

    */

    releaseAsset (asset) {

        releaseManager.tryRelease(asset, true);

    },

    /**

    * !#en

    * Release all unused assets. Refer to {{#crossLink "AssetManager/releaseAsset:method"}}{{/crossLink}} for detailed informations.

    *

    * !#zh

    * 释放所有没有用到的资源。详细信息请参考 {{#crossLink "AssetManager/releaseAsset:method"}}{{/crossLink}}

    *

    * @method releaseUnusedAssets

    * @private

    *

    * @typescript

    * releaseUnusedAssets(): void

    */

    releaseUnusedAssets () {

        assets.forEach(function (asset) {

            releaseManager.tryRelease(asset);

        });

    },

    /**

    * !#en

    * Release all assets. Refer to {{#crossLink "AssetManager/releaseAsset:method"}}{{/crossLink}} for detailed informations.

    *

    * !#zh

    * 释放所有资源。详细信息请参考 {{#crossLink "AssetManager/releaseAsset:method"}}{{/crossLink}}

    *

    * @method releaseAll

    *

    * @typescript

    * releaseAll(): void

    */

    releaseAll () {

        assets.forEach(function (asset) {

            releaseManager.tryRelease(asset, true);

        });

    },

    _transform (input, options) {

        var subTask = Task.create({input, options});

        var urls = [];

        try {

            var result = transformPipeline.sync(subTask);

            for (var i = 0, l = result.length; i < l; i++) {

                var item = result[i];

                var url = item.url;

                item.recycle();

                urls.push(url);

            }

        }

        catch (e) {

            for (var i = 0, l = subTask.output.length; i < l; i++) {

                subTask.output[i].recycle();

            }

            cc.error(e.message, e.stack);

        }

        subTask.recycle();

        return urls.length > 1 ? urls : urls[0];

    }

};

cc.AssetManager = AssetManager;

/**

* @module cc

*/

/**

* @property assetManager

* @type {AssetManager}

*/

cc.assetManager = new AssetManager();

/*

看下面定义,

cc.resources 和 cc.assetManager.resources 等价

*/

Object.defineProperty(cc, 'resources', {

    /**

    * !#en

    * cc.resources is a bundle and controls all asset under assets/resources

    *

    * !#zh

    * cc.resources 是一个 bundle,用于管理所有在 assets/resources 下的资源

    *

    * @property resources

    * @readonly

    * @type {AssetManager.Bundle}

    */

    get () {

        return bundles.get(BuiltinBundleName.RESOURCES);//获取到的是 resources目录针对的bundle对象

    }

});

module.exports = cc.assetManager;

/**

* !#en

* This module controls asset's behaviors and information, include loading, releasing etc.

* All member can be accessed with `cc.assetManager`. All class or enum can be accessed with `cc.AssetManager`

*

* !#zh

* 此模块管理资源的行为和信息,包括加载,释放等,所有成员能够通过 `cc.assetManager` 调用. 所有类型或枚举能通过 `cc.AssetManager` 访问

*

* @module cc.AssetManager

*/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容