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

Put layerIndex and layer in AnimatorLayerData to reduce code #2390

Merged
merged 2 commits into from
Sep 26, 2024

Conversation

luzhuang
Copy link
Contributor

@luzhuang luzhuang commented Sep 26, 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 animator functionality with simplified state updates.
    • Added new properties to improve layer data handling.
  • Refactor

    • Streamlined method signatures for better readability and maintainability.

@luzhuang luzhuang added animation Built-in animation system related functions ignore for release ignore for release labels Sep 26, 2024
@luzhuang luzhuang added this to the 1.4 milestone Sep 26, 2024
Copy link

coderabbitai bot commented Sep 26, 2024

Walkthrough

The pull request includes significant refactoring of the Animator class, specifically the _updateState method, which now accepts fewer parameters, enhancing clarity. The AnimatorLayerData class has also been updated to include new properties for better state management. These changes aim to streamline the animator's functionality and improve code maintainability.

Changes

File Path Change Summary
packages/core/src/animation/Animator.ts Refactored _updateState method to accept only layerData, deltaTime, and aniUpdate. Updated calls throughout the class.
packages/core/src/animation/internal/AnimatorLayerData.ts Added layerIndex (number) and layer (AnimatorControllerLayer) properties to AnimatorLayerData.

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • GuoLei1990

Poem

In the realm of code where bunnies play,
Animators dance in a streamlined way.
With fewer calls and clearer paths,
Our layers hop with joyful laughs.
So let us cheer for changes bright,
In the code, we find delight! 🐇✨


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 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: 5

🧹 Outside diff range and nitpick comments (4)
packages/core/src/animation/internal/AnimatorLayerData.ts (1)

Line range hint 1-31: Summary and Recommendations

  1. The new properties layerIndex and layer have been added to AnimatorLayerData as intended.
  2. The import for AnimatorControllerLayer has been correctly added.
  3. There are concerns about the initialization and usage of the new properties.
  4. It's unclear how these changes contribute to code reduction mentioned in the PR objectives.

Recommendations:

  1. Initialize the new properties to prevent potential undefined behavior.
  2. Provide more context on how these properties will be used within the class and in the broader codebase.
  3. Clarify how these changes contribute to code reduction, possibly by showing changes in other files that benefit from these new properties.
  4. Confirm that these changes don't introduce breaking changes, considering the @internal nature of the class.
  5. Consider adding tests and updating documentation as mentioned in the PR checklist.

These changes seem to be part of a larger refactoring effort. To ensure the changes are beneficial:

  1. Document the purpose of these new properties in the class.
  2. If these properties are meant to replace some existing code patterns, consider deprecating the old patterns to guide future development.
  3. Ensure that the addition of these properties doesn't violate the single responsibility principle for the AnimatorLayerData class.
packages/core/src/animation/Animator.ts (3)

681-681: Use explicit if statement instead of short-circuit evaluation for clarity

At line 681, short-circuit evaluation is used to conditionally call _updateState. While this is concise, using an explicit if statement improves readability and makes the code's intent clearer.

Refactor the code as follows:

-          remainDeltaTime > 0 && this._updateState(layerData, remainDeltaTime, aniUpdate);
+          if (remainDeltaTime > 0) {
+            this._updateState(layerData, remainDeltaTime, aniUpdate);
+          }

798-798: Use explicit if statement instead of short-circuit evaluation for clarity

Similar to line 681, at line 798, replacing the short-circuit evaluation with an if statement enhances code readability.

Refactor the code as follows:

-          remainDeltaTime > 0 && this._updateState(layerData, remainDeltaTime, aniUpdate);
+          if (remainDeltaTime > 0) {
+            this._updateState(layerData, remainDeltaTime, aniUpdate);
+          }

908-908: Use explicit if statement instead of short-circuit evaluation for clarity

At line 908, using an explicit if statement instead of short-circuit evaluation makes the code more readable and the execution flow clearer.

Refactor the code as follows:

-          remainDeltaTime > 0 && this._updateState(layerData, remainDeltaTime, aniUpdate);
+          if (remainDeltaTime > 0) {
+            this._updateState(layerData, remainDeltaTime, aniUpdate);
+          }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between afb7423 and 04b2476.

📒 Files selected for processing (2)
  • packages/core/src/animation/Animator.ts (15 hunks)
  • packages/core/src/animation/internal/AnimatorLayerData.ts (2 hunks)
🧰 Additional context used
Biome
packages/core/src/animation/Animator.ts

[error] 562-562: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

🔇 Additional comments not posted (4)
packages/core/src/animation/internal/AnimatorLayerData.ts (3)

1-1: LGTM: Import statement added for new property type.

The import for AnimatorControllerLayer has been correctly added to support the new layer property.


Line range hint 9-31: Clarification needed on code reduction mentioned in PR objectives.

The PR objectives mention "reducing code", but the changes in this file only add new properties. While this might be part of a larger refactoring effort, it's not clear from this file alone how these changes contribute to code reduction.

Could you please provide more context on how these new properties help in reducing code elsewhere in the project? This would help in understanding the full impact of these changes.

Also, given that this class is marked as @internal, can you confirm that these changes don't introduce any breaking changes for library users?

To get a better understanding of the impact, let's check for files that import and use AnimatorLayerData:

#!/bin/bash
# Search for files that import and use AnimatorLayerData
rg --type typescript -e "import.*AnimatorLayerData" -A 10 | rg -e "new AnimatorLayerData" -B 10

12-13: ⚠️ Potential issue

New properties added, but initialization and usage unclear.

The new properties layerIndex and layer have been added to the AnimatorLayerData class as per the PR objective. However, there are some concerns:

  1. These properties are not initialized, which could lead to undefined behavior.
  2. The purpose and usage of these properties within the class are not clear from this change alone.

Could you please provide more context on how these properties will be used and ensure they are properly initialized?

Consider initializing these properties, either in the constructor or with default values:

layerIndex: number = -1; // or any appropriate default value
layer: AnimatorControllerLayer | null = null;

To understand the usage of these new properties, let's check for their occurrences in the codebase:

✅ Verification successful

New properties are properly integrated and initialized across the codebase.

After searching the codebase, it’s clear that the layerIndex and layer properties in the AnimatorLayerData class are consistently initialized and utilized across multiple files. Their addition aligns with the project's objectives, and there are no indications of undefined behavior.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of layerIndex and layer properties
rg --type typescript -e "layerIndex" -e "\.layer\b" --glob "!**/AnimatorLayerData.ts"

Length of output: 132


Script:

#!/bin/bash
# Search for usages of layerIndex and layer properties in TypeScript files, excluding AnimatorLayerData.ts
rg -e "layerIndex" -e "\.layer\b" --glob "*.ts" --glob "*.tsx" --glob "!**/AnimatorLayerData.ts"

Length of output: 13118

packages/core/src/animation/Animator.ts (1)

198-198: Refactored _updateState call enhances code maintainability

The call to _updateState now utilizes layerData directly, eliminating the need to pass layerIndex and layer separately. This refactoring reduces parameter redundancy and improves code readability.

aniUpdate: boolean
): void {
private _updateState(layerData: AnimatorLayerData, deltaTime: number, aniUpdate: boolean): void {
const { layerIndex, layer } = layerData;
let { weight } = layer;
const additive = layer.blendingMode === AnimatorLayerBlendingMode.Additive;

layerIndex === 0 && (weight = 1.0);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid assignments within expressions to enhance code clarity

According to static analysis, at line 562, there is an assignment used within an expression. Assignments within expressions can be confusing and may lead to unintended side effects, as expressions are generally expected to be side-effect-free.

Refactor the code to separate the assignment from the expression. For example, if the code is:

case LayerState.Playing:
  layerData.layerState = LayerState.Playing;
  // Additional code...

Ensure that assignments are not embedded within conditions or expression statements.

🧰 Tools
Biome

[error] 562-562: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


const transition =
(anyStateTransitions.count &&
this._applyTransitionsByCondition(layerIndex, layerData, layer, anyStateTransitions, aniUpdate)) ||
(anyStateTransitions.count && this._applyTransitionsByCondition(layerData, anyStateTransitions, aniUpdate)) ||
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Check for transition before recursive call to _updateState

At line 970, when applying transitions, ensure that the recursive call to _updateState only occurs if a valid transition is found. This prevents potential infinite recursion or unintended behavior.

Verify that transition is not null before making the recursive call.

@@ -1195,7 +1171,7 @@
if (isSoloMode && !transition.solo) continue;

if (this._checkConditions(transition)) {
if (this._applyTransition(layerIndex, layerData, layer, transition, aniUpdate)) {
if (this._applyTransition(layerData, transition, aniUpdate)) {
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consolidate transition checks to reduce code duplication

The condition checking and application of transitions at lines 1174, 1217, and 1242 follow a similar pattern. Consider refactoring these sections into a single method to reduce code duplication and improve maintainability.

Extract the common logic into a helper function that handles the transition checking and application.

Comment on lines 1497 to 1517
private _checkAnyAndEntryState(layerData: AnimatorLayerData, remainDeltaTime: number, aniUpdate: boolean): void {
const { layerIndex, layer } = layerData;
const { stateMachine } = layer;
const { _anyStateTransitionCollection: anyStateTransitions, _entryTransitionCollection: entryTransitions } =
stateMachine;
let transition: AnimatorStateTransition;

transition =
anyStateTransitions.count &&
this._applyTransitionsByCondition(layerIndex, layerData, layer, anyStateTransitions, aniUpdate);
anyStateTransitions.count && this._applyTransitionsByCondition(layerData, anyStateTransitions, aniUpdate);

if (!transition) {
transition =
entryTransitions.count &&
this._applyTransitionsByCondition(layerIndex, layerData, layer, entryTransitions, aniUpdate);
transition = entryTransitions.count && this._applyTransitionsByCondition(layerData, entryTransitions, aniUpdate);
}

if (transition) {
this._updateState(layerIndex, layerData, layer, remainDeltaTime, aniUpdate);
this._updateState(layerData, remainDeltaTime, aniUpdate);
} else {
const defaultState = stateMachine.defaultState;
if (defaultState) {
this._preparePlay(defaultState, layerIndex);
this._updateState(layerIndex, layerData, layer, remainDeltaTime, aniUpdate);
this._updateState(layerData, remainDeltaTime, aniUpdate);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure default state is properly initialized

In the _checkAnyAndEntryState method (lines 1497-1517), make sure that the default state of the state machine is correctly initialized when no transitions are applied. This ensures that the animator starts in a valid state.

Verify that defaultState is not null and handle the case where it might be undefined to prevent runtime errors.

packages/core/src/animation/Animator.ts Show resolved Hide resolved
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 (1)
packages/core/src/animation/Animator.ts (1)

Line range hint 1-1574: Overall approval: Effective implementation of AnimatorLayerData enhancements

The changes throughout the file consistently and effectively implement the use of AnimatorLayerData to store and access layerIndex and layer. This refactoring aligns well with the PR objectives, resulting in reduced parameter passing, simplified method signatures, and improved code organization. The modifications enhance the maintainability and readability of the animator system.

However, there's one minor issue to address:

On line 562, there's an assignment within an expression:

layerData.layerIndex === 0 && (weight = 1.0);

This style can be confusing and is generally discouraged.

Consider refactoring this line to use a more explicit if statement:

if (layerData.layerIndex === 0) {
  weight = 1.0;
}

This change will improve code clarity and adhere to best practices for avoiding assignments within expressions.

🧰 Tools
Biome

[error] 562-562: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 04b2476 and d7becf5.

📒 Files selected for processing (1)
  • packages/core/src/animation/Animator.ts (15 hunks)
🧰 Additional context used
Biome
packages/core/src/animation/Animator.ts

[error] 562-562: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

🔇 Additional comments not posted (7)
packages/core/src/animation/Animator.ts (7)

557-557: Simplified method signature improves code clarity

The removal of layerIndex and layer parameters from the _updateState method signature aligns with the PR objectives. This change reduces redundant parameter passing and improves code readability by relying on the AnimatorLayerData structure to contain this information.


558-578: Consistent use of AnimatorLayerData improves code maintainability

The changes in the _updateState method body consistently apply the new approach of using AnimatorLayerData to access layer and layerIndex. This reduces code duplication and improves maintainability. The extraction of layer from layerData and the updated condition for setting weight demonstrate a more cohesive use of the AnimatorLayerData structure.

🧰 Tools
Biome

[error] 562-562: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


605-605: Efficient use of AnimatorLayerData enhances code structure

The changes in the _updatePlayingState method demonstrate a consistent and efficient use of the AnimatorLayerData structure. The extraction of anyStateTransitions from layerData.layer.stateMachine showcases how the layer property is now accessible through layerData. The updated method calls, including _fireAnimationEventsAndCallScripts and the recursive call to _updateState, now use layerData or its properties directly, reducing parameter passing and potentially improving performance.

Also applies to: 669-676, 681-681


723-723: Improved readability through consistent use of AnimatorLayerData

The changes in the _updateCrossFadeState method further demonstrate the consistent use of the AnimatorLayerData structure. The extraction of srcPlayData, destPlayData, and layerIndex from layerData at the beginning of the method improves readability and clearly shows that these properties are now part of the AnimatorLayerData structure. The updated recursive call to _updateState maintains consistency with the new approach, potentially reducing parameter passing and improving code maintainability.

Also applies to: 798-798


897-897: Consistent application of AnimatorLayerData across methods

The changes in the _updateCrossFadeFromPoseState method maintain consistency with the new approach of using AnimatorLayerData. The use of layerData.layerIndex in the _fireAnimationEventsAndCallScripts call and the updated recursive call to _updateState demonstrate a uniform application of this pattern across different methods. This consistency improves code maintainability and reduces the likelihood of errors related to parameter passing.

Also applies to: 908-908


1497-1517: Comprehensive application of AnimatorLayerData enhances code structure

The changes in the _checkAnyAndEntryState method demonstrate a thorough and consistent application of the AnimatorLayerData structure. The updated method signature and the extraction of stateMachine from layerData.layer showcase how the layer property is now accessible through layerData. All subsequent method calls within this function now use layerData, maintaining consistency with the new approach. This comprehensive refactoring enhances code structure, reduces parameter passing, and improves overall maintainability of the animator system.


548-553: Core implementation of AnimatorLayerData enhancement

The changes in the _getAnimatorLayerData method represent the core implementation of the PR objectives. By initializing layerIndex and layer properties in the AnimatorLayerData object, this modification enables all the code simplifications seen throughout the file. This central change improves the structure of the AnimatorLayerData, reducing the need for separate parameter passing and enhancing the overall organization of the animator system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
animation Built-in animation system related functions ignore for release ignore for release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants