683 Commits

Author SHA1 Message Date
dgflash
bbbb9b6835 解决ECS框架文件之间的相互依赖 2026-06-19 14:00:22 +08:00
dgflash
2acc9bd7e8 修复提示系统加载与 RichText 兼容问题
1. 统一提示预制路径为 UI_Notify/UI_Wait/UI_Mask
2. LayerNotify 统一异步加载并支持模板克隆
3. LanguageLabel 兼容 RichText 模块未启用场景
2026-06-19 13:26:40 +08:00
dgflash
6cdce6eeee fix:修复游戏切后台再切回时音效重复异常播放问题 2026-06-18 22:43:52 +08:00
dgflash
c88903eac0 refactor(gui): 提示资源配置外部化,修复弹窗遮罩加载失败 2026-06-18 22:21:06 +08:00
dgflash
ccd6688a64 fix: 增强调试信息提示,修复 CCView onLoad 访问修饰符
- IAudioParams 新增 path 属性,用于音效资源路径调试提示
- AudioEffectPool 增加音效资源为空检查,失效提示补充路径信息
- UIButton 警告日志增加节点路径,便于定位缺失 Button 组件的节点
- CCView onLoad 修饰符改为 protected,防止外部误调用
2026-06-18 13:41:25 +08:00
dgflash
ba64e8d586 feat: 添加 @classname 装饰器,修复打包后类名混淆导致 addBusiness 属性绑定失败的问题 2026-06-13 18:59:37 +08:00
dgflash
4fc6652dfd 修复发布模式下类名混淆导致addBusinesss属性绑定失败的问题 2026-06-13 15:32:25 +08:00
dgflash
3a2db77647 1. 核心入口 — ECS.ts
ecs 命名空间:统一导出所有 API,业务只需 import { ecs } from './ECS'
核心类型别名:ecs.Entity / ecs.Comp / ecs.RootSystem / ecs.ComblockSystem
接口再导出:ecs.IComp / ecs.IMatcher / ecs.IEntityEnterSystem / ecs.IEntityRemoveSystem / ecs.ISystemFirstUpdate / ecs.ISystemUpdate
实体工厂:ecs.getEntity(ctor, world?) — 创建或从对象池获取实体
动态查询:ecs.query(matcher, world?) — 按匹配器查询实体
过滤器工厂:ecs.allOf() / ecs.anyOf() / ecs.onlyOf() / ecs.excludeOf() — 组合匹配规则
单例组件:ecs.getSingleton() / ecs.addSingleton() — 全局唯一组件访问
子模块门面:ecs.world / ecs.pool / ecs.system / ecs.storage / ecs.network / ecs.serialize / ecs.entityRef
2. 驱动器 — ECSDriver.ts
封装默认世界的 init / execute / destroy 生命周期
add(system) — 向默认世界添加业务系统
init() — 初始化 ECS(并入 @ecs.register 注册的系统、拓扑排序、init)
execute(dt) — 驱动默认世界一帧
destroy() — 清理所有子系统
3. 实体 — ECSEntity.ts
组件容器:位掩码 mask + 按 tid 索引的密集数组,get/has 为 O(1)
双重重载 add():
add(组件类) — 从对象池取实例或恢复软移除缓存
add(组件实例) — 挂载外部实例(如 cc.Component),设 canRecycle=false
remove(ctor, isRecycle?):
isRecycle=true(默认):reset + 回池/释放 SoA 槽位
isRecycle=false:软移除,数据暂存 compTid2Obj,下次 add 同 tid 恢复
父子层级:addChild / removeChild,带循环引用检测
destroy():断开父子 → 移除全部组件 → 清理软移除缓存 → 回收实体 + 释放 eid
forEachComponent(cb):遍历当前挂载的所有组件
4. 组件 — ECSComp.ts
抽象基类,子类须实现 reset() 方法
canRecycle — 是否可回收(外部创建的组件设 false)
ent — 拥有该组件的实体引用
变更检测:markDirty() / isChangedSince(sinceEpoch) / lastWriteEpoch — 基于 epoch 的帧级脏标记
5. 位掩码 — ECSMask.ts
基于 Uint32Array 的位运算,支持 set / has / delete / and / or / bitCount
对象池复用,clearPool() 清理
6. 注册系统 — ECSRegister.ts + ECSTypeRegistry.ts
@ecs.register('Name') 类装饰器:自动识别注册类型
组件:分配 tid,写入 compCtors 表
实体:记录 ctor → name 映射
系统:注册到全局表或指定世界
ECSTypeRegistry:全局类型注册表(跨世界共享),记录组件/实体/系统元数据
7. 查询 — ECSMatcher.ts + ECSGroup.ts
四种规则:AllOf / AnyOf / OnlyOf / ExcludeOf,规则间为"与"关系
flyweight 缓存:相同组合共享同一 Matcher 实例
小规则优化:tid 数 ≤ 4 时直接 mask.has,否则分配 ECSMask
ECSGroup:SparseSet 实现,O(1) 增删(swap-pop),稳定快照遍历
进入/离开追踪:watchEntityEnterAndRemove 供系统帧内查询变化
8. 系统 — ECSComblockSystem.ts + ECSRootSystem.ts
ComblockSystem:业务系统基类
生命周期:init → entityEnter → firstUpdate → update → entityRemove → onDestroy
filter() — 声明实体匹配规则
interval — 执行间隔(0=每帧,>0=固定间隔)
被动系统:isPassiveSystem() 返回 true 时不参与每帧 update
构造时探测子类钩子,选定 execute 变体(零开销分支)
RootSystem:根系统,一世界一个
init() — 并入 @ecs.register 系统 + 拓扑排序 + 绑定世界 + init
execute(dt) — 切换当前世界 → 递增 epoch → tick 各系统 → flush 命令缓冲
9. 系统调度 — SystemScheduler.ts
声明式执行顺序:@ecs.system.executeBefore / @ecs.system.executeAfter / @ecs.system.inSet
拓扑排序(Kahn 算法):无约束系统保持原始顺序,循环依赖抛 CycleDependencyError
集合机制:inSet('名') 把系统加入虚拟分组,其他系统用 executeAfter('set:名') 批量依赖
10. 世界 — ECSWorld.ts + ECSWorldManager.ts
ECSWorld:运行期数据容器
entities — 活动实体表(eid → 实体)
groups — 响应式查询分组
singletons — 单例组件表
refs — @entityRef 引用追踪
commands — 延迟结构变更命令队列
epoch — 世代号(每帧递增,变更检测用)
getEntity(ctor) — 创建/从池获取实体
assignEid(entity, eid) — 反序列化时保持 eid 一致
ECSWorldManager(ecs.world):多世界管理
get(name?) / default() / current — 获取/切换世界
use(world) — 切换当前世界,返回切换前的世界
inWorld(world, fn) — 在指定世界中执行,自动还原
createSystems(world, ...ctors) — 批量装配系统并 init
defer(fn) / flushCommands() — 延迟结构变更
11. 命令缓冲 — ECSCommandBuffer.ts
延迟结构变更队列,帧末由 RootSystem.execute 统一 flush
push(fn) 入队,flush() 先快照再执行(避免本帧新入队命令在本帧执行)
12. 对象池 — ECSPoolManager.ts + ECSDynamicPool.ts
ecs.pool:统一管理实体/组件动态对象池
getPool(name, factory) — 获取或创建池
clearAll() / clearPools() — 清空池缓存(不触碰存活数据)
getAllMetrics() — 获取各池统计信息(命中/未命中/缓存/创建数)
13. 实体引用 — ECSEntityRef.ts + ECSReferenceTracker.ts
@ecs.entityRef() 属性装饰器:标记组件属性为实体引用
目标实体销毁时自动置 null,避免悬空引用
组件回收时 clearComponentEntityRefs 清理所有引用
14. SoA 列存储 — StorageSoA.ts + StorageDecorators.ts
@ecs.storage.enableSoA 类装饰器:为组件启用 SoA 列存储(默认 AoS,opt-in)
字段装饰器:float64 / float32 / int32 / uint32 / int16 / uint16 / int8 / uint8
数值字段按列存入 TypedArray,按 eid 分配槽位
acquire 返回 Proxy 视图:SoA 字段读写直接落到 TypedArray,非 SoA 字段走后备实例
槽位超出容量时 2 倍扩容,释放时入空闲栈
自注册机制:模块加载时注册到核心,删除 storage/ 目录后基础 ECS 仍可运行
15. 网络同步 — NetworkSync.ts + SyncDecorators.ts + SyncCodec.ts + ByteBuffer.ts
@ecs.network.sync(类型) 字段装饰器:标记组件字段参与网络同步
ecs.network.net 门面:
encodeWorld(op?) — 编码当前世界为紧凑二进制(Full 全量 / Delta 增量)
applyToWorld(bytes, onMissing?) — 将二进制同步数据应用到世界
track(entity, markAll?) — 为实体初始化变更追踪器
clearDirty() — 清除所有脏标记
SyncCodec:实体/组件级编解码器
ByteWriter / ByteReader:二进制读写缓冲(变长整数等)
ChangeTracker:字段级脏标记追踪
16. 序列化 — Serialization.ts + Incremental.ts
@ecs.serialize() 字段装饰器:标记组件需要持久化的字段
全量序列化:
ecs.serialize.serializeWorld(pretty?) — 序列化当前世界为 JSON
ecs.serialize.deserializeWorld(json) — 从 JSON 反序列化到当前世界
增量序列化:
ecs.serialize.snapshot() — 对当前世界拍快照(基线)
ecs.serialize.computeDelta(base) — 计算相对基线的增量(added / removed / changed)
ecs.serialize.applyDelta(delta) — 将增量应用到当前世界
保留实体层级(parentEid),两阶段重建(先建实体+组件,再重建父子)
17. 监控日志 — ECSMonitorLogger.ts
零入侵监控模块,通过控制台命令触发
注册全局命令:
ecsLog() — 打印所有监控表格
ecsWorldSummary() — 各世界实体/系统/组件缓存统计
ecsSummary() — 总体统计(所有世界合计)
ecsEntityPools() — 实体池明细(命中/未命中/缓存)
ecsCompPools() — 组件池明细(按 M/B/V/VC 分类排序)
ecsEntityCaches() — 实体软移除组件缓存明细
ecsHelp() — 显示帮助信息
2026-06-12 21:52:47 +08:00
dgflash
e8d42c140c 删除已废弃的按钮组件 ButtonEffect 和 ButtonTouchLong
- 移除 ButtonEffect(有特效按钮),该组件已被 UIButton 替代
- 移除 ButtonTouchLong(长按按钮),该组件已被 UIButton 替代
- 二者功能已由 UIButton 统一替代
2026-06-06 21:36:56 +08:00
dgflash
0b06fcb11e 优化 2026-05-30 06:59:39 +08:00
dgflash
4b9b05fa9f 修复动画效果回收失败问题 2026-05-30 06:50:57 +08:00
dgflash
ddad261b38 优化 2026-05-30 06:30:31 +08:00
dgflash
d4f140077e feat (core): 完善框架核心功能模块 - 音频、对象池、资源加载与组件系统
新增与优化核心模块
🎯 GUI 交互增强
ButtonInterceptor:按钮点击事件劫持器
劫持 EventHandler.emitEvents / ButtonSimple.onClick 核心方法
支持多类型按钮音效配置注册,按按钮类型自动匹配音效
单例模式管理,支持全局动态激活 / 停用拦截功能
🧩 对象池管理系统
GameNodePool:通用游戏节点对象池管理器
基于预制体(Prefab)UUID 实现池化隔离管理
支持特效、UI 元素等高频对象预加载、复用与回收
全局单例访问,统一管控对象创建 / 销毁逻辑
🔊 音频管理系统
AudioManager:音频核心管理器
独立背景音乐(AudioMusic)+ 音效池(AudioEffectPool)双模块
支持全局音量控制、播放状态恢复与场景切换管理
AudioEffect:基础音效播放器
AudioEnum:音频类型、音效分类枚举定义
📦 资源加载系统
ResLoader:资源加载核心控制器
资源包(Bundle)统一管理 + 并发加载限流控制
远程资源本地缓存、自动释放与内存优化
完整加载进度回调 + 错误异常处理机制
ResTypes:资源类型规范定义
ResErrors:资源加载错误码与异常处理
ResUtils:资源路径、格式转换等工具方法
🧱 模块化组件系统
GameComponent:游戏显示对象组件基类
集成资源自动引用计数(RC)管理
模块化部件(GamePartRegistry)插拔式架构
内置音频、按钮、事件、键盘、节点、对象池、资源七大部件
部件封装:
GamePartAudio:音频功能部件
GamePartButton:按钮交互部件
GamePartEvent:全局事件部件
GamePartKeyboard:键盘输入部件
GamePartNode:节点操作部件
GamePartNodePool:对象池调用部件
GamePartRes:资源加载部件
📝 类型定义完善
新增 IAudio 音频数据与播放参数接口
统一全模块 TS 类型定义与导出规范
优化接口注释与类型约束,提升开发体验
2026-05-29 22:55:13 +08:00
dgflash
0484015e7a 优化 2026-05-25 22:41:55 +08:00
dgflash
6a486bbbc6 优化 2026-05-22 22:52:11 +08:00
dgflash
58d145b7dc 优化 2026-05-22 22:22:33 +08:00
dgflash
d33b668810 添加:
1. 自动管理资源引用计数 - 多组件共享资源时不会错误释放
2. 组件销毁时自动释放资源引用 - 开发者无需手动管理
3. 全局资源追踪 - 可查看任意资源的引用者和引用计数
2026-05-17 20:11:06 +08:00
dgflash
e58951632b 修复LayerPopUp关闭遮罩时把mask节点的uiSprite关闭了,但是打开遮罩时没有启用,导致只有第一个PopUp能显示mask 2026-05-17 18:58:28 +08:00
dgflash
508e5bb2d2 优化ECS 2026-05-10 21:53:03 +08:00
dgflash
3a61f0420f 优化ECS 2026-05-10 21:44:38 +08:00
dgflash
a829dde974 优化ECS 2026-05-10 21:40:04 +08:00
dgflash
c2f787e964 优化ECS 2026-05-10 21:25:36 +08:00
dgflash
1d8f4988a4 优化ECS 2026-05-10 21:01:29 +08:00
dgflash
2c0b5cfa6e 更新版本号 2026-05-04 16:20:04 +08:00
dgflash
3c3b7f4f64 refactor(gui): 提取屏幕适配逻辑到独立 ScreenAdapter 类
- 新增 ScreenAdapter 类,负责屏幕分辨率适配和安全区域适配
- LayerManager 移除 windowAspectRatio/designAspectRatio/mobileSafeArea 属性
- LayerManager 移除 initScreenAdapter() 方法
- LayerManager 添加 screenAdapter 属性,通过组合方式使用

BREAKING CHANGE: 如需访问屏幕适配属性,改为通过 oops.gui.adapter
2026-05-03 21:18:01 +08:00
dgflash
12aedf1491 优化提示 2026-04-29 22:44:22 +08:00
dgflash
d333ff5371 feat(gui): 添加界面缓存查询方法 hasCache
修改内容:
1. LayerUI.ts: 添加 hasCache(prefabPath: string) 方法
   - 检查 ui_cache 中是否存在指定预制件路径的界面

2. LayerManager.ts: 添加 isCached(uiid: Uiid) 方法
   - 对外提供查询界面是否在缓存中的 API
   - 与 has() 方法区分:has() 检查显示中,isCached() 检查缓存中

使用示例:
  // 检查界面是否正在显示
  oops.gui.has(UIID.Loading);      // false(已从舞台移除)

  // 检查界面是否在缓存中(destroy: false 时)
  oops.gui.hasCache(UIID.Loading); // true(在缓存中)

影响范围:
- 仅新增方法,不影响现有功能
- 向后兼容
2026-04-26 23:13:00 +08:00
dgflash
70930f8037 微信小游戏真机调试环境兼容 2026-04-22 09:31:52 +08:00
dgflash
b64c03ede8 强类型事件支持传空参数 2026-04-21 12:20:00 +08:00
dgflash
e274dbb062 修复 loading 转圈因 clearTimeout 提前执行导致无法关闭的 bug,完善状态管理与关闭逻辑 2026-04-10 22:13:45 +08:00
dgflash
0746948455 fix(GameComponent): 修复资源加载相关的安全问题和内存泄漏
## 问题修复
- setButton: 修复组件名不匹配格式时正则匹配崩溃
- createPrefabNode: 修复预制体加载失败时崩溃,返回类型改为 Promise<Node | null>
- load: 修复资源加载失败时引用计数未移除
- loadAny: 修复加载失败时引用计数未移除
- loadDir: 修复加载失败时引用计数未移除
- playEffect: 修复返回值 null! 非空断言,改为 Promise<AudioEffect | null>
- setSprite: 优化失败处理逻辑,返回 boolean

## 新增功能
- loadDirAsync: Promise 模式的文件夹资源加载
- removePathFromRecord: 私有方法,用于加载失败时回滚引用计数

## 代码优化
- loadAny/loadDir: 使用强类型回调参数
- loadAny: 使用对象数组替代字符串拼接解析
2026-04-05 12:22:28 +08:00
dgflash
5a43c3d08e 优化强类型事件类型 2026-04-05 11:15:01 +08:00
dgflash
b32c550b15 1.规范化框架业务模板的提示信息
2.废弃GameCollision.ts
2026-04-05 11:05:58 +08:00
dgflash
9a4fd82dcf CCBusiness支持事件系统全部功能 2026-04-05 10:52:32 +08:00
dgflash
0e569dc31e 统一框架中d.ts文件风格 2026-04-05 10:26:24 +08:00
dgflash
4d9d2eac96 优化强类型事件类型 2026-04-05 10:19:24 +08:00
dgflash
79d5ee8637 优化强类型事件类型 2026-04-05 10:00:53 +08:00
dgflash
421c7db39e 优化聚焦强类型事件方法命名规范调整,核心改动为:废弃原有基于重载区分事件方法的实现方式,统一采用语义化、独立化的方法命名规则。适配 AI 自动生成代码的理解与解析逻辑 2026-04-05 09:19:31 +08:00
dgflash
da020de1ff 框架工具控制Cocos Creator 自动打开预制绑定脚本 2026-04-04 22:37:24 +08:00
dgflash
d2c68fbab5 fix(gui): 修复 onBeforeRemove 回调不触发的问题
问题原因:
在 LayerUI.remove() 方法中,state.valid 被提前设置为 false,
导致 LayerUIElement.remove() 中判断 state.valid 时条件不成立,
从而跳过了 onBeforeRemove 回调的触发。

修复方案:
将 state.valid = false 的赋值操作移动到 LayerUIElement.remove()
调用之后执行,确保回调能正常触发。

影响范围:
- 修复通过 oops.gui.remove() 关闭界面时 onBeforeRemove 回调不执行的问题
- 不影响界面缓存和异步加载的僵尸节点防护逻辑
2026-04-01 22:38:10 +08:00
dgflash
99fd688924 倒计时标签(组合方式实现,不继承 Label),因为在模拟器中下会导致标签文本渲染不出来 2026-03-24 09:14:31 +08:00
dgflash
e06697f4a8 1. 修复常驻 PopUp(如 Main)存在时,最后一个 mask:true 弹窗关闭后,共享 mask 不再残留
2.BlockInputEvents 与 mask 生命周期同步管理
3.代码可维护性提升,职责分离更清晰
2026-03-21 09:35:02 +08:00
dgflash
d43f1de76c ECS 对象池优化 2026-03-08 17:27:27 +08:00
dgflash
0b808f6ab1 优化CCEntity的addPrefab、addUi异步操作时,对象被释放时空对象问题,提高框架稳定性 2026-03-08 13:59:24 +08:00
dgflash
605e0b8d76 CCView 使用MVVM功能时性能优化 2026-03-08 13:42:41 +08:00
dgflash
b7aa3b6d2a Mvvm ViewModel 生命周期自动管理功能,彻底解决了临时tag的命名冲突和内存泄漏问题 2026-03-08 13:27:48 +08:00
dgflash
5776b5b7b8 Mvvm VMBase组件路径解析的性能优化 2026-03-08 13:16:41 +08:00
dgflash
2c95d13b9e 1. 明确文档说明isRecycle=false的使用场景
2. 提供清理缓存的API
2026-03-08 12:46:52 +08:00
dgflash
9d65c31016 MVVM里JsonOb深度监听的性能优化
1. 防止重复观察同一对象
2.优化数组操作(只监听新增元素)
3.支持冻结数据(不监听静态配置)
4.支持批量更新(减少回调次数)
5.支持自定义深度限制
6.更安全的内存管理
7.API 完全兼容原始版本,可零改动升级
2026-03-08 12:09:10 +08:00
dgflash
2350b06c84 ECS 缓存管理优化 2026-03-08 11:49:53 +08:00