1use crate::{util::str_to_c, AddonApi, RendererApi, Revertible, UiApi};
4use std::ffi::{c_char, c_void};
5
6pub const IMGUI_VERSION: u32 = 18000;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13#[cfg_attr(
14 feature = "strum",
15 derive(
16 strum::AsRefStr,
17 strum::Display,
18 strum::EnumCount,
19 strum::EnumIter,
20 strum::IntoStaticStr,
21 strum::VariantArray,
22 strum::VariantNames
23 )
24)]
25#[repr(C)]
26pub enum RenderType {
27 PreRender,
29
30 Render,
32
33 PostRender,
35
36 OptionsRender,
38}
39
40pub type RawGuiRender = extern "C-unwind" fn();
41
42pub type RawGuiAddRender =
43 unsafe extern "C-unwind" fn(render_type: RenderType, render_callback: RawGuiRender);
44
45pub type RawGuiRemRender = unsafe extern "C-unwind" fn(render_callback: RawGuiRender);
46
47pub type RawGuiRegisterCloseOnEscape =
48 unsafe extern "C-unwind" fn(window_name: *const c_char, is_visible: *mut bool);
49
50pub type RawGuiDeregisterCloseOnEscape = unsafe extern "C-unwind" fn(window_name: *const c_char);
51
52pub type ImguiMalloc = unsafe extern "C" fn(size: usize, user_data: *mut c_void) -> *mut c_void;
53
54pub type ImguiFree = unsafe extern "C" fn(ptr: *mut c_void, user_data: *mut c_void);
55
56#[inline]
67pub fn register_render(
68 render_type: RenderType,
69 callback: RawGuiRender,
70) -> Revertible<impl Fn() + Send + Sync + Clone + 'static> {
71 let RendererApi {
72 register,
73 deregister,
74 ..
75 } = AddonApi::get().renderer;
76 unsafe { register(render_type, callback) };
77 let revert = move || unsafe { deregister(callback) };
78 revert.into()
79}
80
81#[inline]
83pub fn unregister_render(callback: RawGuiRender) {
84 let RendererApi { deregister, .. } = AddonApi::get().renderer;
85 unsafe { deregister(callback) }
86}
87
88#[macro_export]
98macro_rules! render {
99 ( $callback:expr $(,)? ) => {{
100 const __CALLBACK: fn(&$crate::imgui::Ui) = $callback;
101
102 extern "C-unwind" fn __render_callback_wrapper() {
103 unsafe { $crate::__macro::with_ui(__CALLBACK) }
104 }
105
106 __render_callback_wrapper
107 }};
108}
109
110pub use render;
111
112pub fn register_close_on_escape(window_name: impl AsRef<str>, opened: &mut bool) {
114 let UiApi {
115 register_close_on_escape,
116 ..
117 } = AddonApi::get().ui;
118 let window_name = str_to_c(window_name, "failed to convert window name");
119 unsafe { register_close_on_escape(window_name.as_ptr(), opened) }
120}
121
122pub fn deregister_close_on_escape(window_name: impl AsRef<str>) {
124 let UiApi {
125 deregister_close_on_escape,
126 ..
127 } = AddonApi::get().ui;
128 let window_name = str_to_c(window_name, "failed to convert window name");
129 unsafe { deregister_close_on_escape(window_name.as_ptr()) }
130}