Skip to main content

dear_implot3d/ui/
token.rs

1use std::marker::PhantomData;
2
3use crate::{debug_end_plot, sys};
4use dear_imgui_rs::{DrawListMut, Ui};
5
6use super::binding::Plot3DContextBinding;
7
8/// RAII token that ends the plot on drop
9///
10/// This token is returned by `Plot3DBuilder::build()` and automatically calls
11/// `ImPlot3D_EndPlot()` when it goes out of scope, ensuring proper cleanup.
12pub struct Plot3DToken<'ui> {
13    pub(crate) binding: Plot3DContextBinding,
14    pub(crate) imgui_alive: Option<dear_imgui_rs::ContextAliveToken>,
15    pub(crate) ui: &'ui Ui,
16    pub(crate) _lifetime: PhantomData<&'ui Ui>,
17}
18
19impl<'ui> Plot3DToken<'ui> {
20    /// Get the active 3D plot draw list as a frame-bound wrapper.
21    pub fn plot_draw_list(&self) -> Option<DrawListMut<'_>> {
22        if let Some(alive) = &self.imgui_alive {
23            assert!(
24                alive.is_alive(),
25                "dear-implot3d: ImGui context has been dropped"
26            );
27        }
28        let _guard = self.binding.bind();
29        let draw_list = unsafe { sys::ImPlot3D_GetPlotDrawList() };
30        if draw_list.is_null() {
31            None
32        } else {
33            Some(unsafe { DrawListMut::from_raw_mut(self.ui, draw_list) })
34        }
35    }
36}
37
38impl Drop for Plot3DToken<'_> {
39    fn drop(&mut self) {
40        if let Some(alive) = &self.imgui_alive {
41            assert!(
42                alive.is_alive(),
43                "dear-implot3d: ImGui context has been dropped"
44            );
45        }
46        let _guard = self.binding.bind();
47        unsafe {
48            debug_end_plot();
49            sys::ImPlot3D_EndPlot();
50        }
51    }
52}