Skip to content

Conversation

@kube
Copy link
Collaborator

@kube kube commented Jan 23, 2026

🌟 What is the purpose of this PR?

Introduce a new PlaybackContext that handles viewing simulation frames at real-time speed based on dt, separate from the computation speed. This allows the simulation to be computed as fast as possible while the visualization plays back at the correct real-time speed. Playback and simulation are now synchronized - pausing playback pauses simulation generation, and resuming playback resumes generation.

🔗 Related links

🚫 Blocked by

Nothing

🔍 What does this change?

  • Create playback/context.ts with PlaybackContextValue type defining playback state and actions
  • Create playback/provider.tsx with requestAnimationFrame-based playback loop
  • Move currentViewedFrame from SimulationContext to PlaybackContext
  • Update all consumer components to use PlaybackContext for frame viewing
  • SimulationContext now only handles computation/generation of frames
  • PlaybackContext advances frames at real-time speed (60Hz max) based on dt
  • Playback/Simulation synchronization: Pausing playback pauses simulation generation, resuming playback resumes generation
  • Playback speed control: Add configurable playback speed (1x, 2x, 4x, 10x, 50x, 100x) to watch simulations faster
  • New useStableCallback hook: Extract common useRef + useEffect pattern for stable callback references
  • Updated UI: Add dedicated playback speed button with icon, tooltip, and popover menu

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • modifies an npm-publishable library and I have added a changeset file(s)

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

⚠️ Known issues

None

🐾 Next steps

None

🛡 What tests cover this?

  • No automated tests yet

❓ How to test this?

  1. Checkout the branch
  2. Run the petrinaut editor with yarn dev
  3. Create a simulation and run it
  4. Confirm that the visualization plays back at real-time speed based on dt
  5. Pause playback and verify simulation generation also pauses
  6. Resume playback and verify simulation generation resumes
  7. Click the playback speed button and change speed (e.g., 10x) to watch faster

📹 Demo

N/A

@vercel
Copy link

vercel bot commented Jan 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Review Updated (UTC)
hashdotdesign Ignored Ignored Preview Jan 29, 2026 10:55am
hashdotdesign-tokens Ignored Ignored Preview Jan 29, 2026 10:55am

@github-actions github-actions bot added area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team labels Jan 23, 2026
Copy link
Collaborator Author

kube commented Jan 23, 2026

@github-actions github-actions bot added the area/infra Relates to version control, CI, CD or IaC (area) label Jan 23, 2026
@kube kube force-pushed the cf/h-5770-simulation-computeplayback branch from a676139 to 2c55788 Compare January 27, 2026 01:24
@kube kube force-pushed the cf/h-5770-simulation-computeplayback branch from 2c55788 to 558a7bb Compare January 27, 2026 11:27
@kube kube changed the base branch from main to graphite-base/8295 January 27, 2026 23:10
@kube kube force-pushed the cf/h-5770-simulation-computeplayback branch from 558a7bb to da55643 Compare January 27, 2026 23:10
@kube kube changed the base branch from graphite-base/8295 to cf/h-5763-have-a-minimap-for-nets-when-not-fully-in-view January 27, 2026 23:10
@kube kube changed the base branch from cf/h-5763-have-a-minimap-for-nets-when-not-fully-in-view to graphite-base/8295 January 28, 2026 00:58
@kube kube force-pushed the cf/h-5770-simulation-computeplayback branch from da55643 to 1ea2c35 Compare January 28, 2026 01:24
@kube kube changed the base branch from graphite-base/8295 to cf/h-5763-have-a-minimap-for-nets-when-not-fully-in-view January 28, 2026 01:24
@github-actions github-actions bot added the area/deps Relates to third-party dependencies (area) label Jan 28, 2026
@graphite-app graphite-app bot changed the base branch from cf/h-5763-have-a-minimap-for-nets-when-not-fully-in-view to graphite-base/8295 January 29, 2026 00:26
@kube kube changed the base branch from graphite-base/8295 to main January 29, 2026 10:48
kube and others added 10 commits January 29, 2026 11:54
Introduce a new PlaybackContext that handles viewing simulation frames
at real-time speed based on dt, separate from the computation speed.

- Create playback/context.ts with PlaybackContextValue type
- Create playback/provider.tsx with requestAnimationFrame-based playback
- Move currentViewedFrame from SimulationContext to PlaybackContext
- Update all consumers to use PlaybackContext for frame viewing
- SimulationContext now only handles computation/generation of frames
- PlaybackContext advances frames at real-time speed (60Hz max)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ider

- Add playback controls popover matching Figma design with three sections:
  - "When pressing play" options (UI only for now)
  - Playback speed selection (1x to Max/Infinity)
  - "Stopping conditions" options (UI only for now)
- Update playback speeds to [1, 2, 5, 10, 30, 60, 120, Infinity]
- Add formatPlaybackSpeed() helper for display formatting
- Add useStableCallback hook for stable function references
- Refactor PlaybackProvider to use stable getters instead of refs
- Use ToolbarButton component for settings button consistency
- Tweak arc firing animation duration and stroke width

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces three play modes:
- viewOnly: Only plays existing frames, no computation (available when simulation is complete)
- computeBuffer: Computes minimally when < 100 frames ahead
- computeMax: Computes as fast as possible while playing

When simulation completes, automatically switches to viewOnly mode and disables
the compute options. When simulation is running, viewOnly is disabled.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Split BottomBar into Edition/Linting and Playback segments with 20px gap
- Reorder SimulationControls: Stop | Play | Timeline | Settings
- Add vertical dividers between control groups

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use motion/react library to animate the BottomBar panels when content
changes (e.g., when simulation starts/stops). This provides smooth
enter/exit animations for buttons, dividers, and timeline controls.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add @testing-library/react, @testing-library/dom, and jsdom as devDependencies
- Create provider.test.tsx with 28 tests covering PlaybackProvider behavior
- Tests use a mock SimulationContext factory pattern for isolation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add isComputeAvailable context flag for when simulation can compute more frames
- Change isViewOnlyAvailable to be true when there are any computed frames
- Update simulation controls to use isComputeAvailable for compute mode buttons
- Add Motion animations to BottomPanel for smooth open/close transitions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

2 participants