Skip to content

refactor(camera): share property list between init and clone#8878

Merged
willeastcott merged 2 commits into
mainfrom
refactor/camera-clone-properties
Jun 11, 2026
Merged

refactor(camera): share property list between init and clone#8878
willeastcott merged 2 commits into
mainfrom
refactor/camera-clone-properties

Conversation

@willeastcott

Copy link
Copy Markdown
Contributor

Summary

First in a planned series of small PRs improving structural consistency across framework/components, continuing #8876 / #8873.

Most component systems duplicate their property list between initializeComponentData and cloneComponent (an inline array in one, a hand-written object literal in the other). The camera system shows why that matters: the two lists had driftedfog and clearDepth were initialized but missing from the clone literal, so cloning an entity silently dropped those camera settings.

This PR:

  • Hoists the property list to a module-level _properties array (the pattern already used by light, gsplat, render and particle-system) and drives both initializeComponentData and cloneComponent from it, so the lists can no longer drift.
  • Fixes the drift: cloned cameras now copy fog and clearDepth. This is the one intentional behavior change in the PR.
  • Adds test/framework/components/camera/component.test.mjs (no camera component test existed). The clone round-trip test was written first and failed on clearDepth/fog before the system change; it now passes and locks in clone behavior for all shared properties.
  • Drops the unused legacy properties parameter from the initializeComponentData override.

Everything else is behavior-preserving: init order, type conversions (rect/scissorRect/clearColor arrays) and clone reference semantics are unchanged.

Planned follow-ups (separate PRs, in order)

  1. Clone-from-list for systems that already have _properties (button, scroll-view, scrollbar, collision)
  2. Hoist inline lists in model, sound, rigid-body
  3. Animation system (isolated due to its post-add clone assignment)
  4. Standardize beforeremove handler naming across all systems

Testing

  • New CameraComponent tests: defaults, full clone round-trip, enabled-state clone
  • Full npm test suite passes (1817 passing)
  • ESLint clean on changed files

🤖 Generated with Claude Code

Hoist the property list from initializeComponentData to a module-level
_properties array (matching light/gsplat/render) and drive cloneComponent
from the same list, so the two can no longer drift.

The lists had already drifted: cloneComponent was missing fog and
clearDepth, so cloning an entity silently dropped those camera settings.
The new CameraComponent unit test demonstrated the bug before the fix
and now locks in clone behavior for all shared properties.

Also drops the unused legacy `properties` parameter from the
initializeComponentData override.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Refactors the CameraComponentSystem to drive both initialization and cloning from a single shared property list, preventing drift between the two code paths and fixing previously-missed camera settings during entity cloning.

Changes:

  • Hoists camera component property names to a module-level _properties list and reuses it in initializeComponentData and cloneComponent.
  • Fixes cloning drift so fog and clearDepth are now cloned as well.
  • Adds a new CameraComponent test suite covering defaults and clone behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/framework/components/camera/system.js Centralizes the camera property list and uses it for both initialization and cloning to prevent future drift.
test/framework/components/camera/component.test.mjs Adds new unit tests for camera defaults and cloning behavior (with a few suggested additions to better cover all cloned properties).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/framework/components/camera/component.test.mjs
Comment thread test/framework/components/camera/component.test.mjs
Comment thread test/framework/components/camera/component.test.mjs
Address review feedback: set non-default values for calculateProjection,
calculateTransform, gammaCorrection and toneMapping in the clone
round-trip test so regressions in cloning those fields are caught.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@willeastcott willeastcott merged commit 600b3c7 into main Jun 11, 2026
8 checks passed
@willeastcott willeastcott deleted the refactor/camera-clone-properties branch June 11, 2026 19:14
willeastcott added a commit that referenced this pull request Jun 11, 2026
…sts (#8879)

Button, scroll-view, scrollbar and collision systems already define a
module-level _properties array used by initializeComponentData, but each
duplicated the same list as a hand-written object literal in
cloneComponent. Build the clone data from the shared list instead (the
camera pattern from #8878) so the two paths can no longer drift.

Collision keeps its two intentional differences explicit: type is
initialized outside the property list, and shape is excluded because the
type implementation creates it during initialization.

No behavior changes - all four clone literals matched their lists 1:1.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
willeastcott added a commit that referenced this pull request Jun 11, 2026
…body (#8880)

Continue the pattern from #8878/#8879: hoist the inline property list in
initializeComponentData to a module-level _properties array and drive
cloneComponent from the same list, so the two paths cannot drift.

Special-case handling is preserved:
- model: material/materialAsset are still resolved by the dedicated
  clone logic, mapping is still shallow-copied via extend
- sound: slots are still converted back to plain option objects
- rigid-body: linearFactor/angularFactor now pass the component Vec3s
  directly instead of converting to arrays; the component setters copy
  values, so the end state is identical with no aliasing

Also drops the unused legacy properties parameter from the
initializeComponentData overrides.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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