Skip to content

feat: replace reload with full rewind to avoid crashes#112

Open
matthewdean wants to merge 4 commits into
mainfrom
feat/rewind
Open

feat: replace reload with full rewind to avoid crashes#112
matthewdean wants to merge 4 commits into
mainfrom
feat/rewind

Conversation

@matthewdean

@matthewdean matthewdean commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator

Frequently when testing movies, I want to play from initial state. Reloading often resulted in crashes. This changes reset to be a full rewind (borrowing the Director control panel concept) which reverts the movie back to its state immediately post-parsing.

  • Rewind fully reloads the movie from the stored DirectorFile, resetting all player state back to frame 1
  • Play resumes from current state if movie was already initialized
  • Stop kills all audio immediately
  • Playback state is pushed to Redux store via onPlaybackStateChanged callback so UI reflects script errors and other state changes
image

Known limitations

  • Bitmap manager is not reset on rewind to avoid dangling font refs — old movie bitmaps become orphaned (minor memory leak per rewind)
  • MP3 audio played via HtmlAudioElement is fire-and-forget and cannot be stopped/paused (pre-existing)

Add perform_rewind() which stops the current movie, fully resets player
state, and reloads from the stored DirectorFile. Modeled after the
transition_to_net_movie pattern.

Key changes to player lifecycle:
- stop() now calls sound_manager.stop_all() and dispatches playback
  state change to JS
- reset() clears additional state: frame_script_instance,
  frame_script_member, last_initialized_frame, virtual_scripts
- play() resumes without re-running init sequence if movie_initialized
- run_movie_init_sequence() checks should_cancel_init() at await points
  to bail early on rewind/stop during init

Rewind is signaled via pending_rewind flag, processed by the frame loop
or the play task after exit. When the movie is already stopped (e.g.
after a script error), rewind is dispatched directly via spawn_local.

Also cleans up dead code in stop(), simplifies sound channel
pause/resume methods.
Wire onPlaybackStateChanged from Rust through dirplayer-js-api to the
Redux store so UI components can reactively track whether the movie is
playing or stopped.
Replace reset button with rewind/stop/play controls using Director-
inspired layout. Button active state is driven by isPlaying from the
Redux store, so it reflects script errors and other state changes.

- Rewind (backward-step icon), Stop, Play order
- IconButton supports active prop with subtle pressed style
- Tooltips on all buttons
- 8px gap between buttons to match debugger toolbar
@github-actions

github-actions Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Snapshot Test Report (native)

1 of 2 snapshots differ from reference. Red pixels indicate changes.

Snapshot diffs

Generated by CI — 2026-04-06T03:40:47Z

View full run & download artifacts

@matthewdean matthewdean requested a review from igorlira April 6, 2026 03:36
@github-actions

github-actions Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Snapshot Test Report (browser)

All 0 snapshots match the reference images.

Generated by CI — 2026-04-06T03:45:22Z

View full run & download artifacts

@matthewdean matthewdean changed the title feat: add rewind — reload movie from stored DirectorFile feat: replace reload with full rewind to avoid crashes Apr 6, 2026
@matthewdean matthewdean marked this pull request as ready for review April 6, 2026 03:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant