Conversation
There was a problem hiding this comment.
Pull request overview
Stage の addChild における root 管理仕様を調整し、WebGPU の描画結果変更に伴う e2e スナップショット更新と、publish workflow の npm publish オプション調整を行うPRです。
Changes:
- Stage の
addChildで$rootMapを一時的に操作し、root 解決ロジックを変更 - WebGPU の instanced fragment shader を
textureSampleLevel(..., 0)からtextureSample(...)に変更 - WebGPU e2e スナップショット PNG 更新、および publish workflow の npm publish を
--access public付きに変更
Reviewed changes
Copilot reviewed 3 out of 6 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/webgpu/src/Shader/wgsl/fragment/InstancedFragment.ts | インスタンス描画のテクスチャサンプリング方法を変更 |
| packages/display/src/Stage.ts | Stage 直下に追加された DisplayObject の root 管理方法を変更 |
| e2e/snapshots/webgpu/shape.spec.ts-snapshots/load-image-flip-webgpu-darwin.png | WebGPU 描画結果変更に伴うスナップショット更新 |
| .github/workflows/publish.yml | publish 時の権限追加と npm publish --access public を適用 |
Comments suppressed due to low confidence (2)
packages/display/src/Stage.ts:195
- Stage overrides
addChild()but notaddChildAt(). Callingstage.addChildAt()will go throughDisplayObjectContainerAddChildUseCase, which sets$rootMaptostage.root(currentlynullunless Stage is in$rootMap), so children added viaaddChildAtcan end up with anullroot whileaddChildsets root to self. Consider overridingaddChildAt()(or refactoring shared logic) to keep Stage root assignment consistent.
addChild<T extends DisplayObject>(display_object: T): T
{
$stageAssignedMap.add(display_object.instanceId);
// fixed logic
$rootMap.set(this, display_object);
super.addChild(display_object);
// fixed logic for root map
$rootMap.delete(this);
$rootMap.set(display_object, display_object);
return display_object;
}
packages/display/src/Stage.ts:195
- This change alters Stage’s root-assignment behavior in a non-trivial way (temporary
$rootMapmutation + cleanup). There are existing unit tests forStagebut none coveraddChild()/root behavior; please add tests that assert (1) a child added to Stage haschild.root === child, (2) Stage does not retain a$rootMapentry after adding, and (3)addChildAt()behaves consistently.
addChild<T extends DisplayObject>(display_object: T): T
{
$stageAssignedMap.add(display_object.instanceId);
// fixed logic
$rootMap.set(this, display_object);
super.addChild(display_object);
// fixed logic for root map
$rootMap.delete(this);
$rootMap.set(display_object, display_object);
return display_object;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $stageAssignedMap.add(display_object.instanceId); | ||
|
|
||
| // fixed logic | ||
| $rootMap.set(this, display_object); | ||
| super.addChild(display_object); | ||
|
|
||
| // fixed logic for root map | ||
| $rootMap.delete(this); | ||
| $rootMap.set(display_object, display_object); | ||
|
|
There was a problem hiding this comment.
$rootMap.set(this, display_object) is used as a temporary hack so super.addChild() will treat display_object as the Stage root. However super.addChild() dispatches events (e.g. ADDED) that can throw, which would skip the cleanup and leave this mapped in $rootMap (and also leave display_object.instanceId in $stageAssignedMap). Wrap the super.addChild() call in try/finally to guarantee $rootMap.delete(this) (and rollback stage assignment if the add fails).
| $stageAssignedMap.add(display_object.instanceId); | |
| // fixed logic | |
| $rootMap.set(this, display_object); | |
| super.addChild(display_object); | |
| // fixed logic for root map | |
| $rootMap.delete(this); | |
| $rootMap.set(display_object, display_object); | |
| const instanceId = display_object.instanceId; | |
| $stageAssignedMap.add(instanceId); | |
| // fixed logic | |
| $rootMap.set(this, display_object); | |
| let added = false; | |
| try { | |
| super.addChild(display_object); | |
| added = true; | |
| } finally { | |
| // always remove temporary root mapping | |
| $rootMap.delete(this); | |
| // rollback stage assignment if addChild fails | |
| if (!added) { | |
| $stageAssignedMap.delete(instanceId); | |
| } | |
| } | |
| if (added) { | |
| // fixed logic for root map | |
| $rootMap.set(display_object, display_object); | |
| } |
| // fixed logic | ||
| $rootMap.set(this, display_object); | ||
| super.addChild(display_object); | ||
|
|
||
| // fixed logic for root map |
There was a problem hiding this comment.
The comments // fixed logic / // fixed logic for root map don’t explain the invariant being maintained here. Please replace them with a short explanation of why Stage is temporarily inserted into $rootMap and why it must be removed immediately after super.addChild().
| // fixed logic | |
| $rootMap.set(this, display_object); | |
| super.addChild(display_object); | |
| // fixed logic for root map | |
| // Temporarily register Stage as the current root so that any logic in super.addChild() | |
| // that consults $rootMap can treat this added subtree as belonging to this Stage. | |
| $rootMap.set(this, display_object); | |
| super.addChild(display_object); | |
| // Restore the $rootMap invariant: only root DisplayObjects (Stage children) are kept as keys, | |
| // not Stage itself, so remove the temporary Stage entry and register the new root child instead. |
No description provided.