Skip to content

feat(particle): add collection clear APIs#3069

Open
luzhuang wants to merge 1 commit into
dev/2.0from
codex/particle-collection-clear
Open

feat(particle): add collection clear APIs#3069
luzhuang wants to merge 1 commit into
dev/2.0from
codex/particle-collection-clear

Conversation

@luzhuang

@luzhuang luzhuang commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add clear() to SubEmittersModule
  • add clear() to CustomDataModule
  • preserve each module cleanup semantics while removing all entries

Why clear is required

Runtime-v2 Prefab componentProps overrides 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:

  • field absent: preserve the inherited collection
  • field present with []: replace it with an empty collection
  • field present with entries: replace it with exactly those entries

Builder 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 clear followed by the authored add calls.

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 build
  • pnpm exec vitest run tests/src/core/particle/SubEmitter.test.ts tests/src/core/particle/CustomData.test.ts — 42 tests passed
  • linked this Engine build with the current Editor resource package compiler and rendered/replayed energy-core-burst.package with no browser warnings or errors

Consumer

Required by galacean/editor#3805 for source-v2 particle collection overrides.

Summary by CodeRabbit

  • New Features

    • Added the ability to clear all custom particle data streams at once.
    • Added the ability to remove all configured sub-emitters at once.
    • Clearing sub-emitters now refreshes particle rendering state automatically.
  • Tests

    • Added coverage verifying custom data and sub-emitter cleanup behavior.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Added clear() methods to particle custom-data and sub-emitter modules, with tests covering stream removal, slot removal, and transform-feedback reset.

Changes

Particle module clearing

Layer / File(s) Summary
Custom data stream clearing
packages/core/src/particle/modules/CustomDataModule.ts, tests/src/core/particle/CustomData.test.ts
CustomDataModule.clear() removes all curve and gradient streams, with tests verifying both collections are empty.
Sub-emitter slot clearing
packages/core/src/particle/modules/SubEmittersModule.ts, tests/src/core/particle/SubEmitter.test.ts
SubEmittersModule.clear() removes all sub-emitter slots and refreshes transform-feedback state, with tests verifying the slot list and state reset.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: enhancement, particle

Suggested reviewers: hhhhkrx, cptbtptpbcptdtptp

Poem

I’m a bunny with a tidy little broom,
Clearing particle streams from every room.
Sub-emitters hop away, feedback turns bright,
Curves and gradients vanish just right.
Clean arrays, clean shaders—what a delight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding clear APIs for particle collection modules.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/particle-collection-clear

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@luzhuang
luzhuang force-pushed the codex/particle-collection-clear branch from 1d08a06 to 05963e9 Compare July 16, 2026 11:09

@GuoLei1990 GuoLei1990 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

总结

SubEmittersModuleCustomDataModule 各加一个公开 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

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.30435% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.64%. Comparing base (9fe48c6) to head (05963e9).

Files with missing lines Patch % Lines
...ges/core/src/particle/modules/SubEmittersModule.ts 81.81% 2 Missing ⚠️
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     
Flag Coverage Δ
unittests 79.64% <91.30%> (-0.19%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@luzhuang
luzhuang marked this pull request as draft July 16, 2026 11:15
@luzhuang
luzhuang marked this pull request as ready for review July 16, 2026 11:15
@GuoLei1990
GuoLei1990 requested a review from hhhhkrx July 21, 2026 07:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants