Skip to content

feat(loader): support $class refs and numeric SpecularMode in v2 scene#2994

Merged
GuoLei1990 merged 4 commits into
galacean:dev/2.0from
luzhuang:feat/runtime-class-ref
May 12, 2026
Merged

feat(loader): support $class refs and numeric SpecularMode in v2 scene#2994
GuoLei1990 merged 4 commits into
galacean:dev/2.0from
luzhuang:feat/runtime-class-ref

Conversation

@luzhuang
Copy link
Copy Markdown
Contributor

@luzhuang luzhuang commented May 12, 2026

Summary

针对 v2 scene 格式的两处 loader 扩展,集中在 packages/loader

$class value sentinel(ReflectionParser)

  • ReflectionParser._resolveValue 新增 { $class: "ClassName" } 解析分支,通过 Loader.getClass 拿到已注册的构造函数本身(不实例化),用于 factory 风格的方法调用,例如:
    { "method": "addEffect", "args": [{ "$class": "BloomEffect" }] }
  • 把原本只服务 $type 的类查找逻辑抽成 _getRegisteredClass(value, sentinel),统一加上「必须是非空字符串」和「类必须已注册」两层校验,$type$class 共用同一份错误信息和兜底
  • CommonSchema.ts 新增 ClassRef 接口与 ComponentRef 等其他 ref 形态对齐

数值化 SpecularMode(SceneSchema)

  • SpecularMode 枚举从字符串 "Sky"/"Custom" 改为数字 0/1,与 v2 scene 中其他枚举(FogModeShadowCascadesMode 等)的数值化约定保持一致,序列化时体积更小、解析时无字符串比较

Test plan

  • tests/src/loader/SceneFormatV2.test.ts:新增 $class 解析用例
    • parser 直接调用:addEffect({ $class: "BloomEffect" })parseCalls,断言生成的 effect 是 BloomEffect 实例且 result.props 正确写回
    • 完整 scene 解析路径:通过 SceneParser 跑端到端,确认 component calls 中的 $class 参数能落到实际组件上
  • tests/src/loader/SceneFormatV2.test.ts:新增 SpecularMode 数值断言(Sky === 0Custom === 1

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Scene configs can reference registered class constructors via a $class property for direct component/effect instantiation.
    • Polymorphic value resolution improved with stricter validation and clearer, consistent error handling.
  • Schema Updates

    • Added a class-reference schema type.
    • Specular mode values changed to numeric representation.
  • Tests

    • Expanded tests for $class resolution, error cases, and scene parsing with effect instances.

Review Change Stack

@luzhuang luzhuang requested a review from GuoLei1990 May 12, 2026 06:07
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8a7c0a63-f7a8-4280-b7d5-e9af9f347c18

📥 Commits

Reviewing files that changed from the base of the PR and between 8d96a71 and 213f387.

📒 Files selected for processing (1)
  • packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts

Walkthrough

Adds a ClassRef schema, extends ReflectionParser to resolve $class (with new helpers that validate and lookup registered classes via Loader), converts SpecularMode enum members to numeric values, and updates tests to cover enum changes and $class resolution/usage in parser and scene instantiation flows.

Changes

Class reference resolution and schema updates

Layer / File(s) Summary
ClassRef schema contract
packages/loader/src/schema/CommonSchema.ts
Exported ClassRef interface with $class: string property defines the contract for referencing registered class constructors.
ReflectionParser $class resolution
packages/loader/src/resource-deserialize/resources/parser/ReflectionParser.ts
Documentation updated to include $class in value resolution priority. _resolveValue refactored to delegate class lookup/validation to new _getRegisteredClass/_resolveRegisteredClass helpers; new $class branch resolves registered constructors and $type delegates to the same validation/lookup with instantiation behavior.
SpecularMode enum numeric values
packages/loader/src/schema/SceneSchema.ts
SpecularMode enum members converted from string literals to numeric values (Sky = 0, Custom = 1).
Test coverage for class resolution and enum values
tests/src/loader/SceneFormatV2.test.ts
Test setup registers PostProcess and BloomEffect. Added assertions for SpecularMode numeric values. New tests verify $class call-arg behavior in ReflectionParser and SceneParser flows, and add negative tests for invalid/non-string/empty/unregistered $type and $class inputs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I'm a rabbit in the code, quick and bright,
$class hops forward into the light,
Enums count neat, zero then one,
Tests bloom where parsing is done,
Constructors found — the scene feels right 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main changes: adding support for $class refs and numeric SpecularMode in v2 scene format, which are the primary features introduced across all modified files.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@luzhuang luzhuang changed the title Feat/runtime class ref feat(loader): support $class refs and numeric SpecularMode in v2 scene May 12, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 12, 2026

Codecov Report

❌ Patch coverage is 91.66667% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.10%. Comparing base (e19b764) to head (213f387).
⚠️ Report is 1 commits behind head on dev/2.0.

Files with missing lines Patch % Lines
...e-deserialize/resources/parser/ReflectionParser.ts 91.17% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           dev/2.0    #2994      +/-   ##
===========================================
- Coverage    78.19%   78.10%   -0.10%     
===========================================
  Files          906      900       -6     
  Lines        99892    99255     -637     
  Branches     10194    10198       +4     
===========================================
- Hits         78112    77521     -591     
+ Misses       21610    21563      -47     
- Partials       170      171       +1     
Flag Coverage Δ
unittests 78.10% <91.66%> (-0.10%) ⬇️

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

☔ View full report in Codecov by Sentry.
📢 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.

GuoLei1990

This comment was marked as outdated.

Add negative coverage for the shared _getRegisteredClass validator
introduced alongside the $class sentinel:

- $class: empty string, non-string, unregistered class name
- $type: non-string (string-but-unregistered already covered)

Also adds a positive parseProps case for $class so the value-level
resolution path (not just call args) is covered.
GuoLei1990

This comment was marked as outdated.

Both v2 sentinel branches duplicated the same try/catch + Promise.reject
template to bridge _getRegisteredClass's synchronous throw into the
_resolveValue promise chain.

Extract _resolveRegisteredClass as the sync-to-async adapter:
- _getRegisteredClass keeps its core responsibility (lookup + validation),
  returning a class synchronously or throwing on invalid input.
- _resolveRegisteredClass adapts that throw into Promise.reject so call
  sites can fold directly into the resolver chain.

The naming split (get vs resolve) mirrors the sync vs async semantic
boundary. Behavior is unchanged — all existing $type/$class negative
tests continue to assert the same error messages.
Copy link
Copy Markdown
Member

@GuoLei1990 GuoLei1990 left a comment

Choose a reason for hiding this comment

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

总结

本轮 commit 213f387 完整实现了 _resolveRegisteredClass 抽取——_getRegisteredClass 保持同步 throw 签名,_resolveRegisteredClass 作为 sync-to-async 适配层,两处调用点均已简化。上轮唯一存活的 P2 已关闭,无新问题。

代码已可合并。

@GuoLei1990 GuoLei1990 merged commit 6732c76 into galacean:dev/2.0 May 12, 2026
11 of 12 checks passed
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.

2 participants