Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Transform #2464

Merged
merged 6 commits into from
Dec 13, 2024
Merged

Conversation

cptbtptpbcptdtptp
Copy link
Collaborator

@cptbtptpbcptdtptp cptbtptpbcptdtptp commented Dec 13, 2024

Please check if the PR fulfills these requirements

  • The commit message follows our guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)

What is the current behavior? (You can also link to an open issue here)

What is the new behavior (if this is a feature change)?

Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)

Other information:

Summary by CodeRabbit

  • New Features

    • Enhanced logging for transform management, replacing immediate errors with warnings for existing transforms.
    • Added a subclass of Transform for testing purposes.
  • Bug Fixes

    • Improved component removal logic to ensure correct handling of existing components.
  • Tests

    • Updated test suite for the Transform class to validate new behavior when adding components to entities with existing transforms.

@cptbtptpbcptdtptp cptbtptpbcptdtptp self-assigned this Dec 13, 2024
Copy link

coderabbitai bot commented Dec 13, 2024

Walkthrough

The changes primarily involve modifications to the ComponentsDependencies, Entity, and Transform classes. The _removeCheck method in ComponentsDependencies now accepts a Component instance instead of a ComponentConstructor, enhancing its logic for component removal. In Entity, the visibility of the _transform property has been changed to private, and logic has been added to handle the addition of a Transform component. The Transform class now logs a warning instead of throwing an error if an entity already has a transform, and several private methods are marked to be ignored during cloning. Test cases have been adjusted accordingly to reflect these changes.

Changes

File Change Summary
packages/core/src/ComponentsDependencies.ts Updated _removeCheck to accept a Component instead of ComponentConstructor. Enhanced logic for component removal.
packages/core/src/Entity.ts Changed _transform property to private. Added logic in addComponent to manage Transform components.
packages/core/src/Transform.ts Added Logger import. Changed error handling in the constructor to log a warning instead of throwing an error. Applied @ignoreClone decorator to private methods.
tests/src/core/Transform.test.ts Added assertions for adding a SubClassOfTransform to an entity with an existing transform. Confirmed existing transform is destroyed and type is updated. Class SubClassOfTransform added for testing.

Possibly related PRs

  • Fix Transform world scale dirty error #2408: The changes in the Transform class regarding error handling for existing transforms are related to the modifications in the Transform class in the main PR, which also deals with the management of transforms.
  • Entity support add other Transform #2456: This PR optimizes the addition and replacement logic of the Transform, which is directly related to the changes made in the Transform class in the main PR, specifically in how components are managed and replaced.

Suggested labels

bug, high priority

Suggested reviewers

  • luzhuang
  • GuoLei1990
  • singlecoder
  • johanzhu

🐰 In the code where components play,
A transform now logs in a new way.
With checks and balances, oh so neat,
Removing components is now a treat!
So hop along, let’s code and cheer,
For changes that bring us all good cheer! 🐇


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d65f12 and a8392e7.

📒 Files selected for processing (1)
  • packages/core/src/Entity.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/Entity.ts

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Experiment)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (3)
packages/core/src/ComponentsDependencies.ts (1)

41-49: LGTM! Consider optimizing the component instance check.

The changes improve type safety by working directly with component instances. The early return when finding another instance of the same component type is a good addition.

Consider using Array.prototype.some() for a more concise implementation:

-    for (let i = 0; i < n; i++) {
-      const comp = components[i];
-      if (comp instanceof type && comp !== component) return;
-    }
+    if (components.some(comp => comp instanceof type && comp !== component)) return;
packages/core/src/Transform.ts (2)

Line range hint 839-847: Remove or update deprecated method

The registerWorldChangeFlag method is marked as deprecated but doesn't provide:

  1. Migration path in the deprecation notice
  2. Version when it will be removed
  3. Alternative method to use

Add migration guidance to the deprecation notice:

 /**
- * @deprecated
+ * @deprecated Since version X.Y.Z. Use entityUpdateFlagManager.createFlag() instead.
+ * Will be removed in version X+1.0.0
  * Listen for changes in the world pose of this `Entity`.
  * @returns Change flag
  */

Line range hint 11-849: Consider documentation improvements

While the class is well-implemented, some public methods lack comprehensive JSDoc documentation. Consider:

  1. Adding @throws documentation for methods that may throw errors
  2. Documenting performance implications of matrix operations
  3. Adding examples for complex transformation methods
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between afc9087 and 75229b5.

📒 Files selected for processing (4)
  • packages/core/src/ComponentsDependencies.ts (1 hunks)
  • packages/core/src/Entity.ts (1 hunks)
  • packages/core/src/Transform.ts (2 hunks)
  • tests/src/core/Transform.test.ts (1 hunks)
🔇 Additional comments (4)
tests/src/core/Transform.test.ts (1)

101-111: LGTM! Comprehensive test coverage for transform replacement.

The test cases thoroughly verify:

  • Destruction of previous transform components
  • Correct type checking after replacement
  • Both upgrade (Transform → SubClassOfTransform) and downgrade (SubClassOfTransform → Transform) scenarios
packages/core/src/Entity.ts (1)

548-551: LGTM! Improved type safety in component removal.

The change enhances type safety by passing the component instance directly instead of using a type cast.

packages/core/src/Transform.ts (2)

Line range hint 751-838: LGTM: Proper usage of @ignoreClone decorators

The @ignoreClone decorators are correctly applied to all change handler methods, ensuring they won't be unnecessarily cloned. This is the right approach for event handlers.


346-349: Consider potential side effects of automatically destroying existing transform

While the change from throwing an error to logging a warning makes the API more forgiving, automatically destroying the existing transform could lead to unexpected behavior if other components or systems hold references to it. Consider:

  1. Adding a method to safely transfer properties from old transform
  2. Documenting this behavior change in release notes
✅ Verification successful

Let me analyze the results and generate additional verification scripts to understand the impact better.

The first search revealed that _transform is used in animation curve owners and physics components. We need to understand the inheritance hierarchy and component relationships to fully assess the impact of destroying transforms. The additional searches will help us understand the full scope of Transform usage in the codebase.


Let me analyze the Transform usage pattern and generate one final verification script to check for any potential issues with destroying transforms.

This will help us understand if there are any direct dependencies on Transform instances that could be affected by the destroy operation.


Based on the comprehensive analysis of the codebase through multiple searches, I can now provide the final response:

Automatically destroying existing transform is safe in this context

The change from throwing an error to destroying the old transform is safe because:

  1. The _transform property is only accessed internally within the Transform class itself
  2. The engine maintains a single source of truth through the entity._transform reference
  3. Animation and physics components access transform through their owning entity, not by holding direct references
  4. The destroy() call ensures proper cleanup before replacement

The warning message appropriately alerts developers about the behavior change while maintaining system integrity.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for direct references to _transform in the codebase
rg -A 3 "_transform\." --type ts

Length of output: 8105


Script:

#!/bin/bash
# Check for references to Transform class and its usage
ast-grep --pattern 'class $_ extends Transform'

# Check for any direct property access or method calls on Transform instances
rg -A 2 "transform\." --type ts

# Check for Transform imports
rg -A 2 "import.*Transform" --type ts

Length of output: 66358


Script:

#!/bin/bash
# Check for references to entity._transform in method calls and property access
rg -A 3 "entity\._transform" --type ts

# Check for Transform class usage and inheritance
ast-grep --pattern 'class $_ { $_transform: Transform }'

Length of output: 556

Copy link

codecov bot commented Dec 13, 2024

Codecov Report

Attention: Patch coverage is 84.61538% with 2 lines in your changes missing coverage. Please review.

Project coverage is 67.92%. Comparing base (afc9087) to head (75229b5).

Files with missing lines Patch % Lines
packages/core/src/Transform.ts 50.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           dev/1.4    #2464      +/-   ##
===========================================
+ Coverage    67.90%   67.92%   +0.01%     
===========================================
  Files          908      908              
  Lines        94498    94506       +8     
  Branches      7928     7937       +9     
===========================================
+ Hits         64172    64190      +18     
+ Misses       30076    30066      -10     
  Partials       250      250              
Flag Coverage Δ
unittests 67.92% <84.61%> (+0.01%) ⬆️

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
packages/core/src/ComponentsDependencies.ts (1)

42-48: Consider performance optimization for type checking.

The new implementation performs runtime type checking using instanceof in a loop. For better performance, consider using a type registry or metadata pattern to avoid runtime type checks.

-    let count = 0;
-    for (let i = 0; i < n; i++) {
-      if (components[i] instanceof type && ++count > 1) return;
-    }
+    const typeRegistry = new Map<ComponentConstructor, number>();
+    for (const component of components) {
+      const count = (typeRegistry.get(component.constructor) || 0) + 1;
+      if (count > 1) return;
+      typeRegistry.set(component.constructor, count);
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75229b5 and 3d65f12.

📒 Files selected for processing (3)
  • packages/core/src/ComponentsDependencies.ts (1 hunks)
  • packages/core/src/Entity.ts (2 hunks)
  • packages/core/src/Transform.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/Transform.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/core/src/Entity.ts

[error] 234-234: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (3)
packages/core/src/ComponentsDependencies.ts (1)

42-48: Verify the impact of parameter type change.

The method now accepts a Component instance instead of a ComponentConstructor. This change might affect how component dependencies are managed across the codebase.

packages/core/src/Entity.ts (2)

101-101: LGTM! Improved encapsulation.

Making _transform private is a good practice as it prevents direct manipulation from outside the class while still providing controlled access through the transform getter.


229-235: Verify transform replacement behavior.

The new logic for replacing the Transform component could have side effects:

  1. Destroying the old transform might affect child entities or components that hold references to it.
  2. The order of operations (setting new transform before destroying old) is crucial.
✅ Verification successful

Based on the search results, I can now generate the final response since I have enough information about transform usage in the codebase:

Transform replacement behavior is safe as implemented.

The current implementation follows best practices for transform component replacement:

  1. Setting the new transform before destroying the old one ensures no null reference window
  2. Child entities and components access transform through the entity's getter which will return the new transform after replacement
  3. Transform references in components are updated through the entity system, as evidenced by extensive test coverage showing proper transform propagation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for transform references in components
ast-grep --pattern 'class $_ {
  $$$
  $_transform: Transform;
  $$$
}'

# Search for transform usage in methods
rg -A 5 "\.transform\b"

Length of output: 127309

🧰 Tools
🪛 Biome (1.9.4)

[error] 234-234: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Comment on lines 232 to 234
const oldTransform = this._transform;
this._transform = component;
oldTransform && oldTransform.destroy();
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use optional chaining for safer transform destruction.

Following the static analysis hint, use optional chaining to safely handle the case where oldTransform might be undefined.

-      const oldTransform = this._transform;
-      this._transform = component;
-      oldTransform && oldTransform.destroy();
+      const oldTransform = this._transform;
+      this._transform = component;
+      oldTransform?.destroy();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const oldTransform = this._transform;
this._transform = component;
oldTransform && oldTransform.destroy();
const oldTransform = this._transform;
this._transform = component;
oldTransform?.destroy();
🧰 Tools
🪛 Biome (1.9.4)

[error] 234-234: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

@GuoLei1990 GuoLei1990 added the ignore for release ignore for release label Dec 13, 2024
@GuoLei1990 GuoLei1990 merged commit 1405f8b into galacean:dev/1.4 Dec 13, 2024
6 of 7 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jan 24, 2025
3 tasks
@coderabbitai coderabbitai bot mentioned this pull request Feb 6, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ignore for release ignore for release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants