feat(particle): add collection clear APIs#3069
Conversation
WalkthroughAdded ChangesParticle module clearing
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
1d08a06 to
05963e9
Compare
GuoLei1990
left a comment
There was a problem hiding this comment.
总结
给 SubEmittersModule 和 CustomDataModule 各加一个公开 clear(),一次性清空集合。动机充分且方向正确:prefab component override 需要用「clear 再 add」表达对继承集合的替换(区分「作者刻意的空集合」和「往继承态追加」),add-only 无法表达。把 clear 落在拥有该 mutation 的模块上,避免 Builder 侧戳私有数组或重建继承态,副作用归属正确。无 P0/P1/P2。
问题
无阻塞问题。逐条核对:
SubEmittersModule.clear()—_subEmitters.length = 0+_setTransformFeedback(),与removeSubEmitterByIndex的清理语义一致;early-return-if-empty 是良性微优化(_setTransformFeedback本身也needed===_useTransformFeedback早退,无副作用差异)。CustomDataModule.clear()— 委托removeCurve/removeGradient而非直接_curves.clear(),这是正确选择:删除路径同时归零 shader uniform(_zeroCurveUniforms/_zeroGradientUniforms)+ swap-pop 平行的_curveStreams/_gradientStreams数组 + 删 Map,直接clear()会漏掉前两者(stale uniform + 泄漏 streams)。虽是 O(n²)(每次 remove 线性扫 streams 找 idx),但 n 极小、非每帧热路径、且复用清理逻辑避免了双源真相——是合理取舍,不建议手写 O(n) 版重复归零逻辑。- Map 迭代期删除安全性 —
for (const name of this._curves.keys()) this.removeCurve(name)中removeCurve会_curves.delete(name)。已实证 ES Map 迭代器对「删除当前 yield 的 key」是良定义安全的,能完整清空(size→0),无跳过/漏删。
简化建议
代码已经足够干净,无需改动。委托复用现有 remove 路径而非另起清理逻辑是本 PR 最好的决定。
测试
两条测试均反向可证伪,链路正确:
CustomData:add A curve + B gradient → clear → 断言curves.size/gradients.size均为 0(clear 若 no-op 则为 1 FAIL)。SubEmitter:add Death 型 sub-emitter(_useTransformFeedback变 true)→ clear → 断言subEmitters.length===0且_useTransformFeedback===false。后者精确守住「clear 必须触发_setTransformFeedback重算」——若 clear 漏调_setTransformFeedback,_hasSubEmitterOfType(Death)仍返 false 但_useTransformFeedback停在 true → FAIL。戳(gen as any)._useTransformFeedback是该 side-effect 契约的唯一可观测点(无公开 getter),且与本文件既有测试风格一致,可接受。
LGTM。
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev/2.0 #3069 +/- ##
===========================================
- Coverage 79.82% 79.64% -0.19%
===========================================
Files 904 904
Lines 101297 101243 -54
Branches 11423 11426 +3
===========================================
- Hits 80865 80631 -234
- Misses 20250 20428 +178
- Partials 182 184 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Summary
clear()toSubEmittersModuleclear()toCustomDataModuleWhy
clearis requiredRuntime-v2 Prefab
componentPropsoverrides are applied after the referenced Prefab has been instantiated, so the target component may already contain inherited collection entries.Source-v2 collection semantics distinguish three states:
[]: replace it with an empty collectionBuilder can encode fixed method calls, but it cannot iterate an inherited runtime collection. Add-only output therefore cannot represent an authored empty collection and turns non-empty overrides into append operations. Correct replacement requires
clearfollowed by the authoredaddcalls.The collection-owning Engine modules must perform the clear because removal has module-specific side effects: sub-emitters must refresh transform-feedback state, while custom data must clear shader uniforms and its parallel stream bookkeeping. Builder-side private mutation or reconstruction of inherited state would bypass those invariants.
Removing a reference from source Prefab data does not remove references already held by an instantiated runtime component. GC only reclaims objects after the runtime collection releases them; it does not reconcile source overrides with live component state or update transform-feedback and shader state.
clear()performs that runtime mutation without destroying referenced emitter entities, which remain owned by the scene hierarchy.Verification
pnpm buildpnpm exec vitest run tests/src/core/particle/SubEmitter.test.ts tests/src/core/particle/CustomData.test.ts— 42 tests passedenergy-core-burst.packagewith no browser warnings or errorsConsumer
Required by galacean/editor#3805 for source-v2 particle collection overrides.
Summary by CodeRabbit
New Features
Tests