mirror of
https://gitee.com/dgflash/oops-plugin-framework.git
synced 2026-05-30 18:39:18 +08:00
@@ -157,7 +157,7 @@ export class AudioEffectPool {
|
||||
|
||||
// 释放音效资源
|
||||
this.res.forEach((urls: string[], bundleName: string) => {
|
||||
urls.forEach(url => resLoader.release(bundleName, url));
|
||||
urls.forEach(url => resLoader.release(url, bundleName));
|
||||
});
|
||||
|
||||
// 释放池中播放器
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { __private, Asset, AssetManager, assetManager, error, js, resources, warn } from "cc";
|
||||
import { __private, AnimationClip, Asset, AssetManager, assetManager, AudioClip, error, Font, ImageAsset, js, JsonAsset, Material, Mesh, Prefab, resources, sp, SpriteFrame, Texture2D, warn } from "cc";
|
||||
|
||||
export type AssetType<T = Asset> = __private.__types_globals__Constructor<T> | null;
|
||||
export type Paths = string | string[];
|
||||
@@ -105,6 +105,15 @@ oops.res.loadRemote<ImageAsset>(this.url, opt, onComplete);
|
||||
//#endregion
|
||||
|
||||
//#region 资源包管理
|
||||
|
||||
/**
|
||||
* 获取资源包
|
||||
* @param name 资源包名
|
||||
*/
|
||||
getBundle(name: string) {
|
||||
return assetManager.bundles.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载资源包
|
||||
* @param name 资源地址
|
||||
@@ -355,7 +364,7 @@ oops.res.loadDir("game", onProgressCallback, onCompleteCallback);
|
||||
if (bundle) {
|
||||
const asset = bundle.get(path);
|
||||
if (asset) {
|
||||
this.releasePrefabtDepsRecursively(asset);
|
||||
this.releasePrefabtDepsRecursively(bundleName, asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -371,7 +380,7 @@ oops.res.loadDir("game", onProgressCallback, onCompleteCallback);
|
||||
var infos = bundle.getDirWithPath(path);
|
||||
if (infos) {
|
||||
infos.map((info) => {
|
||||
this.releasePrefabtDepsRecursively(info.uuid);
|
||||
this.releasePrefabtDepsRecursively(bundleName, info.uuid);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -381,21 +390,80 @@ oops.res.loadDir("game", onProgressCallback, onCompleteCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取资源路径
|
||||
* @param bundleName 资源包名
|
||||
* @param uuid 资源唯一编号
|
||||
* @returns
|
||||
*/
|
||||
getAssetPath(bundleName: string, uuid: string): string {
|
||||
let b = this.getBundle(bundleName)!;
|
||||
let info = b.getAssetInfo(uuid)!;
|
||||
//@ts-ignore
|
||||
return info.path;
|
||||
}
|
||||
|
||||
/** 释放预制依赖资源 */
|
||||
private releasePrefabtDepsRecursively(uuid: string | Asset) {
|
||||
private releasePrefabtDepsRecursively(bundleName: string, uuid: string | Asset) {
|
||||
if (uuid instanceof Asset) {
|
||||
uuid.decRef();
|
||||
// assetManager.releaseAsset(uuid);
|
||||
// this.debugLogReleasedAsset(bundleName, uuid);
|
||||
}
|
||||
else {
|
||||
const asset = assetManager.assets.get(uuid);
|
||||
if (asset) {
|
||||
asset.decRef();
|
||||
// assetManager.releaseAsset(asset);
|
||||
// this.debugLogReleasedAsset(bundleName, asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private debugLogReleasedAsset(bundleName: string, asset: Asset) {
|
||||
if (asset.refCount == 0) {
|
||||
let path = this.getAssetPath(bundleName, asset.uuid);
|
||||
let content: string = "";
|
||||
if (asset instanceof JsonAsset) {
|
||||
content = "【释放资源】Json【路径】" + path;
|
||||
}
|
||||
else if (asset instanceof Prefab) {
|
||||
content = "【释放资源】Prefab【路径】" + path;
|
||||
}
|
||||
else if (asset instanceof SpriteFrame) {
|
||||
content = "【释放资源】SpriteFrame【路径】" + path;
|
||||
}
|
||||
else if (asset instanceof Texture2D) {
|
||||
content = "【释放资源】Texture2D【路径】" + path;
|
||||
}
|
||||
else if (asset instanceof ImageAsset) {
|
||||
content = "【释放资源】ImageAsset【路径】" + path;
|
||||
}
|
||||
else if (asset instanceof AudioClip) {
|
||||
content = "【释放资源】AudioClip【路径】" + path;
|
||||
}
|
||||
else if (asset instanceof AnimationClip) {
|
||||
content = "【释放资源】AnimationClip【路径】" + path;
|
||||
}
|
||||
else if (asset instanceof Font) {
|
||||
content = "【释放资源】Font【路径】" + path;
|
||||
}
|
||||
else if (asset instanceof Material) {
|
||||
content = "【释放资源】Material【路径】" + path;
|
||||
}
|
||||
else if (asset instanceof Mesh) {
|
||||
content = "【释放资源】Mesh【路径】" + path;
|
||||
}
|
||||
else if (asset instanceof sp.SkeletonData) {
|
||||
content = "【释放资源】Spine【路径】" + path;
|
||||
}
|
||||
else {
|
||||
content = "【释放资源】未知【路径】" + path;
|
||||
}
|
||||
console.log(content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取资源
|
||||
* @param path 资源路径
|
||||
@@ -480,7 +548,7 @@ oops.res.loadDir("game", onProgressCallback, onCompleteCallback);
|
||||
/** 打印缓存中所有资源信息 */
|
||||
dump() {
|
||||
assetManager.assets.forEach((value: Asset, key: string) => {
|
||||
console.log(assetManager.assets.get(key));
|
||||
console.log(`引用数量:${value.refCount}`, assetManager.assets.get(key));
|
||||
})
|
||||
console.log(`当前资源总数:${assetManager.assets.count}`);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ const EventOnRemoved: string = "onRemoved";
|
||||
export class DelegateComponent extends Component {
|
||||
/** 视图参数 */
|
||||
vp: ViewParams = null!;
|
||||
/** 关闭窗口之前 */
|
||||
onCloseWindowBefore: Function = null!;
|
||||
/** 界面关闭回调 - 包括关闭动画播放完(辅助框架内存业务流程使用) */
|
||||
onCloseWindow: Function = null!;
|
||||
|
||||
@@ -69,6 +71,10 @@ export class DelegateComponent extends Component {
|
||||
|
||||
/** 窗口关闭前动画处理完后的回调方法,主要用于释放资源 */
|
||||
private onBeforeRemoveNext(isDestroy?: boolean) {
|
||||
if (this.onCloseWindowBefore) {
|
||||
this.onCloseWindowBefore();
|
||||
this.onCloseWindowBefore = null!;
|
||||
}
|
||||
this.removed(this.vp, isDestroy);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { __private, native, sys } from "cc";
|
||||
/** 平台数据 */
|
||||
export class PlatformUtil {
|
||||
/** 获取当前设备的网络类型, 如果网络类型无法获取,默认将返回 `sys.NetworkType.LAN` */
|
||||
getNetworkType(): __private._pal_system_info_enum_type_network_type__NetworkType {
|
||||
static getNetworkType(): __private._pal_system_info_enum_type_network_type__NetworkType {
|
||||
return sys.getNetworkType();
|
||||
}
|
||||
|
||||
@@ -16,17 +16,23 @@ export class PlatformUtil {
|
||||
* 获取当前设备的电池电量,如果电量无法获取,默认将返回 1
|
||||
* @return - 0.0 ~ 1.0
|
||||
*/
|
||||
getBatteryLevel(): number {
|
||||
static getBatteryLevel(): number {
|
||||
return sys.getBatteryLevel();
|
||||
}
|
||||
|
||||
/** 尝试打开一个 web 页面,并非在所有平台都有效 */
|
||||
openURL(url: string) {
|
||||
static openURL(url: string) {
|
||||
sys.openURL(url);
|
||||
}
|
||||
|
||||
/** 拷贝字符串到剪切板 */
|
||||
copyText(text: string) {
|
||||
native.copyTextToClipboard(text);
|
||||
static async copyText(text: string) {
|
||||
if (sys.isNative) {
|
||||
native.copyTextToClipboard(text);
|
||||
|
||||
}
|
||||
else {
|
||||
await navigator.clipboard.writeText(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,13 @@ interface ResRecord {
|
||||
bundle: string,
|
||||
/** 资源路径 */
|
||||
path: string,
|
||||
/** 引用计数 */
|
||||
refCount: number,
|
||||
/** 资源编号 */
|
||||
resId?: number
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 游戏显示对象组件模板
|
||||
* 1、当前对象加载的资源,会在对象释放时,自动释放引用的资源
|
||||
@@ -148,8 +151,12 @@ export class GameComponent extends Component {
|
||||
for (let index = 0; index < paths.length; index++) {
|
||||
let realPath = paths[index];
|
||||
let key = this.getResKey(realBundle, realPath, resId);
|
||||
if (!rps.has(key)) {
|
||||
rps.set(key, { path: realPath, bundle: realBundle, resId: resId });
|
||||
let rp = rps.get(key);
|
||||
if (rp) {
|
||||
rp.refCount++;
|
||||
}
|
||||
else {
|
||||
rps.set(key, { path: realPath, bundle: realBundle, refCount: 1, resId: resId });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,16 +164,24 @@ export class GameComponent extends Component {
|
||||
let realBundle = bundleName;
|
||||
let realPath = paths;
|
||||
let key = this.getResKey(realBundle, realPath, resId);
|
||||
if (!rps.has(key)) {
|
||||
rps.set(key, { path: realPath, bundle: realBundle, resId: resId });
|
||||
let rp = rps.get(key);
|
||||
if (rp) {
|
||||
rp.refCount++;
|
||||
}
|
||||
else {
|
||||
rps.set(key, { path: realPath, bundle: realBundle, refCount: 1, resId: resId });
|
||||
}
|
||||
}
|
||||
else {
|
||||
let realBundle = oops.res.defaultBundleName;
|
||||
let realPath = bundleName;
|
||||
let key = this.getResKey(realBundle, realPath, resId);
|
||||
if (!rps.has(key)) {
|
||||
rps.set(key, { path: realPath, bundle: realBundle, resId: resId });
|
||||
let rp = rps.get(key);
|
||||
if (rp) {
|
||||
rp.refCount++;
|
||||
}
|
||||
else {
|
||||
rps.set(key, { path: realPath, bundle: realBundle, refCount: 1, resId: resId });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,7 +280,9 @@ export class GameComponent extends Component {
|
||||
const rps = this.resPaths.get(ResType.Load);
|
||||
if (rps) {
|
||||
rps.forEach((value: ResRecord) => {
|
||||
oops.res.release(value.path, value.bundle);
|
||||
for (let i = 0; i < value.refCount; i++) {
|
||||
oops.res.release(value.path, value.bundle);
|
||||
}
|
||||
});
|
||||
rps.clear();
|
||||
}
|
||||
@@ -290,7 +307,7 @@ export class GameComponent extends Component {
|
||||
const rps = this.resPaths.get(ResType.Audio);
|
||||
if (rps) {
|
||||
rps.forEach((value: ResRecord) => {
|
||||
oops.audio.putEffect(value.resId!, value.path, value.bundle);
|
||||
oops.audio.putEffect(value.resId!, value.path, value.bundle); // 回收音乐效到音效池中等下次使用
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -313,6 +330,7 @@ export class GameComponent extends Component {
|
||||
}
|
||||
return;
|
||||
}
|
||||
spriteFrame.addRef();
|
||||
target.spriteFrame = spriteFrame;
|
||||
}
|
||||
//#endregion
|
||||
@@ -346,16 +364,16 @@ export class GameComponent extends Component {
|
||||
*/
|
||||
async playEffect(url: string, bundleName?: string) {
|
||||
if (bundleName == null) bundleName = oops.res.defaultBundleName;
|
||||
await oops.audio.playEffect(url, bundleName, () => {
|
||||
let resId = await oops.audio.playEffect(url, bundleName, () => {
|
||||
if (!this.isValid) return;
|
||||
|
||||
|
||||
const rps = this.resPaths.get(ResType.Audio);
|
||||
if (rps) {
|
||||
const key = this.getResKey(bundleName, url);
|
||||
rps.delete(key);
|
||||
}
|
||||
});
|
||||
this.addPathToRecord(ResType.Audio, bundleName, url);
|
||||
this.addPathToRecord(ResType.Audio, bundleName, url, resId);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Node, __private } from "cc";
|
||||
import { oops } from "../../core/Oops";
|
||||
import { resLoader } from "../../core/common/loader/ResLoader";
|
||||
import { UICallbacks } from "../../core/gui/layer/Defines";
|
||||
import { DelegateComponent } from "../../core/gui/layer/DelegateComponent";
|
||||
import { ViewUtil } from "../../core/utils/ViewUtil";
|
||||
import { ecs } from "../../libs/ecs/ECS";
|
||||
import { CompType } from "../../libs/ecs/ECSModel";
|
||||
@@ -81,13 +82,43 @@ export class ModuleUtil {
|
||||
|
||||
/**
|
||||
* 业务实体上移除界面组件
|
||||
* @param ent 模块实体
|
||||
* @param ctor 界面逻辑组件
|
||||
* @param uiId 界面资源编号
|
||||
* @param isDestroy 是否释放界面缓存(默认为释放界面缓存)
|
||||
* @param ent 模块实体
|
||||
* @param ctor 界面逻辑组件
|
||||
* @param uiId 界面资源编号
|
||||
* @param isDestroy 是否释放界面缓存(默认为释放界面缓存)
|
||||
* @param onRemoved 窗口关闭完成事件
|
||||
*/
|
||||
static removeViewUi(ent: ecs.Entity, ctor: CompType<ecs.IComp>, uiId: number, isDestroy: boolean = true) {
|
||||
if (isDestroy) ent.remove(ctor, isDestroy);
|
||||
static removeViewUi(ent: ecs.Entity, ctor: CompType<ecs.IComp>, uiId: number, isDestroy: boolean = true, onRemoved?: Function) {
|
||||
const node = oops.gui.get(uiId);
|
||||
if (!node) {
|
||||
if (onRemoved) onRemoved();
|
||||
return;
|
||||
}
|
||||
|
||||
const comp = node.getComponent(DelegateComponent);
|
||||
if (comp) {
|
||||
if (comp.vp.callbacks.onBeforeRemove) {
|
||||
comp.onCloseWindowBefore = () => {
|
||||
ent.remove(ctor, isDestroy);
|
||||
if (onRemoved) onRemoved();
|
||||
};
|
||||
}
|
||||
else if (comp.vp.callbacks.onRemoved) {
|
||||
comp.onCloseWindow = () => {
|
||||
ent.remove(ctor, isDestroy);
|
||||
if (onRemoved) onRemoved();
|
||||
};
|
||||
}
|
||||
else {
|
||||
ent.remove(ctor, isDestroy);
|
||||
if (onRemoved) onRemoved();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ent.remove(ctor, isDestroy);
|
||||
if (onRemoved) onRemoved();
|
||||
}
|
||||
|
||||
oops.gui.remove(uiId, isDestroy);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user