"use strict"; cc._RF.push(module, 'd22c81wFEpPQq3vcJUA0bsW', 'loadermanager'); // Scripts/common/loadermanager.js "use strict"; // -------------------------------------------------------------------- // @author: shiraho@syg.com(必填, 创建模块的人员) // @description: // 加载资源控制器,到时候直接修改这边就好了 //
Create: new Date().toISOString() // -------------------------------------------------------------------- var FileInfo = require("fileinfo"); var ZipLoader = require("ZipLoader"); var PathTool = require("pathtool"); var DownloadManager = require("downloadmanager"); var SpineLoadingItem = require("spine_loading_item"); window.LoaderManager = cc.Class({ properties: { // 当前拥有资源管理 resources_list: { "default": {} }, //当前已加载数据 data_list: { "default": {} }, // 界面资源管理 reference_key_counter: { // 界面资源计数 "default": {} }, skeleton_counter: { // 动画计数 "default": {} }, spine_counter: { "default": {} }, release_sqe: { "default": {} }, loading_spines: { "default": {} }, _sprite_frame_cache: { "default": {} }, _prefab_time: 0, is_loading: false }, ctor: function ctor() { this.mainloop_timer = gcore.Timer.set(function () { this.update(1); }.bind(this), 1000, -1); }, statics: { instance: null }, update: function update(dt) { this._prefab_time += 1; if (this._prefab_time >= 60) { if (!this.is_loading) { cc.log("开始释放没用的预设资源"); this.clearRes(); this._prefab_time = 0; } } // for (var resi in this.release_sqe) { // this.release_sqe[resi] -= dt; // if (this.release_sqe[resi] < 0) { // this.releseSpienRes(resi); // delete this.release_sqe[resi]; // } // } }, // 加载资源,比如预制体类的,带上路径后缀,例如:预设体就是.prefab,图集就是.plist,图片就是.png或者.jpg等 loadRes: function loadRes(path, callback) { if (path == null) { return; } var loadInfo = this.getResInfo(path); switch (loadInfo.load_type) { case cc.Prefab: this.loadPrefab(loadInfo.str_key, callback); break; case cc.SpriteAtlas: this.loadAtlas(loadInfo.str_key, callback); break; case sp.SkeletonData: this.loadSpine(loadInfo.str_key, callback); break; default: { this.loadUsuallyRes(loadInfo.str_key, callback, loadInfo.load_type); } } }, releaseRes: function releaseRes(path) { if (path == null) { return; } var loadInfo = this.getResInfo(path); switch (loadInfo.load_type) { case cc.Prefab: this.releasePrefab(loadInfo.str_key); break; case cc.SpriteAtlas: this.releaseAtlas(loadInfo.str_key); break; case sp.SkeletonData: this.releaseSpine(loadInfo.str_key); break; default: { this.releaseUsuallyRes(loadInfo.str_key, loadInfo.load_type); } } }, loadUsuallyRes: function loadUsuallyRes(path, callback, load_type) { // 动态加载界面资源 // gcore.Timer.set(function(path, callback, load_type) { if (path.indexOf("ui_res") > -1) { this.is_loading = true; cc.loader.loadRes(path, load_type, function (path, errorMessage, resObject) { if (!errorMessage && resObject) { var deps = cc.loader.getDependsRecursively(resObject); for (var dep_i in deps) { this.countReference(deps[dep_i]); } callback(resObject); } else { cc.error(errorMessage, "load usuallyRes faild--->" + path); } this.is_loading = false; }.bind(this, path)); return; } if (this._sprite_frame_cache[path]) { callback(this._sprite_frame_cache[path]); return; } if (this.resources_list[path] && this.resources_list[path]["obj"]) { this.resources_list[path]["count"]++; callback(this.resources_list[path]["obj"]); return; } cc.loader.loadRes(path, load_type, function (path, errorMessage, resObject) { if (!errorMessage) { if (!this.resources_list[path]) { this.resources_list[path] = {}; this.resources_list[path]["obj"] = resObject; this.resources_list[path]["count"] = 0; } this.resources_list[path]["count"]++; callback(resObject); } else { cc.error(errorMessage, "load usuallyRes faild--->" + path); } }.bind(this, path)); // }.bind(this, path, callback, load_type), 50, 1) }, releaseUsuallyRes: function releaseUsuallyRes(path, res_type) { if (this._sprite_frame_cache[path]) { return; } if (path.indexOf("ui_res") > -1) { // var res_obj = cc.loader.getRes(path, res_type); // if (res_obj) { // var deps = cc.loader.getDependsRecursively(res_obj); // for (var dep_i in deps) { // this.countReference(deps[dep_i], -1); // } // } return; } if (this.resources_list[path]) { --this.resources_list[path]["count"]; // if (this.resources_list[path]["count"] <= 0) { // var releay_res = cc.loader.getDependsRecursively(this.resources_list[path]["obj"]); // cc.loader.release(releay_res); // delete this.resources_list[path]; // } } }, // 资源图集可以被加载很多次,但释放只需要一次就可以释放 loadAtlas: function loadAtlas(path, callback) { var atlasObj = cc.loader.getRes(path, cc.SpriteAtlas); if (atlasObj) { this.countReference(atlasObj); callback(atlasObj); return; } cc.loader.loadRes(path, cc.SpriteAtlas, function (path, err, atlsObj) { if (path) { for (var path_i in cacheAtlas) { if (cacheAtlas[path_i] == path) { var spriteFramas = atlsObj.getSpriteFrames(); for (var item_i in spriteFramas) { var spriteFrame = spriteFramas[item_i]; var itemn_path = "res/item/" + spriteFrame.name; this._sprite_frame_cache[itemn_path] = spriteFrame; } break; } } } if (!err && callback) { this.countReference(atlsObj); callback(atlsObj); } else { cc.error(err, "load preafa faild--->" + path); } }.bind(this, path)); }, releaseAtlas: function releaseAtlas(path) { var atlasObj = cc.loader.getRes(path); if (atlasObj) { this.countReference(atlasObj, -1); } }, // 加载spine资源 loadSpine: function loadSpine(spinePath, callback) { if (!spinePath) return; if (window.OUT_SPINE) { var spine_infos = spinePath.split("/"); var action = spine_infos.pop(); var anima_id = spine_infos.pop(); var loadItem = new SpineLoadingItem(anima_id, action, callback); } else { if (this.release_sqe[spinePath]) { delete this.release_sqe[spinePath]; this.spine_counter[spinePath] = 0; } if (!this.loading_spines[spinePath]) this.loading_spines[spinePath] = true; cc.loader.loadRes(spinePath, sp.SkeletonData, function (spinePath, error, resObject) { if (!error) { if (this.spine_counter[spinePath] > 0) { this.spine_counter[spinePath] += 1; } else { this.spine_counter[spinePath] = 1; } callback(resObject); if (this.loading_spines[spinePath]) delete this.loading_spines[spinePath]; } else { callback(); cc.error(error, "load spine faild--->" + spinePath); } }.bind(this, spinePath)); } }, // 释放spine资源 releaseSpine: function releaseSpine(spinePath) { return; if (!spinePath) return; if (this.spine_counter[spinePath] === undefined) { return; } if (this.spine_counter[spinePath] > 0) --this.spine_counter[spinePath]; if (this.spine_counter[spinePath] > 0) return; this.releseSpienRes(spinePath); }, delteSpine: function delteSpine(spinePath) { this.releseSpienRes(spinePath); }, releseSpienRes: function releseSpienRes(spinePath) { if (!this.loading_spines[spinePath]) { var skeleton_data = cc.loader.getRes(spinePath, sp.SkeletonData); var atlas_data = cc.loader.getRes(spinePath, cc.SpriteAtlas); if (skeleton_data) { var deps = cc.loader.getDependsRecursively(skeleton_data); for (var deps_i in deps) { var depsData = cc.loader.getRes(deps[deps_i]); cc.loader.release(depsData); } cc.loader.release(skeleton_data); } } }, /** * 基于参考key的引用计数 * @author zhanghuxing 2018-12-20 * @param asset 资源对象 * @param count 数量 * @return {[type]} */ countReference: function countReference(assetOrKey, count) { if (!assetOrKey) return; count = count === undefined ? 1 : count; var referenceKey; // if (assetOrKey instanceof cc.Asset) { // referenceKey = cc.loader._getReferenceKey(assetOrKey); // if (assetOrKey instanceof cc.SpriteAtlas) { // var dependes = cc.loader.getDependsRecursively(assetOrKey); // for (var keyIndex in dependes) { // this.countReference(dependes[keyIndex], count); // } // } // } else { referenceKey = assetOrKey; // } if (!this.reference_key_counter[referenceKey]) this.reference_key_counter[referenceKey] = 0; this.reference_key_counter[referenceKey] += count; // if (this.reference_key_counter[referenceKey] <= 0) { // // 释放png资源 // cc.loader.release(referenceKey); // } }, clearRes: function clearRes() { for (var res_key in this.reference_key_counter) { if (!this.reference_key_counter[res_key]) this.reference_key_counter[res_key] = 0; if (this.reference_key_counter[res_key] <= 0) { // 释放png资源 cc.loader.release(res_key); delete this.reference_key_counter[res_key]; } } for (var res_i in this.resources_list) { if (this.resources_list[res_i]["count"] <= 0) { var releay_res = cc.loader.getDependsRecursively(this.resources_list[res_i]["obj"]); cc.loader.release(releay_res); delete this.resources_list[res_i]; } } }, releaseByReferenceKey: function releaseByReferenceKey(referenceKey) {}, // 加载预制资源 loadPrefab: function loadPrefab(path, callback) { if (!window.PREFAB_BUILD) { CC_SUPPORT_JIT = false; this.is_loading = true; cc.loader.loadRes(path, cc.Prefab, function (err, prefab) { CC_SUPPORT_JIT = true; if (!err) { if (callback && !game.preload_loading || path == "prefab/drama/guide_main_view") { var deps = cc.loader.getDependsRecursively(prefab); for (var resIndex in deps) { // var testAsset = cc.loader.getRes(deps[resIndex]); this.countReference(deps[resIndex]); } callback(cc.instantiate(prefab)); } } else { if (callback) callback(); cc.error(err, "load preafa faild--->" + path); } this.is_loading = false; }.bind(this)); } else { var preafab_info = path.split("/"); var prefab_name = preafab_info.pop() + "_p"; var total_name = preafab_info.pop() + "_" + prefab_name; cc.loader.loadRes("prefabjs/" + total_name, cc.JsonAsset, function (total_name, err, text_data) { var testJS = require(total_name); var testObj = new testJS(text_data.json); // testObj.node.x = this.rootNd.width * 0.5; // testObj.node.y = this.rootNd.height * 0.5; callback(testObj.node); }.bind(this, total_name)); } }, // 释放预制资源 releasePrefab: function releasePrefab(path) { var testAsset = cc.loader.getRes(path); var deps = cc.loader.getDependsRecursively(testAsset); for (var resIndex in deps) { var testAsset = cc.loader.getRes(deps[resIndex]); this.countReference(deps[resIndex], -1); } }, // 释放资源 deleteRes: function deleteRes(path) { this.releaseRes(path); // if (this.resources_list[path]) { // var fileInfo = this.resources_list[path]; // fileInfo.decrementLoadNum(); // var loadNum = fileInfo.getLoadNum(); // if (loadNum <= 0){ // cc.loader.releaseRes(fileInfo.url); // fileInfo.deleteMe(); // this.resources_list[path] = null; // } // } }, getResInfo: function getResInfo(path) { // 资源类型的起始位置下表 var type_index = path.indexOf("."); // 字符串总长度 var total_num = path.length; // 剔除字符串类型的路径 var str_key = path.substring(0, type_index); // 资源纹理格式 var assets_type = path.substring(type_index, total_num); // 需要加载的资源格式 var load_type = this.getAssetsTypeSuffix(assets_type); // 后续这里要加上版本信息以及url路径处理 var resulet = {}; resulet.str_key = str_key; resulet.load_type = load_type; return resulet; }, getAssetsTypeSuffix: function getAssetsTypeSuffix(suffix) { switch (suffix) { case ".jpg": case ".png": return cc.SpriteFrame; case ".plist": return cc.SpriteAtlas; case ".mp3": return cc.AudioClip; case ".atlas": return sp.SkeletonData; case ".prefab": return cc.Prefab; } }, initConfigs: function initConfigs(callback) { // var config_zip_url = DATA_URL + "data.zip" + "?" + DATA_VER; // 微信小游戏不使用二进制文件 if (window.DEBUG_Data) { var ModuleInfo = require("modulelist"); var time = gcore.SmartSocket.getTime(); var data_url = "https://dev-h5-sszg.shiyuegame.com/data/"; var total_num = 0; for (var cfg_i = 0; cfg_i < ModuleInfo.data_list.length; cfg_i++) { var totoal_url = data_url + ModuleInfo.data_list[cfg_i] + ".json" + "?time=" + time; cc.loader.load(totoal_url, function (name, err, json_data) { total_num++; if (!err) { Config[name] = json_data; } if (total_num == ModuleInfo.data_list.length) { callback(); } else { callback(total_num / ModuleInfo.data_list.length); } }.bind(this, ModuleInfo.data_list[cfg_i])); } } else { if (PLATFORM_TYPR == "WX_SDK" || PLATFORM_TYPR == "SH_SDK" || PLATFORM_TYPR == "QQ_SDK") { var ModuleInfo = require("modulelist"); var totalNum = ModuleInfo.data_list.length; var finishNum = 0; for (var cfg_i = 0; cfg_i < ModuleInfo.data_list.length; cfg_i++) { var data_path = "data/" + ModuleInfo.data_list[cfg_i]; gcore.Timer.set(function (data_path, cfg_i) { cc.loader.loadRes(data_path, cc.JsonAsset, function (name, err, jsonData) { Config[name] = jsonData.json; finishNum++; cc.log(Config); if (finishNum == totalNum) { callback(); } else { callback(finishNum / totalNum); } }.bind(this, ModuleInfo.data_list[cfg_i])); }.bind(this, data_path, cfg_i), 20 * cfg_i, 1); } } else { ZipLoader.RegisterZipLoader(); var data_path = cc.url.raw("resources/data/data.zip"); cc.loader.load(data_path, function (err, zipData) { var JSZip = require("jszip"); zipData = new JSZip(zipData, { checkCRC32: false }); if (zipData) { var total_num = 0; var cur_num = 0; for (var data_i in zipData.files) { total_num++; gcore.Timer.set(function (data_i, cur_num) { var data = JSON.parse(zipData.files[data_i].asText()); var file_name = data_i.substring(0, data_i.length - 5); Config[file_name] = data; var progress = cur_num / 66; callback(progress); if (cur_num >= total_num && cur_num > 0) { if (callback) callback(); } }.bind(this, data_i, total_num), 20 * total_num, 1); } } }.bind(this)); } } }, initConfigScript: function initConfigScript(finish_cb) { // 发布版本,需要加载合并后json后的JS文件 if (window.USE_MERGE_JSON) { var data_path = "src/merge_json" + (window.PACKAGE_VERSION || "") + ".js"; // var data_path = "src/merge_json" + ".js"; console.log("___json==>", data_path); cc.loader.load(data_path, function (err, data) { if (data) { console.log("加载merge成功"); // console.log(window.ImportConfigs) } if (err) { console.log("加载merge_json失败"); console.log(err); } }); } } }); LoaderManager.getInstance = function () { if (!LoaderManager.instance) { LoaderManager.instance = new LoaderManager(); } return LoaderManager.instance; }; module.exports = LoaderManager; cc._RF.pop();