mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-10 21:18:36 +00:00
turn global contexts into thread locals
This commit is contained in:
parent
5cfd7fe182
commit
ec123482c0
@ -664,7 +664,7 @@ impl Context {
|
||||
backend: Box::new(backend),
|
||||
};
|
||||
|
||||
*crate::PLATFORM_VIEWPORT_BACKEND.lock().unwrap() = Some(ctx);
|
||||
crate::PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|c| *c = Some(ctx));
|
||||
|
||||
let pio = self.platform_io_mut();
|
||||
pio.platform_create_window = Some(docking_utils::platform_create_window);
|
||||
@ -703,7 +703,7 @@ impl Context {
|
||||
backend: Box::new(backend),
|
||||
};
|
||||
|
||||
*crate::RENDERER_VIEWPORT_BACKEND.lock().unwrap() = Some(ctx);
|
||||
crate::RENDERER_VIEWPORT_CONTEXT.with_borrow_mut(|c| *c = Some(ctx));
|
||||
|
||||
let pio = self.platform_io_mut();
|
||||
pio.renderer_create_window = Some(docking_utils::renderer_create_window);
|
||||
|
||||
@ -1,17 +1,16 @@
|
||||
use std::{
|
||||
cell::UnsafeCell,
|
||||
cell::RefCell,
|
||||
ffi::{c_void, CStr},
|
||||
os::raw::{c_char, c_int},
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
use crate::{PlatformIo, Viewport};
|
||||
|
||||
pub(crate) static PLATFORM_VIEWPORT_BACKEND: Mutex<Option<crate::PlatformViewportContext>> =
|
||||
Mutex::new(None);
|
||||
thread_local!(
|
||||
pub(crate) static PLATFORM_VIEWPORT_CONTEXT: RefCell<Option<crate::PlatformViewportContext>> = const { RefCell::new(None) });
|
||||
|
||||
pub(crate) static RENDERER_VIEWPORT_BACKEND: Mutex<Option<crate::RendererViewportContext>> =
|
||||
Mutex::new(None);
|
||||
thread_local!(
|
||||
pub(crate) static RENDERER_VIEWPORT_CONTEXT: RefCell<Option<crate::RendererViewportContext>> = const { RefCell::new(None) });
|
||||
|
||||
/// Trait holding functions needed when the platform integration supports viewports.
|
||||
///
|
||||
@ -73,94 +72,108 @@ pub trait PlatformViewportBackend: 'static {
|
||||
) -> i32;
|
||||
}
|
||||
|
||||
/// Used to get the current Contexts [`PlatformViewportContext`].
|
||||
fn get_platform_ctx() -> &'static mut PlatformViewportContext {
|
||||
let a = UnsafeCell::new(PLATFORM_VIEWPORT_BACKEND.lock().unwrap()).get();
|
||||
unsafe { (*a).as_mut().unwrap() }
|
||||
#[inline]
|
||||
fn get_platform(
|
||||
ctx: &mut Option<PlatformViewportContext>,
|
||||
) -> &mut Box<dyn PlatformViewportBackend> {
|
||||
&mut ctx.as_mut().unwrap().backend
|
||||
}
|
||||
|
||||
/// Used to get the current Contexts [`RendererViewportContext`].
|
||||
fn get_renderer_ctx() -> &'static mut RendererViewportContext {
|
||||
let a = UnsafeCell::new(RENDERER_VIEWPORT_BACKEND.lock().unwrap()).get();
|
||||
unsafe { (*a).as_mut().unwrap() }
|
||||
#[inline]
|
||||
fn get_renderer(
|
||||
ctx: &mut Option<RendererViewportContext>,
|
||||
) -> &mut Box<dyn RendererViewportBackend> {
|
||||
&mut ctx.as_mut().unwrap().backend
|
||||
}
|
||||
|
||||
pub(crate) extern "C" fn platform_create_window(viewport: *mut Viewport) {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend.create_window(unsafe { &mut *viewport });
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx: &mut Option<crate::PlatformViewportContext>| {
|
||||
get_platform(ctx).create_window(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_destroy_window(viewport: *mut Viewport) {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend.destroy_window(unsafe { &mut *viewport });
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_platform(ctx).destroy_window(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) extern "C" fn platform_show_window(viewport: *mut Viewport) {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend.show_window(unsafe { &mut *viewport });
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_platform(ctx).show_window(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_set_window_pos(viewport: *mut Viewport, pos: sys::ImVec2) {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend
|
||||
.set_window_pos(unsafe { &mut *viewport }, [pos.x, pos.y]);
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_platform(ctx).set_window_pos(unsafe { &mut *viewport }, [pos.x, pos.y]);
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_get_window_pos(
|
||||
viewport: *mut Viewport,
|
||||
out_pos: *mut sys::ImVec2,
|
||||
) {
|
||||
let ctx = get_platform_ctx();
|
||||
let pos = ctx.backend.get_window_pos(unsafe { &mut *viewport });
|
||||
unsafe {
|
||||
*out_pos = sys::ImVec2::new(pos[0], pos[1]);
|
||||
}
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
let pos = get_platform(ctx).get_window_pos(unsafe { &mut *viewport });
|
||||
unsafe {
|
||||
*out_pos = sys::ImVec2::new(pos[0], pos[1]);
|
||||
}
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_set_window_size(viewport: *mut Viewport, size: sys::ImVec2) {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend
|
||||
.set_window_size(unsafe { &mut *viewport }, [size.x, size.y]);
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_platform(ctx).set_window_size(unsafe { &mut *viewport }, [size.x, size.y]);
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_get_window_size(
|
||||
viewport: *mut Viewport,
|
||||
out_size: *mut sys::ImVec2,
|
||||
) {
|
||||
let ctx = get_platform_ctx();
|
||||
let size = ctx.backend.get_window_size(unsafe { &mut *viewport });
|
||||
unsafe {
|
||||
*out_size = sys::ImVec2::new(size[0], size[1]);
|
||||
}
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx: &mut Option<crate::PlatformViewportContext>| {
|
||||
let size = get_platform(ctx).get_window_size(unsafe { &mut *viewport });
|
||||
unsafe {
|
||||
*out_size = sys::ImVec2::new(size[0], size[1]);
|
||||
}
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_set_window_focus(viewport: *mut Viewport) {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend.set_window_focus(unsafe { &mut *viewport });
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx: &mut Option<crate::PlatformViewportContext>| {
|
||||
get_platform(ctx).set_window_focus(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_get_window_focus(viewport: *mut Viewport) -> bool {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend.get_window_focus(unsafe { &mut *viewport })
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx: &mut Option<crate::PlatformViewportContext>| {
|
||||
get_platform(ctx).get_window_focus(unsafe { &mut *viewport })
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_get_window_minimized(viewport: *mut Viewport) -> bool {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend.get_window_minimized(unsafe { &mut *viewport })
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx: &mut Option<crate::PlatformViewportContext>| {
|
||||
get_platform(ctx).get_window_minimized(unsafe { &mut *viewport })
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_set_window_title(viewport: *mut Viewport, title: *const c_char) {
|
||||
let ctx = get_platform_ctx();
|
||||
let title = unsafe { CStr::from_ptr(title).to_str().unwrap() };
|
||||
ctx.backend
|
||||
.set_window_title(unsafe { &mut *viewport }, title);
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
let title = unsafe { CStr::from_ptr(title).to_str().unwrap() };
|
||||
get_platform(ctx).set_window_title(unsafe { &mut *viewport }, title);
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_set_window_alpha(viewport: *mut Viewport, alpha: f32) {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend
|
||||
.set_window_alpha(unsafe { &mut *viewport }, alpha);
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_platform(ctx).set_window_alpha(unsafe { &mut *viewport }, alpha);
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_update_window(viewport: *mut Viewport) {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend.update_window(unsafe { &mut *viewport });
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_platform(ctx).update_window(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_render_window(viewport: *mut Viewport, _arg: *mut c_void) {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend.render_window(unsafe { &mut *viewport });
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_platform(ctx).render_window(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_swap_buffers(viewport: *mut Viewport, _arg: *mut c_void) {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend.swap_buffers(unsafe { &mut *viewport });
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_platform(ctx).swap_buffers(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn platform_create_vk_surface(
|
||||
viewport: *mut Viewport,
|
||||
@ -168,11 +181,11 @@ pub(crate) extern "C" fn platform_create_vk_surface(
|
||||
_arg: *const c_void,
|
||||
out_surface: *mut u64,
|
||||
) -> c_int {
|
||||
let ctx = get_platform_ctx();
|
||||
ctx.backend
|
||||
.create_vk_surface(unsafe { &mut *viewport }, instance, unsafe {
|
||||
PLATFORM_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_platform(ctx).create_vk_surface(unsafe { &mut *viewport }, instance, unsafe {
|
||||
&mut *out_surface
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Just holds a [`PlatformViewportBackend`].
|
||||
@ -180,8 +193,6 @@ pub(crate) struct PlatformViewportContext {
|
||||
pub(crate) backend: Box<dyn PlatformViewportBackend>,
|
||||
}
|
||||
|
||||
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.
|
||||
@ -197,25 +208,29 @@ pub trait RendererViewportBackend: 'static {
|
||||
}
|
||||
|
||||
pub(crate) extern "C" fn renderer_create_window(viewport: *mut Viewport) {
|
||||
let ctx = get_renderer_ctx();
|
||||
ctx.backend.create_window(unsafe { &mut *viewport });
|
||||
RENDERER_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_renderer(ctx).create_window(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn renderer_destroy_window(viewport: *mut Viewport) {
|
||||
let ctx = get_renderer_ctx();
|
||||
ctx.backend.destroy_window(unsafe { &mut *viewport });
|
||||
RENDERER_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_renderer(ctx).destroy_window(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn renderer_set_window_size(viewport: *mut Viewport, size: sys::ImVec2) {
|
||||
let ctx = get_renderer_ctx();
|
||||
ctx.backend
|
||||
.set_window_size(unsafe { &mut *viewport }, [size.x, size.y]);
|
||||
RENDERER_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_renderer(ctx).set_window_size(unsafe { &mut *viewport }, [size.x, size.y]);
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn renderer_render_window(viewport: *mut Viewport, _arg: *mut c_void) {
|
||||
let ctx = get_renderer_ctx();
|
||||
ctx.backend.render_window(unsafe { &mut *viewport });
|
||||
RENDERER_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_renderer(ctx).render_window(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
pub(crate) extern "C" fn renderer_swap_buffers(viewport: *mut Viewport, _arg: *mut c_void) {
|
||||
let ctx = get_renderer_ctx();
|
||||
ctx.backend.swap_buffers(unsafe { &mut *viewport });
|
||||
RENDERER_VIEWPORT_CONTEXT.with_borrow_mut(|ctx| {
|
||||
get_renderer(ctx).swap_buffers(unsafe { &mut *viewport });
|
||||
})
|
||||
}
|
||||
|
||||
/// Just holds a [`RendererViewportBackend`].
|
||||
@ -223,8 +238,6 @@ pub(crate) struct RendererViewportContext {
|
||||
pub(crate) backend: Box<dyn RendererViewportBackend>,
|
||||
}
|
||||
|
||||
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