From 41d7fe125c50aa6dd45a03bc8fdbac26d7853b3d Mon Sep 17 00:00:00 2001 From: han_han9 Date: Wed, 29 Oct 2025 07:52:29 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E4=BC=98=E5=8C=96=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/max-studio/core/max.d.ts | 5 ++ .../assets/max-studio/core/max.d.ts.meta | 9 +++ .../max-studio/core/res/RemoteSprite.ts | 46 +++++------- .../max-studio/core/res/RemoteSpriteCache.ts | 71 +++++-------------- 4 files changed, 48 insertions(+), 83 deletions(-) create mode 100644 extensions/max-studio/assets/max-studio/core/max.d.ts create mode 100644 extensions/max-studio/assets/max-studio/core/max.d.ts.meta diff --git a/extensions/max-studio/assets/max-studio/core/max.d.ts b/extensions/max-studio/assets/max-studio/core/max.d.ts new file mode 100644 index 0000000..d37e08e --- /dev/null +++ b/extensions/max-studio/assets/max-studio/core/max.d.ts @@ -0,0 +1,5 @@ +declare module "cc" { + interface SpriteFrame { + remoteUrl?: string; + } +} diff --git a/extensions/max-studio/assets/max-studio/core/max.d.ts.meta b/extensions/max-studio/assets/max-studio/core/max.d.ts.meta new file mode 100644 index 0000000..2f5f700 --- /dev/null +++ b/extensions/max-studio/assets/max-studio/core/max.d.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "22f3e111-a4f8-4e05-aa61-cbea5c1b9cc1", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/extensions/max-studio/assets/max-studio/core/res/RemoteSprite.ts b/extensions/max-studio/assets/max-studio/core/res/RemoteSprite.ts index b49d2f2..82b4563 100644 --- a/extensions/max-studio/assets/max-studio/core/res/RemoteSprite.ts +++ b/extensions/max-studio/assets/max-studio/core/res/RemoteSprite.ts @@ -1,4 +1,4 @@ -import { _decorator, Sprite } from "cc"; +import { _decorator, isValid, Sprite } from "cc"; import { EDITOR } from "cc/env"; import { UITransform } from "cc"; import { StringUtils } from "../utils/StringUtils"; @@ -26,13 +26,13 @@ export default class RemoteSprite extends Sprite { const newValue = value || ""; if (this._remoteUrl !== newValue) { this._remoteUrl = newValue; - if (this._remoteUrl !== this._currentUrl) { + if (StringUtils.isEmpty(this._remoteUrl)) { + this.release(); + return; + } + if (this.spriteFrame == null || this._remoteUrl !== this.spriteFrame.remoteUrl) { this.loadRemoteSprite(this._remoteUrl).catch((err) => { - LogUtils.error( - "RemoteSprite", - `加载远程图片失败: ${this._remoteUrl}`, - err, - ); + LogUtils.error("RemoteSprite", `加载远程图片失败: ${this._remoteUrl}`, err); // 可以添加默认图片或错误状态处理 if (this.isValid) { this.spriteFrame = null; @@ -42,29 +42,18 @@ export default class RemoteSprite extends Sprite { } } - // 私有属性 - private _currentUrl: string = ""; - public onLoad(): void { super.onLoad(); if (EDITOR) { return; } - RemoteSpriteCache.getInstance().checkAndRegisterSprite( - this._currentUrl, - this.spriteFrame, - ); - if ( - !StringUtils.isEmpty(this._remoteUrl) && - StringUtils.isEmpty(this._currentUrl) - ) { + RemoteSpriteCache.getInstance().checkAndRegisterSprite(this.spriteFrame); + if (!StringUtils.isEmpty(this._remoteUrl) && this.spriteFrame?.remoteUrl !== this._remoteUrl) { this.loadRemoteSprite(this._remoteUrl).catch((err) => { - LogUtils.error( - "RemoteSprite", - `onLoad加载远程图片失败: ${this._remoteUrl}`, - err, - ); + LogUtils.error("RemoteSprite", `onLoad加载远程图片失败: ${this._remoteUrl}`, err); }); + } else if (StringUtils.isEmpty(this._remoteUrl) && !StringUtils.isEmpty(this.spriteFrame?.remoteUrl)) { + this.release(); } } @@ -74,21 +63,19 @@ export default class RemoteSprite extends Sprite { } // URL 相同,且已经加载完成,直接返回 - if (this._currentUrl === url && this.spriteFrame) { + if (this.spriteFrame && this.spriteFrame.remoteUrl == url) { return; } this.release(); const sp = await RemoteSpriteCache.getInstance().loadSpriteFrame(url); - // 检查是否在加载过程中URL发生了变化 - if (this._remoteUrl !== url || this._currentUrl === url) { + if (!isValid(this.node, true) || this._remoteUrl !== url || this.spriteFrame?.remoteUrl === url) { RemoteSpriteCache.getInstance().releaseResource(url); return; } this.spriteFrame = sp; - this._currentUrl = url; } public setSize(widthOrHeight: number, height?: number): void { @@ -98,10 +85,9 @@ export default class RemoteSprite extends Sprite { } public release(): void { - if (!StringUtils.isEmpty(this._currentUrl)) { - RemoteSpriteCache.getInstance()?.releaseResource(this._currentUrl); + if (!StringUtils.isEmpty(this.spriteFrame?.remoteUrl)) { + RemoteSpriteCache.getInstance()?.releaseResource(this.spriteFrame.remoteUrl); } - this._currentUrl = ""; this.spriteFrame = null; } diff --git a/extensions/max-studio/assets/max-studio/core/res/RemoteSpriteCache.ts b/extensions/max-studio/assets/max-studio/core/res/RemoteSpriteCache.ts index b7beafb..b8ff4d6 100644 --- a/extensions/max-studio/assets/max-studio/core/res/RemoteSpriteCache.ts +++ b/extensions/max-studio/assets/max-studio/core/res/RemoteSpriteCache.ts @@ -1,10 +1,4 @@ -import { - _decorator, - SpriteFrame, - ImageAsset, - Texture2D, - assetManager, -} from "cc"; +import { _decorator, SpriteFrame, ImageAsset, Texture2D, assetManager } from "cc"; import NodeSingleton from "../NodeSingleton"; import LogUtils from "../utils/LogUtils"; import { StringUtils } from "../utils/StringUtils"; @@ -71,7 +65,7 @@ class CacheItem { const TAG = "RemoteSpriteCache"; const CLEANUP_CHECK_INTERVAL = 10; // 10秒检查一次 -const CACHE_EXPIRE_TIME = 1 * 60 * 1000; // 1分钟 +const CACHE_EXPIRE_TIME = 1 * 30 * 1000; // 1分钟 // 添加最大缓存数量限制 const MAX_CACHE_SIZE = 100; // 最大缓存数量 @@ -98,13 +92,10 @@ export class RemoteSpriteCache extends NodeSingleton { /** * 检查并注册精灵 */ - public checkAndRegisterSprite( - url: string, - spriteFrame: SpriteFrame, - ): boolean { - if (spriteFrame && !StringUtils.isEmpty(url)) { - const cacheItem = this._cache.get(url); - if (cacheItem && cacheItem.spriteFrame === spriteFrame) { + public checkAndRegisterSprite(spriteFrame: SpriteFrame): boolean { + if (spriteFrame && !StringUtils.isEmpty(spriteFrame.remoteUrl)) { + const cacheItem = this._cache.get(spriteFrame.remoteUrl); + if (cacheItem) { cacheItem.refCount++; return true; } @@ -115,10 +106,7 @@ export class RemoteSpriteCache extends NodeSingleton { protected update(dt: number): void { const currentTime = Date.now(); // 每隔指定时间检查一次过期资源 - if ( - currentTime - this._lastCleanupTime >= - CLEANUP_CHECK_INTERVAL * 1000 - ) { + if (currentTime - this._lastCleanupTime >= CLEANUP_CHECK_INTERVAL * 1000) { this.cleanupUnusedResources(); this._lastCleanupTime = currentTime; } @@ -130,16 +118,10 @@ export class RemoteSpriteCache extends NodeSingleton { public async loadSpriteFrame(url: string): Promise { let cacheItem = this._cache.get(url); if (cacheItem) { - if ( - cacheItem.loadState === LoadState.LOADED && - cacheItem.spriteFrame - ) { + if (cacheItem.loadState === LoadState.LOADED && cacheItem.spriteFrame) { cacheItem.refCount++; return cacheItem.spriteFrame; - } else if ( - cacheItem.loadState === LoadState.LOADING && - cacheItem.loadPromise - ) { + } else if (cacheItem.loadState === LoadState.LOADING && cacheItem.loadPromise) { try { const spriteFrame = await cacheItem.loadPromise; if (spriteFrame) { @@ -155,14 +137,8 @@ export class RemoteSpriteCache extends NodeSingleton { } // 如果加载失败且重试次数未达到上限,重新尝试 - if ( - cacheItem.loadState === LoadState.FAILED && - cacheItem.retryCount < MAX_RETRY_COUNT - ) { - LogUtils.warn( - TAG, - `重试加载: ${url}, 第${cacheItem.retryCount + 1}次`, - ); + if (cacheItem.loadState === LoadState.FAILED && cacheItem.retryCount < MAX_RETRY_COUNT) { + LogUtils.warn(TAG, `重试加载: ${url}, 第${cacheItem.retryCount + 1}次`); cacheItem.incrementRetry(); return this.doLoadSpriteFrame(url, cacheItem); } @@ -178,10 +154,7 @@ export class RemoteSpriteCache extends NodeSingleton { return this.doLoadSpriteFrame(url, cacheItem); } - private async doLoadSpriteFrame( - url: string, - cacheItem: CacheItem, - ): Promise { + private async doLoadSpriteFrame(url: string, cacheItem: CacheItem): Promise { cacheItem.loadState = LoadState.LOADING; cacheItem.setLoadStartTime(); @@ -193,6 +166,7 @@ export class RemoteSpriteCache extends NodeSingleton { reject(new Error(`加载超时: ${url}`)); }, LOAD_TIMEOUT); + console.log(`开始加载资源: ${url}`); assetManager.loadRemote(url, (err, asset: ImageAsset) => { clearTimeout(timeoutId); @@ -209,6 +183,7 @@ export class RemoteSpriteCache extends NodeSingleton { const spriteFrame = new SpriteFrame(); spriteFrame.texture = texture; spriteFrame.addRef(); + spriteFrame.remoteUrl = url; cacheItem.refCount++; cacheItem.spriteFrame = spriteFrame; @@ -218,11 +193,7 @@ export class RemoteSpriteCache extends NodeSingleton { resolve(spriteFrame); } catch (createErr) { - LogUtils.error( - TAG, - `创建SpriteFrame失败: ${url}`, - createErr, - ); + LogUtils.error(TAG, `创建SpriteFrame失败: ${url}`, createErr); cacheItem.loadState = LoadState.FAILED; cacheItem.loadPromise = null; reject(createErr); @@ -242,6 +213,7 @@ export class RemoteSpriteCache extends NodeSingleton { const cacheItem = this._cache.get(url); if (cacheItem) { cacheItem.refCount--; + console.log(`释放资源引用: ${url}, 引用计数: ${cacheItem.refCount}`); } } } @@ -300,11 +272,7 @@ export class RemoteSpriteCache extends NodeSingleton { private cleanupByUsageTime(targetSize: number): void { // 直接筛选并排序需要清理的资源 const entriesToClean = Array.from(this._cache.entries()) - .filter( - ([_, cacheItem]) => - cacheItem.refCount <= 0 && - cacheItem.loadState === LoadState.LOADED, - ) + .filter(([_, cacheItem]) => cacheItem.refCount <= 0 && cacheItem.loadState === LoadState.LOADED) .sort((a, b) => a[1].lastAccessTime - b[1].lastAccessTime); let cleanedCount = 0; @@ -343,10 +311,7 @@ export class RemoteSpriteCache extends NodeSingleton { let imageAsset: ImageAsset = null; // 如果已加入动态合图,必须取原始的Texture2D - if ( - cacheItem.spriteFrame.packable && - cacheItem.spriteFrame.original - ) { + if (cacheItem.spriteFrame.packable && cacheItem.spriteFrame.original) { texture = cacheItem.spriteFrame.original._texture as Texture2D; }