Skip to content

Merge origin/dev into origin/main#1032

Merged
yiiqii merged 6 commits into
mainfrom
dev
Jun 13, 2025
Merged

Merge origin/dev into origin/main#1032
yiiqii merged 6 commits into
mainfrom
dev

Conversation

@yiiqii

@yiiqii yiiqii commented Jun 13, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Refactor

    • Simplified asset and texture management within scenes, making texture arrays required and introducing a dedicated assets property.
    • Streamlined the process of loading and initializing textures for scenes.
    • Improved the handling of scene compositions and asset preparation for greater consistency.
  • Documentation

    • Updated method documentation for font style settings to clarify usage and default values.
  • Style

    • Enhanced type clarity and removed redundant assertions for improved code readability.

yiiqii and others added 6 commits June 6, 2025 16:51
Merge origin/main into origin/dev
#1029)

* fix: video will be downloaded twice when loaded using the assetmanager

* chore: modify type

---------

Co-authored-by: yiiqii <yfj5tzl2005@sina.com>
fix: pre composition mask migration error
docs: 修改 setFontStyle 注释
@yiiqii
yiiqii requested a review from wumaolinmaoan June 13, 2025 02:24
@coderabbitai

coderabbitai Bot commented Jun 13, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This change refactors asset and texture handling across several modules, making the textures property required in the Scene interface and introducing an explicit assets dictionary. The migration logic is simplified by removing recursive composition processing. Asset loading and preparation now operate directly on scene-attached assets, with related type and documentation updates.

Changes

File(s) Change Summary
packages/effects-core/src/asset-manager.ts Simplified loadScene logic: removed plugin/image async processing, now assigns assets and textures directly.
packages/effects-core/src/asset-service.ts Refactored texture initialization: direct assignment from engine, removed conditional logic.
packages/effects-core/src/composition.ts Now assigns _textures from scene.textures; removed clearing of scene.textures for reusable scenes.
packages/effects-core/src/fallback/migration.ts Removed refCompositions map and recursive handling; processes all compositions in a flat loop.
packages/effects-core/src/plugins/particle/particle-system.ts Type assertion for originVec clarified; redundant assertion removed.
packages/effects-core/src/plugins/text/text-item.ts JSDoc updated for setFontStyle method; no code logic changes.
packages/effects-core/src/scene.ts Scene interface: textures now required; added assets dictionary property.
packages/effects/src/player.ts Asset preparation now uses scene.assets instead of assetManager.getAssets().

Sequence Diagram(s)

sequenceDiagram
    participant Player
    participant AssetManager
    participant AssetService
    participant Scene

    Player->>AssetManager: loadScene(json)
    AssetManager->>Scene: Assign textures, assets directly
    Player->>AssetService: prepareAssets(scene.assets)
    AssetService->>Scene: Initialize textures from scene.textures
Loading

Possibly related PRs

Suggested reviewers

  • wumaolinmaoan

Poem

A bunny hopped through fields of code,
Tidying assets in every node.
Textures now march in a neat array,
Assets are mapped, no more disarray.
Compositions flat, recursion gone—
Hopping forward, code moves on!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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.

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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

🧹 Nitpick comments (1)
packages/effects-core/src/plugins/particle/particle-system.ts (1)

441-444: Use type annotation instead of assertion for originVec and hoist constant to avoid per-frame allocation

Creating a new array each time the burst loop runs adds unnecessary GC pressure.
Also, a type annotation is cleaner than an as assertion.

-              const originVec = [0, 0, 0] as vec3;
+              // constant defined once at module scope avoids re-allocating
+const ORIGIN_VEC: vec3 = [0, 0, 0];
+
+              const burstOffset = (offsets && offsets[opts.cycleIndex]) || ORIGIN_VEC;

If you decide to keep it local, at least switch to

const originVec: vec3 = [0, 0, 0];
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0070a8 and b824a42.

📒 Files selected for processing (8)
  • packages/effects-core/src/asset-manager.ts (1 hunks)
  • packages/effects-core/src/asset-service.ts (2 hunks)
  • packages/effects-core/src/composition.ts (1 hunks)
  • packages/effects-core/src/fallback/migration.ts (1 hunks)
  • packages/effects-core/src/plugins/particle/particle-system.ts (2 hunks)
  • packages/effects-core/src/plugins/text/text-item.ts (1 hunks)
  • packages/effects-core/src/scene.ts (1 hunks)
  • packages/effects/src/player.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
packages/effects-core/src/plugins/particle/particle-system.ts (1)

462-463: 👍 Removal of redundant as vec3 cast

The spread call already enforces number arguments, so the explicit cast was noise.
No further action required.

packages/effects/src/player.ts (1)

346-351:

Details

❓ Verification inconclusive

Ensure scene.assets is populated before calling prepareAssets

AssetManager.getAssets() previously guaranteed the map was filled.
Now we rely on scene.assets, which is assigned inside AssetManager.loadScene.
If any plugin mutates or clears this property after load, asset preparation will silently skip required assets.

Please verify at least one key exists for typical scenes:

If empties are possible, consider falling back to assetManager.getAssets() or throwing early.


🏁 Script executed:

#!/bin/bash
# Count scenes whose assets map is empty after loadScene
rg --no-heading -t ts -N $'\\.assets\\s*=\\s*\\{\\}' | head -n 20

Length of output: 266


🏁 Script executed:

#!/bin/bash
# Show loadScene implementation context
rg -n -A50 "loadScene" packages/effects-core/src/asset-manager.ts

Length of output: 1940


🏁 Script executed:

#!/bin/bash
# Find all occurrences of `.assets` in asset-manager.ts
rg -n "\.assets" packages/effects-core/src/asset-manager.ts

Length of output: 485


🏁 Script executed:

#!/bin/bash
# Locate getAssets implementation in AssetManager
rg -n -A5 "getAssets" packages/effects-core/src/asset-manager.ts

Length of output: 227


Verify non-empty scene.assets after loadScene
File: packages/effects/src/player.ts (lines 346–351)

We used to rely on assetManager.getAssets() to always return a populated map. With the new API, scene.assets comes from inside loadScene and could be empty if no assets were found or if later code tampered with that object.

– After calling loadScene, add a quick check:

const scene = await assetManager.loadScene(source, this.renderer, { env: this.env });

// fallback if no assets were loaded
if (Object.keys(scene.assets).length === 0) {
  // either reuse the manager’s copy…
  scene.assets = assetManager.getAssets();
  // …or throw early:
  // throw new Error('Loaded scene contains no assets.');
}

this.assetService.prepareAssets(scene, scene.assets);
this.assetService.updateTextVariables(scene, assetManager.options.variables);
this.assetService.initializeTexture(scene);

Please confirm that your typical scenes always populate scene.assets. If not, implement this fallback or fail fast.

packages/effects-core/src/scene.ts (1)

21-24: Required textures / new assets field LGTM

Making textures mandatory simplifies downstream code, and adding an assets
dictionary aligns with the new load flow.
No issues spotted.

packages/effects-core/src/plugins/text/text-item.ts (1)

225-228: Docstring improvement acknowledged

The JSDoc now correctly describes “font style” with a default of "normal".
No code impact.

Comment on lines 304 to 308

this.renderer = renderer;
this._textures = scene.textureOptions as Texture[];
this._textures = scene.textures;
this.postProcessingEnabled = scene.jsonScene.renderSettings?.postProcessingEnabled ?? false;
this.getEngine().renderLevel = scene.renderLevel;

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.

🛠️ Refactor suggestion

Sharing scene.textures between compositions can lead to double-dispose or premature unload

this._textures = scene.textures; means all compositions built from the same
Scene instance hold the same array reference.
dispose() iterates and tex.dispose() each entry.
If two compositions share the array, the first dispose call frees the GPU
resource and the second dispose call will hit an already-destroyed texture.

Clone the array or track ownership:

-    this._textures = scene.textures;
+    // clone to avoid double-dispose when multiple compositions share a scene
+    this._textures = scene.textures.slice();

Or introduce a reference-count in Texture/Scene.

📝 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
this.renderer = renderer;
this._textures = scene.textureOptions as Texture[];
this._textures = scene.textures;
this.postProcessingEnabled = scene.jsonScene.renderSettings?.postProcessingEnabled ?? false;
this.getEngine().renderLevel = scene.renderLevel;
this.renderer = renderer;
// clone to avoid double-dispose when multiple compositions share a scene
this._textures = scene.textures.slice();
this.postProcessingEnabled = scene.jsonScene.renderSettings?.postProcessingEnabled ?? false;
this.getEngine().renderLevel = scene.renderLevel;
🤖 Prompt for AI Agents
In packages/effects-core/src/composition.ts around lines 304 to 308, the
assignment this._textures = scene.textures shares the same texture array
reference across compositions, causing double-dispose issues. To fix this, clone
the textures array when assigning it to this._textures so each composition has
its own copy, preventing multiple disposes of the same texture. Alternatively,
implement reference counting in Texture or Scene to manage shared ownership
safely.

Comment on lines +167 to +169
textures: [],
images: loadedImages,
assets: this.assets,

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.

⚠️ Potential issue

Avoid shared-reference leaks between AssetManager and Scene.

scene.assets = this.assets hands out the same object.
When AssetManager.dispose() executes, it only reassigns its own reference (this.assets = {}), leaving scene.assets pointing to the old map – GPU / memory never freed.

Either:

  1. Give the scene a shallow copy so the manager can safely clear its own map, or
  2. Make dispose() iterate the map and release resources, then also clear scene.assets.
-          assets: this.assets,
+          assets: { ...this.assets },   // decouple the two owners
📝 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
textures: [],
images: loadedImages,
assets: this.assets,
textures: [],
images: loadedImages,
assets: { ...this.assets }, // decouple the two owners
🤖 Prompt for AI Agents
In packages/effects-core/src/asset-manager.ts around lines 167 to 169, the
assignment scene.assets = this.assets shares the same object reference, causing
dispose() to clear only the manager's assets while the scene retains the old
reference, leading to resource leaks. Fix this by assigning a shallow copy of
this.assets to scene.assets to avoid shared references, or modify dispose() to
explicitly release resources in the map and clear scene.assets as well.

Comment on lines +88 to 90
scene.textures[i] = this.engine.findObject<Texture>({ id: scene.textureOptions[i].id });
scene.textures[i].initialize();
}

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.

⚠️ Potential issue

Null-check findObject() result to prevent runtime crash.

this.engine.findObject can return undefined; calling .initialize() unguarded will throw and abort scene loading.

-      scene.textures[i] = this.engine.findObject<Texture>({ id: scene.textureOptions[i].id });
-      scene.textures[i].initialize();
+      const tex = this.engine.findObject<Texture>({ id: scene.textureOptions[i].id });
+      if (!tex) {
+        console.warn(`Texture ${scene.textureOptions[i].id} not found`);
+        continue;            // or throw, depending on expectations
+      }
+      tex.initialize();
+      scene.textures[i] = tex;
📝 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
scene.textures[i] = this.engine.findObject<Texture>({ id: scene.textureOptions[i].id });
scene.textures[i].initialize();
}
const tex = this.engine.findObject<Texture>({ id: scene.textureOptions[i].id });
if (!tex) {
console.warn(`Texture ${scene.textureOptions[i].id} not found`);
continue; // or throw, depending on expectations
}
tex.initialize();
scene.textures[i] = tex;
}
🤖 Prompt for AI Agents
In packages/effects-core/src/asset-service.ts around lines 88 to 90, the result
of this.engine.findObject may be undefined, causing a runtime crash when calling
initialize() on it. Add a null-check to ensure the object exists before calling
initialize(), and handle the case where findObject returns undefined to prevent
aborting scene loading.

Comment on lines +119 to +121
for (const comp of compositions) {
processContent(comp);
}

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.

🛠️ Refactor suggestion

Reset mask state per composition to avoid cross-composition bleed-through.

currentMaskComponent is global. Iterating every composition consecutively means a mask set in one composition may wrongly influence the next.

+  for (const comp of compositions) {
+    currentMaskComponent = undefined;   // clear previous composition context
     processContent(comp);
   }

Without this, obscured items in later compositions may reference a mask from an unrelated composition.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/effects-core/src/fallback/migration.ts around lines 119 to 121, the
variable currentMaskComponent is global and not reset between processing each
composition, causing mask state to bleed across compositions. To fix this, reset
or reinitialize currentMaskComponent at the start of each iteration inside the
for loop so that each composition processes with a fresh mask state and does not
inherit masks from previous compositions.

@yiiqii
yiiqii merged commit 2d5cde1 into main Jun 13, 2025
3 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