mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-14 06:58:35 +00:00
Allow simultaneous access to different draw lists
Only need to prevent accessing the same draw-list twice at one time Closes #488
This commit is contained in:
parent
bb43463c2e
commit
52898779e1
@ -19,8 +19,17 @@ fn draw_text_centered(
|
||||
fn main() {
|
||||
let system = support::init(file!());
|
||||
system.main_loop(move |_, ui| {
|
||||
|
||||
// Get access to draw FG and BG draw lists.
|
||||
let bg_draw_list = ui.get_background_draw_list();
|
||||
let fg_draw_list = ui.get_foreground_draw_list();
|
||||
|
||||
// Note we cannot access two instances of the same draw list
|
||||
// at once. That is to say, the following line would panic if
|
||||
// uncommented:
|
||||
//let bg_draw_list_2 = ui.get_background_draw_list(); // panic!
|
||||
|
||||
{
|
||||
let bg_draw_list = ui.get_background_draw_list();
|
||||
bg_draw_list
|
||||
.add_circle([150.0, 150.0], 150.0, [1.0, 0.0, 0.0])
|
||||
.thickness(4.0)
|
||||
@ -36,7 +45,6 @@ fn main() {
|
||||
|
||||
{
|
||||
let [w, h] = ui.io().display_size;
|
||||
let fg_draw_list = ui.get_foreground_draw_list();
|
||||
fg_draw_list
|
||||
.add_circle([w - 150.0, h - 150.0], 150.0, [1.0, 0.0, 0.0])
|
||||
.thickness(4.0)
|
||||
|
||||
@ -61,27 +61,47 @@ bitflags!(
|
||||
}
|
||||
);
|
||||
|
||||
enum DrawListType {
|
||||
Window,
|
||||
Background,
|
||||
Foreground,
|
||||
}
|
||||
|
||||
/// Object implementing the custom draw API.
|
||||
///
|
||||
/// Called from [`Ui::get_window_draw_list`], [`Ui::get_background_draw_list`] or [`Ui::get_foreground_draw_list`].
|
||||
/// No more than one instance of this structure can live in a program at the same time.
|
||||
/// The program will panic on creating a second instance.
|
||||
pub struct DrawListMut<'ui> {
|
||||
draw_list_type: DrawListType,
|
||||
draw_list: *mut ImDrawList,
|
||||
_phantom: PhantomData<&'ui Ui<'ui>>,
|
||||
}
|
||||
|
||||
static DRAW_LIST_LOADED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
|
||||
// Lock for each variant of draw list. See https://github.com/imgui-rs/imgui-rs/issues/488
|
||||
static DRAW_LIST_LOADED_WINDOW: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
|
||||
static DRAW_LIST_LOADED_BACKGROUND: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
|
||||
static DRAW_LIST_LOADED_FOREGROUND: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
|
||||
|
||||
impl<'ui> Drop for DrawListMut<'ui> {
|
||||
fn drop(&mut self) {
|
||||
DRAW_LIST_LOADED.store(false, std::sync::atomic::Ordering::Release);
|
||||
match self.draw_list_type {
|
||||
DrawListType::Window => &DRAW_LIST_LOADED_WINDOW,
|
||||
DrawListType::Background => &DRAW_LIST_LOADED_BACKGROUND,
|
||||
DrawListType::Foreground => &DRAW_LIST_LOADED_FOREGROUND,
|
||||
}.store(false, std::sync::atomic::Ordering::Release);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ui> DrawListMut<'ui> {
|
||||
fn lock_draw_list() {
|
||||
let already_loaded = DRAW_LIST_LOADED
|
||||
fn lock_draw_list(t: DrawListType) {
|
||||
let lock = match t {
|
||||
DrawListType::Window => &DRAW_LIST_LOADED_WINDOW,
|
||||
DrawListType::Background => &DRAW_LIST_LOADED_BACKGROUND,
|
||||
DrawListType::Foreground => &DRAW_LIST_LOADED_FOREGROUND,
|
||||
};
|
||||
|
||||
let already_loaded = lock
|
||||
.compare_exchange(
|
||||
false,
|
||||
true,
|
||||
@ -90,33 +110,42 @@ impl<'ui> DrawListMut<'ui> {
|
||||
)
|
||||
.is_err();
|
||||
if already_loaded {
|
||||
panic!("DrawListMut is already loaded! You can only load one instance of it!")
|
||||
let name = match t {
|
||||
DrawListType::Window => "window",
|
||||
DrawListType::Background => "background",
|
||||
DrawListType::Foreground => "foreground",
|
||||
};
|
||||
panic!("The DrawListMut instance for the {} draw list is already loaded! You can only load one instance of it!", name)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "GetWindowDrawList")]
|
||||
pub(crate) fn window(_: &Ui<'ui>) -> Self {
|
||||
Self::lock_draw_list();
|
||||
Self::lock_draw_list(DrawListType::Window);
|
||||
|
||||
Self {
|
||||
draw_list: unsafe { sys::igGetWindowDrawList() },
|
||||
draw_list_type: DrawListType::Window,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "GetBackgroundDrawList")]
|
||||
pub(crate) fn background(_: &Ui<'ui>) -> Self {
|
||||
Self::lock_draw_list();
|
||||
Self::lock_draw_list(DrawListType::Background);
|
||||
Self {
|
||||
draw_list: unsafe { sys::igGetBackgroundDrawList() },
|
||||
draw_list_type: DrawListType::Background,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "GetForegroundDrawList")]
|
||||
pub(crate) fn foreground(_: &Ui<'ui>) -> Self {
|
||||
Self::lock_draw_list();
|
||||
Self::lock_draw_list(DrawListType::Foreground);
|
||||
Self {
|
||||
draw_list: unsafe { sys::igGetForegroundDrawList() },
|
||||
draw_list_type: DrawListType::Foreground,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user