Track engine-dev API changes and fix edit-history race conditions#874
Track engine-dev API changes and fix edit-history race conditions#874slimbuck merged 5 commits intoplaycanvas:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Updates the editor to stay compatible with upcoming PlayCanvas engine API changes while addressing an undo/redo race that can occur around asynchronous splat position readbacks.
Changes:
- Update camera render-pass wiring to use the engine’s renamed
framePassesAPI. - Update splat shader tonemapping call to match the engine’s updated
prepareOutputFromGammasignature (adds view-space depth). - Introduce serialized processing for history edits (add/undo/redo) and adjust splat transform history recording order to reduce undo/redo races.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/splats-transform-handler.ts | Reorders transform history recording vs. async updatePositions() and moves visual restoration after the await. |
| src/shaders/splat-shader.ts | Passes view-space depth into tonemapping helper to match engine API. |
| src/editor.ts | Applies fov before setPose so camera distance calculations use the updated FOV. |
| src/edit-history.ts | Adds a promise-chain queue to serialize edit history mutations triggered via events. |
| src/camera.ts | Renames renderPasses usage to framePasses per engine rename. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/edit-history.ts:95
_redo()incrementscursorbefore awaitingeditOp.do(). Ifdo()fails,cursorwill point past the operation that wasn’t actually applied, which can break subsequent undo/redo (and is especially problematic now that the queue logs errors and keeps executing later ops). Consider incrementingcursoronly after a successfuldo()(and similarly for the suppressed-op path), or rolling backcursoron failure.
private async _redo(suppressOp = false) {
const editOp = this.history[this.cursor++];
if (!suppressOp) {
await editOp.do();
}
this.events.fire('edit.apply', editOp);
this.fireEvents();
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Adopts upcoming PlayCanvas engine API changes and fixes a race in edit history that could be triggered by rapid undo/redo during/after splat transforms.
Engine API updates
camera.ts: renamecamera.renderPasses→camera.framePassesto match the engine's renamed property.shaders/splat-shader.ts: pass view-space depth (-center.view.z) as the second argument toprepareOutputFromGamma, matching the engine's updated tonemapping signature.Edit history race fix
edit-history.ts: serializeedit.add/edit.undo/edit.redothrough an internal promise chain. Previously, rapid Ctrl+Z / Ctrl+Shift+Z could race with an in-flightupdatePositionsGPU readback and corrupt the sorter's centers buffer in centers-overlay mode.splats-transform-handler.ts: fireedit.addfor the transform op before awaitingupdatePositions(). Becauseevents.firesynchronously enqueues onto the serialized history chain, any undo pressed while the readback is still pending is now guaranteed to revert the transform op (rather than the prior selection op). The post-drag visual restoration (selectionAlpha, outline, underlay) is moved after the await since the GPU state is already applied duringupdate().Camera pose ordering
editor.ts: incamera.setPose, assignfovbefore callingscene.camera.setPose(...)so the camera distance is computed using the newfovFactor.Test plan
camera.setPosewith afovchange and confirm the resulting framing uses the new FOV.