Donner 0.5.1
Embeddable browser-grade SVG2 engine
Loading...
Searching...
No Matches
ReproFile.h File Reference

Data model for a .donner-repro file: a recorded sequence of editor UI inputs (mouse events, keyboard events, wheel events, window resizes) plus enough session metadata to re-instantiate the editor and replay the events deterministically. More...

#include <cstdint>
#include <filesystem>
#include <optional>
#include <string>
#include <vector>
Include dependency graph for ReproFile.h:
This graph shows which files directly or indirectly include this file:

Classes

struct  donner::editor::repro::ReproEvent
 One discrete event that fired within a frame. Frame-state (mouse position, button mask) lives on the owning frame record; this captures only events that can't be reconstructed from continuous state (key presses, character input, wheel deltas, resizes). More...
struct  donner::editor::repro::ReproFrame
 One frame's snapshot: continuous input state + any discrete events that fired during the frame. More...
 Session-level metadata captured at recording start. More...
struct  donner::editor::repro::ReproFile
 In-memory form of a loaded or in-progress recording. More...

Namespaces

namespace  donner
 Top-level Donner namespace, which is split into different sub-namespaces such as donner::svg and donner::css.

Functions

bool donner::editor::repro::WriteReproFile (const std::filesystem::path &path, const ReproFile &file)
 Serialize file to the given path in NDJSON form. Returns true on success; on failure writes an error message to stderr and returns false. Atomic: writes to path.tmp then renames over path, so a crash mid-write never truncates an existing file.
std::optional< ReproFiledonner::editor::repro::ReadReproFile (const std::filesystem::path &path)
 Parse an NDJSON repro file. Returns std::nullopt on any error (file missing, version mismatch, malformed line); writes details to stderr.

Variables

constexpr int donner::editor::repro::kReproFileVersion = 1
 File format version. Bump when format changes; loader rejects unknown versions.
constexpr int donner::editor::repro::kMaxMouseButtons = 5
 Maximum number of mouse buttons recorded. Matches ImGui's ImGuiMouseButton_COUNT.

Detailed Description

Data model for a .donner-repro file: a recorded sequence of editor UI inputs (mouse events, keyboard events, wheel events, window resizes) plus enough session metadata to re-instantiate the editor and replay the events deterministically.

The file records at the raw ImGui-input level (below menu action dispatch, below tool dispatch, below the compositor) so every stage of the stack — from Donner's DOM mutations down through the RendererTinySkia pixel ops — is exercised during playback. That breadth is the point: a recording made in the live editor reproduces the bug regardless of which layer it lives in.

Format is one JSON object per line (NDJSON):

{"v":1,"svg":"path.svg","wnd":[1600,900],"scale":2.0,"exp":false}
{"f":0,"t":0.0,"dt":16.6,"mx":100.5,"my":50.2,"btn":0,"mod":0}
{"f":1,"t":16.6,"dt":16.7,"mx":120.0,"my":50.0,"btn":0,"mod":0,
"e":[{"k":"mdown","b":0},{"k":"wheel","dy":1.0}]}
...

Frame records carry the full mouse state plus any discrete events that fired during that frame. Discrete events are keyed by short type codes:

code meaning fields
mdown mouse button down b (button index 0-4)
mup mouse button up b
kdown keyboard key down k (ImGui key enum), m (mods)
kup keyboard key up k, m
chr character input c (UTF-32 code point)
wheel mouse wheel dx, dy (float units)
resize window resize w, h
focus window focus change on (0/1)

The "frame record" itself captures the continuous state (mouse position + current button mask) so a dropped event in the discrete list can't leave the player in an inconsistent state — the next frame's state trumps.