mirror of
https://gitee.com/dgflash/oops-plugin-framework.git
synced 2026-06-03 18:49:23 +08:00
!11 修复音乐资源对象池同一个资源包中资源记录相互覆盖导致,释放音效资源时内存泄漏
Merge pull request !11 from dgflash/develop
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2023-08-28 10:02:57
|
||||
*/
|
||||
import { _decorator, Component, director, Game, game, JsonAsset, Node, screen, sys } from "cc";
|
||||
import { _decorator, Component, director, Game, game, JsonAsset, Node, resources, screen, sys } from "cc";
|
||||
import { GameConfig } from "../module/config/GameConfig";
|
||||
import { GameQueryConfig } from "../module/config/GameQueryConfig";
|
||||
import { oops, version } from "./Oops";
|
||||
@@ -20,8 +20,6 @@ import { LayerManager } from "./gui/layer/LayerManager";
|
||||
|
||||
const { property } = _decorator;
|
||||
|
||||
let isInited = false;
|
||||
|
||||
/** 框架显示层根节点 */
|
||||
export class Root extends Component {
|
||||
/** 游戏层节点 */
|
||||
@@ -42,16 +40,12 @@ export class Root extends Component {
|
||||
private persist: Node = null!
|
||||
|
||||
onLoad() {
|
||||
if (!isInited) {
|
||||
isInited = true; // 注:这里是规避cc3.8在编辑器模式下运行时,关闭游戏会两次初始化报错
|
||||
console.log(`Oops Framework ${version}`);
|
||||
this.enabled = false;
|
||||
|
||||
console.log(`Oops Framework ${version}`);
|
||||
this.enabled = false;
|
||||
|
||||
this.initModule();
|
||||
this.iniStart();
|
||||
this.loadConfig().then();
|
||||
}
|
||||
this.initModule();
|
||||
this.iniStart();
|
||||
this.loadConfig().then();
|
||||
}
|
||||
|
||||
private initModule() {
|
||||
@@ -75,8 +69,12 @@ export class Root extends Component {
|
||||
|
||||
private async loadConfig() {
|
||||
const config_name = "config";
|
||||
const config = await oops.res.loadAsync(config_name, JsonAsset);
|
||||
if (config) {
|
||||
resources.load(config_name, JsonAsset, (err, config) => {
|
||||
if (err) {
|
||||
this.loadConfig().then();
|
||||
return;
|
||||
}
|
||||
|
||||
oops.config.game = new GameConfig(config);
|
||||
|
||||
// 本地存储模块
|
||||
@@ -90,7 +88,6 @@ export class Root extends Component {
|
||||
|
||||
// 设置默认资源包
|
||||
oops.res.defaultBundleName = oops.config.game.bundleDefault;
|
||||
oops.res.init(oops.config.game.data.bundle);
|
||||
|
||||
// 游戏界面管理
|
||||
oops.gui.mobileSafeArea = oops.config.game.mobileSafeArea;
|
||||
@@ -104,11 +101,8 @@ export class Root extends Component {
|
||||
this.init();
|
||||
this.run();
|
||||
|
||||
oops.res.release(config_name);
|
||||
}
|
||||
else {
|
||||
this.loadConfig().then();
|
||||
}
|
||||
resources.release(config_name);
|
||||
});
|
||||
}
|
||||
|
||||
update(dt: number) {
|
||||
|
||||
@@ -35,7 +35,7 @@ export class AudioEffectPool {
|
||||
/** 对象池集合 */
|
||||
private effects: Map<string, AudioEffect> = new Map();
|
||||
/** 用过的音效资源记录 */
|
||||
private res: Map<string, string> = new Map();
|
||||
private res: Map<string, string[]> = new Map();
|
||||
|
||||
private _aeId: number = 0;
|
||||
/** 获取请求唯一编号 */
|
||||
@@ -63,8 +63,16 @@ export class AudioEffectPool {
|
||||
}
|
||||
else {
|
||||
clip = resLoader.get(url, AudioClip, bundleName)!;
|
||||
if (!clip) {
|
||||
this.res.set(bundleName, url);
|
||||
if (clip == null) {
|
||||
let urls = this.res.get(bundleName);
|
||||
if (urls == null) {
|
||||
urls = [];
|
||||
this.res.set(bundleName, urls);
|
||||
urls.push(url);
|
||||
}
|
||||
else if (urls.indexOf(url) == -1) {
|
||||
urls.push(url);
|
||||
}
|
||||
clip = await resLoader.loadAsync(bundleName, url, AudioClip);
|
||||
}
|
||||
}
|
||||
@@ -148,8 +156,8 @@ export class AudioEffectPool {
|
||||
this.effects.clear();
|
||||
|
||||
// 释放音效资源
|
||||
this.res.forEach((url: string, bundleName: string) => {
|
||||
resLoader.release(bundleName, url);
|
||||
this.res.forEach((urls: string[], bundleName: string) => {
|
||||
urls.forEach(url => resLoader.release(bundleName, url));
|
||||
});
|
||||
|
||||
// 释放池中播放器
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Asset, AssetManager, __private, assetManager, error, js, resources, warn } from "cc";
|
||||
import { __private, Asset, AssetManager, assetManager, error, js, resources, warn } from "cc";
|
||||
|
||||
export type AssetType<T = Asset> = __private.__types_globals__Constructor<T> | null;
|
||||
export type Paths = string | string[];
|
||||
@@ -35,8 +35,6 @@ export class ResLoader {
|
||||
//#region 资源配置数据
|
||||
/** 全局默认加载的资源包名 */
|
||||
defaultBundleName: string = "resources";
|
||||
/** 是否使用远程 CDN 资源 */
|
||||
cdn: boolean = false;
|
||||
|
||||
/** 下载时的最大并发数 - 项目设置 -> 项目数据 -> 资源下载并发数,设置默认值;初始值为15 */
|
||||
get maxConcurrency() {
|
||||
@@ -70,17 +68,6 @@ export class ResLoader {
|
||||
assetManager.downloader.retryInterval = value;
|
||||
}
|
||||
|
||||
/** 资源包配置 */
|
||||
private bundles: Map<string, string> = new Map<string, string>();
|
||||
//#endregion
|
||||
|
||||
init(config: any) {
|
||||
this.cdn = config.enable;
|
||||
for (let bundleName in config.packages) {
|
||||
this.bundles.set(bundleName, config.packages[bundleName]);
|
||||
}
|
||||
}
|
||||
|
||||
//#region 加载远程资源
|
||||
/**
|
||||
* 加载远程资源
|
||||
@@ -120,16 +107,13 @@ oops.res.loadRemote<ImageAsset>(this.url, opt, onComplete);
|
||||
//#region 资源包管理
|
||||
/**
|
||||
* 加载资源包
|
||||
* @param url 资源地址
|
||||
* @param v 资源MD5版本号
|
||||
* @param name 资源地址
|
||||
* @example
|
||||
var serverUrl = "http://192.168.1.8:8080/"; // 服务器地址
|
||||
var md5 = "8e5c0"; // Cocos Creator 构建后的MD5字符
|
||||
await oops.res.loadBundle(serverUrl,md5);
|
||||
await oops.res.loadBundle(name);
|
||||
*/
|
||||
loadBundle(url: string, v?: string) {
|
||||
loadBundle(name: string) {
|
||||
return new Promise<AssetManager.Bundle>((resolve, reject) => {
|
||||
assetManager.loadBundle(url, { version: v }, (err, bundle: AssetManager.Bundle) => {
|
||||
assetManager.loadBundle(name, (err, bundle: AssetManager.Bundle) => {
|
||||
if (err) {
|
||||
return error(err);
|
||||
}
|
||||
@@ -366,7 +350,7 @@ oops.res.loadDir("game", onProgressCallback, onCompleteCallback);
|
||||
*/
|
||||
release(path: string, bundleName?: string) {
|
||||
if (bundleName == undefined) bundleName = this.defaultBundleName;
|
||||
|
||||
|
||||
const bundle = assetManager.getBundle(bundleName);
|
||||
if (bundle) {
|
||||
const asset = bundle.get(path);
|
||||
@@ -483,8 +467,7 @@ oops.res.loadDir("game", onProgressCallback, onCompleteCallback);
|
||||
}
|
||||
// 自动加载资源包
|
||||
else {
|
||||
const v = this.cdn ? this.bundles.get(args.bundle) : "";
|
||||
bundle = await this.loadBundle(args.bundle, v);
|
||||
bundle = await this.loadBundle(args.bundle);
|
||||
if (bundle) this.loadByBundleAndArgs(bundle, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* @LastEditTime: 2022-09-02 13:44:12
|
||||
*/
|
||||
import { BlockInputEvents, Layers, Node, Widget, instantiate } from "cc";
|
||||
import { EDITOR } from "cc/env";
|
||||
import { ViewUtil } from "../../utils/ViewUtil";
|
||||
import { PromptResType } from "../GuiEnum";
|
||||
import { Notify } from "../prompt/Notify";
|
||||
@@ -29,10 +30,7 @@ export class LayerNotify extends Node {
|
||||
widget.left = widget.right = widget.top = widget.bottom = 0;
|
||||
widget.alignMode = 2;
|
||||
widget.enabled = true;
|
||||
this.init();
|
||||
}
|
||||
|
||||
private init() {
|
||||
this.layer = Layers.Enum.UI_2D;
|
||||
this.black = this.addComponent(BlockInputEvents);
|
||||
this.black.enabled = false;
|
||||
@@ -41,9 +39,13 @@ export class LayerNotify extends Node {
|
||||
/** 打开等待提示 */
|
||||
async waitOpen() {
|
||||
if (this.wait == null) {
|
||||
this.wait = ViewUtil.createPrefabNode(PromptResType.Wait);
|
||||
// 兼容编辑器预览模式
|
||||
if (this.wait == null) this.wait = await ViewUtil.createPrefabNodeAsync(PromptResType.Wait);
|
||||
if (EDITOR) {
|
||||
this.wait = await ViewUtil.createPrefabNodeAsync(PromptResType.Wait);
|
||||
}
|
||||
else {
|
||||
this.wait = ViewUtil.createPrefabNode(PromptResType.Wait);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.wait.parent == null) {
|
||||
@@ -67,9 +69,13 @@ export class LayerNotify extends Node {
|
||||
*/
|
||||
async toast(content: string, useI18n: boolean) {
|
||||
if (this.notify == null) {
|
||||
this.notify = ViewUtil.createPrefabNode(PromptResType.Toast);
|
||||
// 兼容编辑器预览模式
|
||||
if (this.notify == null) this.notify = await ViewUtil.createPrefabNodeAsync(PromptResType.Toast);
|
||||
if (EDITOR) {
|
||||
this.notify = await ViewUtil.createPrefabNodeAsync(PromptResType.Toast);
|
||||
}
|
||||
else {
|
||||
this.notify = ViewUtil.createPrefabNode(PromptResType.Toast);
|
||||
}
|
||||
this.notifyItem = this.notify.children[0];
|
||||
this.notifyItem.parent = null;
|
||||
}
|
||||
|
||||
@@ -20,10 +20,7 @@ export class LayerPopUp extends LayerUI {
|
||||
|
||||
constructor(name: string) {
|
||||
super(name);
|
||||
this.init();
|
||||
}
|
||||
|
||||
private init() {
|
||||
|
||||
this.layer = Layers.Enum.UI_2D;
|
||||
this.on(Node.EventType.CHILD_ADDED, this.onChildAdded, this);
|
||||
this.on(Node.EventType.CHILD_REMOVED, this.onChildRemoved, this);
|
||||
|
||||
@@ -30,6 +30,11 @@ export default class LabelTime extends Label {
|
||||
})
|
||||
zeroize: boolean = true;
|
||||
|
||||
@property({
|
||||
tooltip: "游戏进入后台时间暂时",
|
||||
})
|
||||
paused: boolean = false;
|
||||
|
||||
private backStartTime: number = 0; // 进入后台开始时间
|
||||
private dateDisable!: boolean; // 时间能否由天数显示
|
||||
private result!: string; // 时间结果字符串
|
||||
@@ -152,6 +157,11 @@ export default class LabelTime extends Label {
|
||||
}
|
||||
|
||||
private onGameShow() {
|
||||
// 时间到了
|
||||
if (this.countDown <= 0) return;
|
||||
// 时间暂停
|
||||
if (this.paused) return;
|
||||
|
||||
const interval = Math.floor((oops.timer.getTime() - (this.backStartTime || oops.timer.getTime())) / 1000);
|
||||
this.countDown -= interval;
|
||||
if (this.countDown < 0) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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 { ViewUtil } from "../../core/utils/ViewUtil";
|
||||
import { ecs } from "../../libs/ecs/ECS";
|
||||
@@ -60,17 +61,19 @@ export class ModuleUtil {
|
||||
|
||||
/**
|
||||
* 通过资源内存中获取预制上的组件添加到ECS实体中
|
||||
* @param ent 模块实体
|
||||
* @param ctor 界面逻辑组件
|
||||
* @param parent 显示对象父级
|
||||
* @param url 显示资源地址
|
||||
* @param ent 模块实体
|
||||
* @param ctor 界面逻辑组件
|
||||
* @param parent 显示对象父级
|
||||
* @param url 显示资源地址
|
||||
* @param bundleName 资源包名称
|
||||
*/
|
||||
static addView<T extends CCVMParentComp | CCComp>(
|
||||
ent: ecs.Entity,
|
||||
ctor: __private.__types_globals__Constructor<T> | __private.__types_globals__AbstractedConstructor<T>,
|
||||
parent: Node,
|
||||
url: string) {
|
||||
const node = ViewUtil.createPrefabNode(url);
|
||||
url: string,
|
||||
bundleName: string = resLoader.defaultBundleName) {
|
||||
const node = ViewUtil.createPrefabNode(url, bundleName);
|
||||
const comp = node.getComponent(ctor)!;
|
||||
ent.add(comp);
|
||||
node.parent = parent;
|
||||
|
||||
Reference in New Issue
Block a user