-
-
Notifications
You must be signed in to change notification settings - Fork 311
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
Replace Transform
#2464
Conversation
WalkthroughThe changes primarily involve modifications to the Changes
Possibly related PRs
Suggested labels
Suggested reviewers
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 methodThe
registerWorldChangeFlag
method is marked as deprecated but doesn't provide:
- Migration path in the deprecation notice
- Version when it will be removed
- 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 improvementsWhile the class is well-implemented, some public methods lack comprehensive JSDoc documentation. Consider:
- Adding @throws documentation for methods that may throw errors
- Documenting performance implications of matrix operations
- Adding examples for complex transformation methods
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 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:
- Adding a method to safely transfer properties from old transform
- 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:
- The
_transform
property is only accessed internally within the Transform class itself - The engine maintains a single source of truth through the entity._transform reference
- Animation and physics components access transform through their owning entity, not by holding direct references
- 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
Codecov ReportAttention: Patch coverage is
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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this 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
📒 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:
- Destroying the old transform might affect child entities or components that hold references to it.
- 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:
- Setting the new transform before destroying the old one ensures no null reference window
- Child entities and components access transform through the entity's getter which will return the new transform after replacement
- 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)
packages/core/src/Entity.ts
Outdated
const oldTransform = this._transform; | ||
this._transform = component; | ||
oldTransform && oldTransform.destroy(); |
There was a problem hiding this comment.
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.
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)
Please check if the PR fulfills these requirements
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
Bug Fixes
Tests