mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 05:28:35 +00:00
move platform and renderer backends out of Dear Imgui
Store the objects containing the callback methods for multi viewport support in two globals that are managed by imgui-rs, instead of using BackendPlatformUserdata and BackendRendererUserData fixes #820
This commit is contained in:
parent
150ede3b4e
commit
184b86d355
@ -683,12 +683,11 @@ impl Context {
|
||||
/// Installs a [`PlatformViewportBackend`](crate::PlatformViewportBackend) that is used to
|
||||
/// create platform windows on demand if a window is dragged outside of the main viewport.
|
||||
pub fn set_platform_backend<T: crate::PlatformViewportBackend>(&mut self, backend: T) {
|
||||
let ctx = Box::new(UnsafeCell::new(crate::PlatformViewportContext {
|
||||
let ctx = crate::PlatformViewportContext {
|
||||
backend: Box::new(backend),
|
||||
}));
|
||||
};
|
||||
|
||||
let io = self.io_mut();
|
||||
io.backend_platform_user_data = ctx.get() as *mut _;
|
||||
*crate::PLATFORM_VIEWPORT_BACKEND.lock().unwrap() = Some(ctx);
|
||||
|
||||
let pio = self.platform_io_mut();
|
||||
pio.platform_create_window = Some(docking_utils::platform_create_window);
|
||||
@ -719,18 +718,15 @@ impl Context {
|
||||
pio.platform_render_window = Some(docking_utils::platform_render_window);
|
||||
pio.platform_swap_buffers = Some(docking_utils::platform_swap_buffers);
|
||||
pio.platform_create_vk_surface = Some(docking_utils::platform_create_vk_surface);
|
||||
|
||||
self.platform_viewport_ctx = ctx;
|
||||
}
|
||||
/// Installs a [`RendererViewportBackend`](crate::RendererViewportBackend) that is used to
|
||||
/// render extra viewports created by ImGui.
|
||||
pub fn set_renderer_backend<T: crate::RendererViewportBackend>(&mut self, backend: T) {
|
||||
let ctx = Box::new(UnsafeCell::new(crate::RendererViewportContext {
|
||||
let ctx = crate::RendererViewportContext {
|
||||
backend: Box::new(backend),
|
||||
}));
|
||||
};
|
||||
|
||||
let io = self.io_mut();
|
||||
io.backend_renderer_user_data = ctx.get() as *mut _;
|
||||
*crate::RENDERER_VIEWPORT_BACKEND.lock().unwrap() = Some(ctx);
|
||||
|
||||
let pio = self.platform_io_mut();
|
||||
pio.renderer_create_window = Some(docking_utils::renderer_create_window);
|
||||
@ -738,8 +734,6 @@ impl Context {
|
||||
pio.renderer_set_window_size = Some(docking_utils::renderer_set_window_size);
|
||||
pio.renderer_render_window = Some(docking_utils::renderer_render_window);
|
||||
pio.renderer_swap_buffers = Some(docking_utils::renderer_swap_buffers);
|
||||
|
||||
self.renderer_viewport_ctx = ctx;
|
||||
}
|
||||
/// Updates the extra Viewports created by ImGui.
|
||||
/// Has to be called every frame if Viewports are enabled.
|
||||
|
||||
@ -1,9 +1,17 @@
|
||||
use std::{
|
||||
cell::UnsafeCell,
|
||||
ffi::{c_void, CStr},
|
||||
os::raw::{c_char, c_int},
|
||||
sync::{Mutex, MutexGuard},
|
||||
};
|
||||
|
||||
use crate::{Io, PlatformIo, Viewport};
|
||||
use crate::{PlatformIo, Viewport};
|
||||
|
||||
pub(crate) static PLATFORM_VIEWPORT_BACKEND: Mutex<Option<crate::PlatformViewportContext>> =
|
||||
Mutex::new(None);
|
||||
|
||||
pub(crate) static RENDERER_VIEWPORT_BACKEND: Mutex<Option<crate::RendererViewportContext>> =
|
||||
Mutex::new(None);
|
||||
|
||||
/// Trait holding functions needed when the platform integration supports viewports.
|
||||
///
|
||||
@ -67,20 +75,14 @@ pub trait PlatformViewportBackend: 'static {
|
||||
|
||||
/// Used to get the current Contexts [`PlatformViewportContext`].
|
||||
fn get_platform_ctx() -> &'static mut PlatformViewportContext {
|
||||
unsafe {
|
||||
// should be safe as it is impossible to call any imgui function on a non-active context.
|
||||
&mut *((*(sys::igGetIO() as *const Io)).backend_platform_user_data
|
||||
as *mut PlatformViewportContext)
|
||||
}
|
||||
let a = UnsafeCell::new(PLATFORM_VIEWPORT_BACKEND.lock().unwrap()).get();
|
||||
unsafe { (*a).as_mut().unwrap() }
|
||||
}
|
||||
|
||||
/// Used to get the current Contexts [`RendererViewportContext`].
|
||||
fn get_renderer_ctx() -> &'static mut RendererViewportContext {
|
||||
unsafe {
|
||||
// should be safe as it is impossible to call any imgui function on a non-active context.
|
||||
&mut *((*(sys::igGetIO() as *const Io)).backend_renderer_user_data
|
||||
as *mut RendererViewportContext)
|
||||
}
|
||||
let a = UnsafeCell::new(RENDERER_VIEWPORT_BACKEND.lock().unwrap()).get();
|
||||
unsafe { (*a).as_mut().unwrap() }
|
||||
}
|
||||
|
||||
pub(crate) extern "C" fn platform_create_window(viewport: *mut Viewport) {
|
||||
@ -259,6 +261,8 @@ impl PlatformViewportContext {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for PlatformViewportContext {}
|
||||
|
||||
/// Trait that holds optional functions for a rendering backend to support multiple viewports.
|
||||
///
|
||||
/// It is completely fine to not use this Backend at all, as all functions are optional.
|
||||
@ -332,6 +336,8 @@ impl RendererViewportContext {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for RendererViewportContext {}
|
||||
|
||||
/// Describes a monitor that can be used by ImGui.
|
||||
#[repr(C)]
|
||||
pub struct PlatformMonitor {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user