You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
275 lines
8.8 KiB
275 lines
8.8 KiB
//*********************
|
|
// create by 流云
|
|
// time: 2020.12.18
|
|
// desc: 资源管理器
|
|
//*********************
|
|
import { Asset, assetManager, AssetManager, _decorator } from "cc";
|
|
|
|
const { ccclass } = _decorator;
|
|
|
|
/**
|
|
* 开箱即用资源管理器
|
|
*/
|
|
@ccclass
|
|
export class ResManager {
|
|
|
|
private static _ins: ResManager = null;
|
|
public static get Ins() {
|
|
if (!this._ins) this._ins = new ResManager();
|
|
return this._ins;
|
|
}
|
|
|
|
private _res_map: Map<string, ResRecord> = new Map<string, ResRecord>();
|
|
|
|
getRes({ bundle, path, name, type = Asset, canRelease = true, onComplete = null }) {
|
|
let k = bundle + path + name;
|
|
let res = this._res_map.get(k);
|
|
if (!res) {
|
|
res = new ResRecord();
|
|
this._res_map.set(k, res);
|
|
res.canRelease = canRelease;
|
|
}
|
|
|
|
res.bundle = bundle;
|
|
res.path = path;
|
|
res.name = name;
|
|
|
|
if (!res.res) {
|
|
this.loadBundle(bundle, (b) => {
|
|
this.loadRes(b, path + name, (asset) => {
|
|
res.res = asset;
|
|
//res.res.addRef();
|
|
if (onComplete) { onComplete(res.res); }
|
|
}, type);
|
|
})
|
|
}
|
|
else {
|
|
if (onComplete) { onComplete(res.res); }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 同步获取资源
|
|
* @param bundleName 资源包名称
|
|
* @param path 路径
|
|
* @param resName 名称
|
|
* @param type 类型
|
|
* @param canRelease 是否可释放
|
|
* @returns
|
|
*/
|
|
async getResAsync(bundleName, path, resName, type = Asset, canRelease = true) {
|
|
let k = bundleName + path + resName;
|
|
let res = this._res_map.get(k);
|
|
if (!res) {
|
|
res = new ResRecord();
|
|
this._res_map.set(k, res);
|
|
res.canRelease = canRelease;
|
|
}
|
|
res.bundle = bundleName;
|
|
res.path = path;
|
|
res.name = resName;
|
|
if (!res.res) {
|
|
let b = await this.loadBundle(bundleName);
|
|
if (!b) return null;
|
|
res.res = await this.loadRes(b, path + resName, null, type);
|
|
//if (res.res) res.res.addRef();
|
|
}
|
|
return res.res;
|
|
}
|
|
|
|
/**
|
|
* 预加载bundle
|
|
* @param bundleName bundle名称
|
|
* @param onProgress 进度回调
|
|
* @param onComplete 完成回调
|
|
*/
|
|
preLoadBundle(bundleName, onProgress = null, onComplete = null, path = "/") {
|
|
let bundle = assetManager.getBundle(bundleName);
|
|
if (bundle) {
|
|
bundle.preloadDir(path, onProgress, onComplete);
|
|
return;
|
|
}
|
|
this.loadBundle(bundleName, (b: AssetManager.Bundle) => {
|
|
b.preloadDir(path, onProgress, onComplete);
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 预加载资源包
|
|
* @param resComfArr 资源包数组,例如:
|
|
* [
|
|
* {name:"gameBg",bundle:"game",path:"img/",canRelease:true},
|
|
* {name:"gametitle",bundle:"game",path:"img/",canRelease:true},
|
|
* {name:"gametext",bundle:"game",path:"img/",canRelease:true}
|
|
* ]
|
|
* @param onProgress 加载进度回调
|
|
* @param onComplete 加载完成回调
|
|
*/
|
|
preLoadModeRes(resComfArr, onProgress: Function = null, onComplete: Function = null) {
|
|
try {
|
|
let maxCount = resComfArr.length;
|
|
let curentCount = 0;
|
|
for (let i = 0; i < resComfArr.length; i++) {
|
|
let ritem = resComfArr[i];
|
|
this.loadBundle(ritem.bundle, (b) => {
|
|
this.preLoadRes(b, ritem.path + ritem.name, () => {
|
|
curentCount++;
|
|
if (onProgress) { onProgress(curentCount, maxCount); }
|
|
if (onComplete && curentCount == maxCount) { onComplete(); }
|
|
})
|
|
})
|
|
}
|
|
} catch (error) {
|
|
console.log("预加载模块资源出错", error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 加载资源包
|
|
* @param resComfArr 资源包数组,例如:
|
|
* [
|
|
* {name:"gameBg",bundle:"game",path:"img/",canRelease:true},
|
|
* {name:"gametitle",bundle:"game",path:"img/",canRelease:true},
|
|
* {name:"gametext",bundle:"game",path:"img/",canRelease:true}
|
|
* ]
|
|
* @param onProgress 加载进度回调
|
|
* @param onComplete 加载完成回调
|
|
*/
|
|
loadModeRes(resComfArr, onProgress: Function = null, onComplete: Function = null) {
|
|
try {
|
|
let maxCount = resComfArr.length;
|
|
let curentCount = 0;
|
|
for (let i = 0; i < resComfArr.length; i++) {
|
|
let ritem = resComfArr[i];
|
|
let k = ritem.bundle + ritem.path + ritem.name;
|
|
let r = this._res_map.get(k);
|
|
if (r && r.res && r.res.isValid) {
|
|
curentCount++;
|
|
if (onProgress) { onProgress(curentCount, maxCount); }
|
|
if (onComplete && curentCount == maxCount) { onComplete(); }
|
|
continue;
|
|
}
|
|
if (!r) {
|
|
r = new ResRecord();
|
|
this._res_map.set(k, r);
|
|
}
|
|
r.bundle = ritem.bundle;
|
|
r.canRelease = ritem.canRelease;
|
|
r.key = k;
|
|
r.name = ritem.name;
|
|
r.path = ritem.path;
|
|
this.loadBundle(ritem.bundle, (b) => {
|
|
this.loadRes(b, ritem.path + ritem.name, (res) => {
|
|
r.res = res;
|
|
curentCount++;
|
|
if (onProgress) { onProgress(curentCount, maxCount); }
|
|
if (onComplete && curentCount == maxCount) { onComplete(); }
|
|
})
|
|
})
|
|
}
|
|
} catch (error) {
|
|
console.log("加载模块资源出错", error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 释放单个资源
|
|
* @param bundleName 资源包名
|
|
* @param path 路径
|
|
* @param resName 资源名称
|
|
*/
|
|
releaseRes(bundleName, path, resName) {
|
|
let k = bundleName + path + resName;
|
|
let r = this._res_map.get(k);
|
|
if (r && r.res) {
|
|
r.res.decRef();
|
|
if (r.res.refCount == 0)
|
|
r.res = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 释放模块包资源
|
|
* @param resComfArr 资源模块配置包
|
|
*/
|
|
releaseModeRes(resComfArr) {
|
|
try {
|
|
for (let i = 0; i < resComfArr.length; i++) {
|
|
let item = resComfArr[i];
|
|
this.releaseRes(item.bundle, item.path, item.name);
|
|
}
|
|
} catch (error) {
|
|
console.log("释放资源出错", error);
|
|
}
|
|
}
|
|
|
|
releaseAll() {
|
|
this._res_map.forEach((v, k) => {
|
|
if (v.res && v.canRelease) {
|
|
v.res.decRef();
|
|
if (v.res.refCount == 0) {
|
|
v.res = null;
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
public async loadBundle(bundleName, onComplete: Function = null) {
|
|
return new Promise<AssetManager.Bundle>((resolve, reject) => {
|
|
assetManager.loadBundle(bundleName, (err, bundle) => {
|
|
if (err) {
|
|
console.log(`加载Bundle:${bundleName}错误`, err);
|
|
if (onComplete)
|
|
onComplete(null);
|
|
resolve(null);
|
|
} else {
|
|
if (onComplete)
|
|
onComplete(bundle);
|
|
resolve(bundle);
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
private async loadRes(bundle: AssetManager.Bundle, assetPath, onComplete: Function = null, type = Asset) {
|
|
return new Promise<Asset>((resolve, reject) => {
|
|
bundle.load(assetPath, type, (err, asset) => {
|
|
if (err) {
|
|
console.log(`加载Bundle:${bundle.name},path:${assetPath}资源错误`, err);
|
|
if (onComplete)
|
|
onComplete(null);
|
|
resolve(null);
|
|
} else {
|
|
if (onComplete)
|
|
onComplete(asset);
|
|
resolve(asset);
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
private preLoadRes(bundle: AssetManager.Bundle, assetPath, onComplete: Function = null) {
|
|
console.log(`预加载Bundle:${bundle.name},path:${assetPath}资源开始11111`,bundle);
|
|
bundle.preload(assetPath, (err, asset) => {
|
|
console.log(`预加载Bundle:${bundle.name},path:${assetPath}资源完成`,err,asset);
|
|
if (err) {
|
|
console.log(`预加载Bundle:${bundle.name},path:${assetPath}资源错误`, err);
|
|
if (onComplete)
|
|
onComplete(null);
|
|
} else {
|
|
if (onComplete)
|
|
onComplete(asset);
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
class ResRecord {
|
|
key = ``;
|
|
bundle = ``;
|
|
path = ``;
|
|
name = ``;
|
|
type = Asset;
|
|
res: Asset = null;
|
|
canRelease = true;
|
|
} |