Skip to content

v1 parity: RAII scope wrappers for every Begin/End + Push/Pop pair#20

Merged
borisbat merged 2 commits into
masterfrom
bbatkin/v1-scope-parity
Jun 7, 2026
Merged

v1 parity: RAII scope wrappers for every Begin/End + Push/Pop pair#20
borisbat merged 2 commits into
masterfrom
bbatkin/v1-scope-parity

Conversation

@borisbat

@borisbat borisbat commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Audit result

The thin v1 tier (imgui_implot_boost) exists to wrap the paired ImPlot APIs whose End/Pop can't be safely skipped — that's its whole value-add. Everything else (items like PlotText/PlotHeatmap/PlotBarGroups/DragPoint, SetNext* styling, SampleColormap, PlotToPixels, SetupAxis/SetupLegend) is already reachable raw via require implot public, so it needs no wrapper.

Auditing the binding for Begin*/End* + Push*/Pop* pairs, v1 already had with_plot and with_subplots; this fills in every remaining paired scope:

Wrapper Native pair
with_aligned_plots BeginAlignedPlots / EndAlignedPlots
with_colormap PushColormap / PopColormap
with_style_color PushStyleColor / PopStyleColor
with_style_var (float / int / float2) PushStyleVar / PopStyleVar
with_plot_clip_rect PushPlotClipRect / PopPlotClipRect
with_legend_popup BeginLegendPopup / EndLegendPopup
with_drag_drop_source_item / _plot / _axis BeginDragDropSource* / EndDragDropSource
with_drag_drop_target_plot / _axis / _legend BeginDragDropTarget* / EndDragDropTarget

Same arity-overload style as the existing with_plot/with_subplots (gen2 binds a trailing block to the slot after the last explicit arg, so optional args become overloads, not defaults). Push/Pop scopes run the body unconditionally and always Pop; Begin/End scopes run the body iff Begin returned true.

Deliberately out of scope

  • Items / styling / coord / sample_colormap — raw-callable, no wrapper needed (the point above).
  • Snapshot / playwright telemetry — v1's with_plot has no snapshot hook by design; that's a v2 (imgui_implot_boost_v2) concern.

Testing

tests/integration/test_v1_scopes.das — a headless in-process smoke. v1 has no snapshot to query, so it nests every new scope and passes iff it renders crash-free (an unbalanced Push/Pop or a missed End would trip an ImGui assert). Full integration suite 13/13 green locally.

🤖 Generated with Claude Code

The v1 thin tier (imgui_implot_boost) wraps the paired APIs whose End/Pop can't be
safely skipped — that is v1's whole value-add. Everything else (items, styling,
colormap sampling, coord conversion, axis/legend setup) is already reachable raw via
`require implot public`, so it needs no wrapper. This fills the gaps: the only paired
APIs v1 was missing.

Added (same arity-overload style as the existing with_plot / with_subplots, since
gen2 binds a trailing block to the slot after the last explicit arg, so optional args
become overloads not defaults):

- with_aligned_plots          (BeginAlignedPlots / EndAlignedPlots)
- with_colormap               (PushColormap / PopColormap)
- with_style_color            (PushStyleColor / PopStyleColor)
- with_style_var              (PushStyleVar / PopStyleVar — float / int / float2)
- with_plot_clip_rect         (PushPlotClipRect / PopPlotClipRect)
- with_legend_popup           (BeginLegendPopup / EndLegendPopup)
- with_drag_drop_source_item / _plot / _axis  (Begin* / EndDragDropSource)
- with_drag_drop_target_plot / _axis / _legend (Begin* / EndDragDropTarget)

Push/Pop scopes run the body unconditionally and always Pop; Begin/End scopes run
the body iff Begin returned true (the ImPlot contract).

tests/integration/test_v1_scopes.das: a headless in-process smoke (v1 has no snapshot
hook to query, so it nests every new scope and passes iff it renders crash-free — an
unbalanced Push/Pop or a missed End would trip an ImGui assert). Full suite 13/13 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the v1 “thin” ImPlot wrapper module (imgui_implot_boost) by adding RAII-style scope helpers for the remaining paired ImPlot APIs (Begin/End and Push/Pop) so callers can’t accidentally skip required End*/Pop* calls. It also adds a headless integration smoke test that exercises all new scopes to catch imbalance asserts.

Changes:

  • Add v1 scope wrappers for BeginAlignedPlots/EndAlignedPlots, Push*/Pop* style scopes, legend popup, and plot drag/drop source/target scopes.
  • Add a headless integration smoke test that nests all new scopes and passes if it renders crash-free for several frames.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
daslib/implot_boost.das Adds the new v1 RAII scope wrappers for remaining paired ImPlot APIs.
tests/integration/test_v1_scopes.das New headless smoke test that exercises all newly added v1 scopes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread daslib/implot_boost.das
Comment thread daslib/implot_boost.das
Comment thread daslib/implot_boost.das
Comment thread daslib/implot_boost.das
Comment thread daslib/implot_boost.das
Comment thread daslib/implot_boost.das
The no-optional convenience overloads passed explicit literals (vertical=true,
expand=0, mouse_button=1, flags=0) that exactly match the native defaults. The
implot binding carries SCALAR C++ defaults (bool/int/float), so the shorter native
call is equivalent and drops the magic values — verified by compiling the 1-arg
forms. (with_plot/with_subplots stay explicit: their size default is an ImVec2
struct, which the binding does NOT carry, so the shorter form won't compile.)

- with_aligned_plots / with_plot_clip_rect / with_legend_popup /
  with_drag_drop_source_item / _plot / _axis: call the native with no optional arg.

Smoke (test_v1_scopes.das) still renders crash-free.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@borisbat

borisbat commented Jun 7, 2026

Copy link
Copy Markdown
Owner Author

Addressed all 6 in 9a233a1 — dropped the redundant explicit literals (vertical=true, expand=0, mouse_button=1, flags=0) and let the native default apply.

Verified the premise first: the implot binding does carry scalar C++ defaults (bool/int/float), so BeginAlignedPlots(group_id) / PushPlotClipRect() / BeginLegendPopup(label_id) / BeginDragDropSource*(…) compile and are equivalent. Note it does not carry struct defaults — BeginPlot("t") fails with "missing argument size" (its default is ImVec2(-1,0)), which is why with_plot/with_subplots keep passing the size explicitly. Smoke (test_v1_scopes.das) still renders crash-free.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@borisbat borisbat merged commit 94aeef9 into master Jun 7, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants