fix(core): invoke structured Signal listeners with runtime args before bound args#2987
fix(core): invoke structured Signal listeners with runtime args before bound args#2987cptbtptpbcptdtptp wants to merge 2 commits into
Conversation
…e bound args Previously `Signal._addListener` applied bound arguments first and runtime signal args last, producing `method(...boundArgs, ...signalArgs)`. This made the event object's position shift with the number of bound arguments and diverged from the DOM / Cocos `(event, customEventData)` convention. Flip the order so the listener method receives runtime args first and bound args last: `method(...signalArgs, ...boundArgs)`. The event object now always sits at index 0, making migrated Cocos scripts with `(event, customData)` signatures work without rewrites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add three test cases verifying that runtime signal args are passed before bound args: - "runtime args precede bound args" — full ordering with two of each. - "event object stays at index 0 regardless of bound args count" — position invariant of the conventional event argument. - "once: runtime + bound args order preserved" — same guarantee for once-style listeners. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WalkthroughSignal's structured binding listener changes argument order: runtime signal arguments now precede pre-resolved bound arguments when invoking target methods. Implementation, documentation, and test coverage are updated to reflect and validate this new invocation contract. ChangesSignal Argument Ordering for Structured Binding
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
已关闭问题清单
所有历史问题均已关闭。
总结
将 Signal 结构化绑定监听器的调用顺序从 method(...boundArgs, ...signalArgs) 修正为 method(...signalArgs, ...boundArgs),确保 event 对象始终在 index 0,与 DOM addEventListener约定对齐。改动一行,方向完全正确,三个新测试验证了参数顺序、事件对象位置不变性(含多 bound args 场景)和 once() 对等性。
[P2] 破坏性变更建议记录在 CHANGELOG
...boundArgs, ...signalArgs → ...signalArgs, ...boundArgs 是破坏性变更:已有使用结构化绑定且依赖旧参数顺序的用户代码会静默接收到错误参数而不报错。若项目维护 CHANGELOG,建议在 2.0 breaking changes 中加一条说明。不阻塞合并,但有助于下游感知。
其余无新问题。LGTM。
GuoLei1990
left a comment
There was a problem hiding this comment.
总结
把 structured Signal listener 的调用参数顺序从 method(...boundArgs, ...signalArgs) 翻转为 method(...signalArgs, ...boundArgs),让 event 对象固定在 index 0,对齐 DOM (event, customData) 习惯。改动本身一行,方向合理。
已核对:引擎内部没有任何 listener 依赖旧顺序。4 个 Signal 实例(onClick/onStateChanged/onTrackedDeviceChanged/onChanged)全部走 closure 形式(传函数,不传 component+methodName),不受影响。唯一的 structured-binding 生产调用点是 ReflectionParser.ts:181(反序列化 scene 数据的透传),它本身不绑定具体 handler 逻辑,不会"坏"。两个既有用到 bound args 的测试都用零 runtime args invoke,翻转后结果不变。
问题
无阻塞性问题。
唯一的暴露面是按旧顺序编写的序列化 scene 资产 / 用户代码(handler 签名期望 (boundArg, ...event))会静默收到 (...event, boundArg)——这点是 breaking change,我前几轮已多次提过,按既定结论属非阻塞,需要在 2.0 的 breaking-changes CHANGELOG 里记一笔 old→new 顺序供迁移。此处不重复展开,仅确认状态:仍未在 CHANGELOG 体现,但不阻塞合入。
自检
call site 分析(closure vs structured binding)已对照 Signal.ts dispatch wrapper 与全 packages/ grep 确认。breaking-change/CHANGELOG 点不重新升级,仅作状态确认。LGTM。
Summary
method(...boundArgs, ...signalArgs)tomethod(...signalArgs, ...boundArgs), so the event object always sits at index 0.(event, customData)convention.Background
Cherry-picked from
b16d8b5d7on fix/shaderlab.Test plan
Signal.test.tscases: arg ordering, event index 0 invariant,once()parity🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests