From 6a486bbbc681b5c1b41bcd8fb872d8f08e58dfa1 Mon Sep 17 00:00:00 2001 From: dgflash Date: Fri, 22 May 2026 22:52:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/core/common/loader/ResAutoTracker.ts | 88 ++++++++++++++++----- assets/libs/ecs/pool/IECSPoolMetrics.ts | 4 - assets/libs/ecs/pool/index.ts | 1 - assets/module/common/view/GameResModule.ts | 27 +------ 4 files changed, 72 insertions(+), 48 deletions(-) diff --git a/assets/core/common/loader/ResAutoTracker.ts b/assets/core/common/loader/ResAutoTracker.ts index 249fa30..dd5ce23 100644 --- a/assets/core/common/loader/ResAutoTracker.ts +++ b/assets/core/common/loader/ResAutoTracker.ts @@ -20,11 +20,19 @@ class ResAutoTracker { private readonly ownerEntries = new Map(); private debugMode = false; + /** + * 启用或关闭调试模式 + * @param enabled - 是否启用调试输出 + */ enableDebug(enabled: boolean): void { this.debugMode = enabled; } - /** 持有者是否已通过本追踪器占用过资源 */ + /** + * 持有者是否已通过本追踪器占用过资源 + * @param owner - 资源持有者(Component) + * @returns 是否正在追踪该持有者的资源 + */ isTracking(owner: Component): boolean { const list = this.ownerEntries.get(owner); return list != null && list.length > 0; @@ -32,6 +40,8 @@ class ResAutoTracker { /** * 为持有者增加对资源及其递归依赖的引用(主资源 + deps 各自 addRef) + * @param owner - 资源持有者(Component) + * @param asset - 要引用的资源,可为 null 或 undefined */ acquire(owner: Component, asset: Asset | null | undefined): void { if (!owner || !asset) { @@ -60,6 +70,8 @@ class ResAutoTracker { /** * 为持有者批量登记资源(常用于 loadDir / loadAny) + * @param owner - 资源持有者(Component) + * @param assets - 要引用的资源数组,可为 null 或 undefined */ acquireMany(owner: Component, assets: (Asset | null | undefined)[] | null | undefined): void { if (!owner || !assets || assets.length === 0) { @@ -73,6 +85,9 @@ class ResAutoTracker { /** * 释放持有者登记的一条「与给定 asset uuid 匹配的」条目(若同 asset 有多条仅移除最先匹配的一条) + * @param owner - 资源持有者(Component) + * @param asset - 要释放的资源,可为 null 或 undefined + * @returns 是否成功释放 */ releaseByAsset(owner: Component, asset: Asset | null | undefined): boolean { if (!owner || !asset) { @@ -95,7 +110,13 @@ class ResAutoTracker { return true; } - /** 路径 + bundle:从缓存取资源后解除一条逻辑引用(供 releaseRes(path) 使用) */ + /** + * 路径 + bundle:从缓存取资源后解除一条逻辑引用(供 releaseRes(path) 使用) + * @param owner - 资源持有者(Component) + * @param path - 资源路径 + * @param bundleName - bundle 名称 + * @returns 是否成功释放 + */ releaseByPath(owner: Component, path: string, bundleName: string): boolean { if (!owner || !path) { return false; @@ -113,6 +134,8 @@ class ResAutoTracker { /** * 释放持有者名下全部条目,返回被逻辑释放的条目数 + * @param owner - 资源持有者(Component),可为 null 或 undefined + * @returns 被释放的条目数量 */ releaseAll(owner: Component | null | undefined): number { if (!owner) { @@ -134,11 +157,19 @@ class ResAutoTracker { return count; } - /** 持有者当前登记的根资源条目数 */ + /** + * 持有者当前登记的根资源条目数 + * @param owner - 资源持有者(Component) + * @returns 该持有者登记的条目数量 + */ getOwnerEntryCount(owner: Component): number { return this.ownerEntries.get(owner)?.length ?? 0; } + /** + * 获取追踪器统计信息 + * @returns 包含持有者数、根资源条目数、依赖条数之和的统计对象 + */ getStats(): { totalOwners: number; totalTrackedRoots: number; totalDepAssetsInEntries: number } { let totalTrackedRoots = 0; let totalDepAssetsInEntries = 0; @@ -159,6 +190,10 @@ class ResAutoTracker { return { totalOwners, totalTrackedRoots, totalDepAssetsInEntries }; } + /** + * 打印指定持有者的资源状态到控制台 + * @param owner - 资源持有者(Component) + */ printOwnerStatus(owner: Component): void { const entries = this.ownerEntries.get(owner); console.log(`\n===== ResAutoTracker ${this.ownerLabel(owner)} =====`); @@ -166,13 +201,20 @@ class ResAutoTracker { console.log(' (无)'); } else { - entries.forEach((e, idx) => { - console.log(` [${idx}] ${e.asset.constructor.name} name=${e.asset.name} uuid=${e.asset.uuid} refCount=${e.asset.refCount} deps=${e.deps.length}`); - }); + console.table(entries.map((e, idx) => ({ + 类型: e.asset.constructor.name, + 名称: e.asset.name, + 唯一标识: e.asset.uuid, + 引用数: e.asset.refCount, + 依赖数: e.deps.length + }))); } console.log('========================================\n'); } + /** + * 打印追踪器全局状态到控制台 + */ printStatus(): void { console.log('\n========== ResAutoTracker 全局 =========='); const stats = this.getStats(); @@ -180,22 +222,22 @@ class ResAutoTracker { this.ownerEntries.forEach((entries, owner) => { console.log(`\n ▸ ${this.ownerLabel(owner)} — ${entries.length} 条`); - entries.forEach((e, i) => { - console.log(` [${i}] ${e.asset.constructor.name} ref=${e.asset.refCount} deps=${e.deps.length}`); - }); + console.table(entries.map((e, i) => ({ + 类型: e.asset.constructor.name, + 名称: e.asset.name, + 引用: e.asset.refCount, + 依赖数: e.deps.length + }))); }); console.log('=========================================\n'); } - /** 清空记录(不推荐运行时使用;不传参清空全部持有者) */ - clear(): void { - this.ownerEntries.clear(); - if (this.debugMode) { - console.warn('[ResAutoTracker] clear() — 已与引擎 refCount 不同步:仅清空表,不负责 decRef'); - } - } - + /** + * 生成持有者的标签字符串(用于调试输出) + * @param owner - 资源持有者(Component) + * @returns 格式化的持有者标签字符串 + */ private ownerLabel(owner: Component): string { const ctor = owner?.constructor?.name ?? 'Unknown'; const nodeName = owner?.node?.name ?? '?'; @@ -203,6 +245,11 @@ class ResAutoTracker { return `${ctor}<${nodeName}>@${uuidShort}`; } + /** + * 收集指定资源的递归依赖资源列表 + * @param root - 根资源 + * @returns 依赖资源数组(不含根资源本身) + */ private collectDependencyAssets(root: Asset): Asset[] { const out: Asset[] = []; const seen = new Set(); @@ -229,6 +276,11 @@ class ResAutoTracker { return out; } + /** + * 释放单个条目(执行 decRef 操作) + * @param owner - 资源持有者(Component) + * @param entry - 要释放的追踪条目 + */ private releaseEntry(owner: Component, entry: TrackedResEntry): void { const deps = entry.deps; const dLen = deps.length; @@ -244,4 +296,4 @@ class ResAutoTracker { } } -export const resAutoTracker = new ResAutoTracker(); \ No newline at end of file +export const resAutoTracker = new ResAutoTracker(); diff --git a/assets/libs/ecs/pool/IECSPoolMetrics.ts b/assets/libs/ecs/pool/IECSPoolMetrics.ts index a55ce05..9268950 100644 --- a/assets/libs/ecs/pool/IECSPoolMetrics.ts +++ b/assets/libs/ecs/pool/IECSPoolMetrics.ts @@ -1,7 +1,3 @@ -/** - * 池统计指标 - */ - /** 池统计指标 */ export interface IECSPoolMetrics { /** 创建次数 */ diff --git a/assets/libs/ecs/pool/index.ts b/assets/libs/ecs/pool/index.ts index 19cbd69..53d2647 100644 --- a/assets/libs/ecs/pool/index.ts +++ b/assets/libs/ecs/pool/index.ts @@ -13,7 +13,6 @@ * - 场景优化:场景切换时自动预热相关对象池 */ -export { IECSPoolMetrics } from './IECSPoolMetrics'; export { ECSDynamicPool } from './ECSDynamicPool'; export { ECSPoolManager } from './ECSPoolManager'; diff --git a/assets/module/common/view/GameResModule.ts b/assets/module/common/view/GameResModule.ts index 52b4e90..97c18a5 100644 --- a/assets/module/common/view/GameResModule.ts +++ b/assets/module/common/view/GameResModule.ts @@ -10,10 +10,10 @@ import type { AssetType, CompleteCallback, Paths, ProgressCallback } from '../.. import { resLoader } from '../../../core/common/loader/ResLoader'; import { resAutoTracker } from '../../../core/common/loader/ResAutoTracker'; import { GameViewModule } from './GameViewModuleBase'; +import { DEBUG } from 'cc/env'; /** 资源加载与引用计数管理 */ export class GameResModule extends GameViewModule { - /** 获取资源 * @param path 资源路径 * @param type 资源类型 @@ -98,34 +98,11 @@ export class GameResModule extends GameViewModule { /** 销毁资源模块 */ override destroy(): void { const released = resAutoTracker.releaseAll(this.comp); - if (released > 0) { + if (DEBUG && released > 0) { console.log(`[GameComponent] ${this.comp.node?.name} 释放 ${released} 条资源登记`); } } - /** 获取资源引用计数 - * @param path 资源路径 - * @param bundleName 资源包名称 - * @returns 引用计数 - */ - getResRefCount(path: string, bundleName: string = resLoader.defaultBundleName): number { - const bundle = assetManager.getBundle(bundleName); - const a = bundle?.get(path) as Asset | null; - return a ? a.refCount : 0; - } - - /** 获取追踪的资源根节点数量 - * @returns 资源根节点数量 - */ - getTrackedResRootCount(): number { - return resAutoTracker.getOwnerEntryCount(this.comp); - } - - /** 打印资源使用情况 */ - printResUsage(): void { - resAutoTracker.printOwnerStatus(this.comp); - } - /** 设置精灵图片 * @param target 精灵组件 * @param path 图片路径