mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-27 13:28:28 +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() {
|
fn main() {
|
||||||
let system = support::init(file!());
|
let system = support::init(file!());
|
||||||
system.main_loop(move |_, ui| {
|
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
|
bg_draw_list
|
||||||
.add_circle([150.0, 150.0], 150.0, [1.0, 0.0, 0.0])
|
.add_circle([150.0, 150.0], 150.0, [1.0, 0.0, 0.0])
|
||||||
.thickness(4.0)
|
.thickness(4.0)
|
||||||
@ -36,7 +45,6 @@ fn main() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let [w, h] = ui.io().display_size;
|
let [w, h] = ui.io().display_size;
|
||||||
let fg_draw_list = ui.get_foreground_draw_list();
|
|
||||||
fg_draw_list
|
fg_draw_list
|
||||||
.add_circle([w - 150.0, h - 150.0], 150.0, [1.0, 0.0, 0.0])
|
.add_circle([w - 150.0, h - 150.0], 150.0, [1.0, 0.0, 0.0])
|
||||||
.thickness(4.0)
|
.thickness(4.0)
|
||||||
|
|||||||
@ -61,27 +61,47 @@ bitflags!(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
enum DrawListType {
|
||||||
|
Window,
|
||||||
|
Background,
|
||||||
|
Foreground,
|
||||||
|
}
|
||||||
|
|
||||||
/// Object implementing the custom draw API.
|
/// Object implementing the custom draw API.
|
||||||
///
|
///
|
||||||
/// Called from [`Ui::get_window_draw_list`], [`Ui::get_background_draw_list`] or [`Ui::get_foreground_draw_list`].
|
/// 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.
|
/// 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.
|
/// The program will panic on creating a second instance.
|
||||||
pub struct DrawListMut<'ui> {
|
pub struct DrawListMut<'ui> {
|
||||||
|
draw_list_type: DrawListType,
|
||||||
draw_list: *mut ImDrawList,
|
draw_list: *mut ImDrawList,
|
||||||
_phantom: PhantomData<&'ui Ui<'ui>>,
|
_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> {
|
impl<'ui> Drop for DrawListMut<'ui> {
|
||||||
fn drop(&mut self) {
|
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> {
|
impl<'ui> DrawListMut<'ui> {
|
||||||
fn lock_draw_list() {
|
fn lock_draw_list(t: DrawListType) {
|
||||||
let already_loaded = DRAW_LIST_LOADED
|
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(
|
.compare_exchange(
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
@ -90,33 +110,42 @@ impl<'ui> DrawListMut<'ui> {
|
|||||||
)
|
)
|
||||||
.is_err();
|
.is_err();
|
||||||
if already_loaded {
|
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")]
|
#[doc(alias = "GetWindowDrawList")]
|
||||||
pub(crate) fn window(_: &Ui<'ui>) -> Self {
|
pub(crate) fn window(_: &Ui<'ui>) -> Self {
|
||||||
Self::lock_draw_list();
|
Self::lock_draw_list(DrawListType::Window);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
draw_list: unsafe { sys::igGetWindowDrawList() },
|
draw_list: unsafe { sys::igGetWindowDrawList() },
|
||||||
|
draw_list_type: DrawListType::Window,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(alias = "GetBackgroundDrawList")]
|
#[doc(alias = "GetBackgroundDrawList")]
|
||||||
pub(crate) fn background(_: &Ui<'ui>) -> Self {
|
pub(crate) fn background(_: &Ui<'ui>) -> Self {
|
||||||
Self::lock_draw_list();
|
Self::lock_draw_list(DrawListType::Background);
|
||||||
Self {
|
Self {
|
||||||
draw_list: unsafe { sys::igGetBackgroundDrawList() },
|
draw_list: unsafe { sys::igGetBackgroundDrawList() },
|
||||||
|
draw_list_type: DrawListType::Background,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(alias = "GetForegroundDrawList")]
|
#[doc(alias = "GetForegroundDrawList")]
|
||||||
pub(crate) fn foreground(_: &Ui<'ui>) -> Self {
|
pub(crate) fn foreground(_: &Ui<'ui>) -> Self {
|
||||||
Self::lock_draw_list();
|
Self::lock_draw_list(DrawListType::Foreground);
|
||||||
Self {
|
Self {
|
||||||
draw_list: unsafe { sys::igGetForegroundDrawList() },
|
draw_list: unsafe { sys::igGetForegroundDrawList() },
|
||||||
|
draw_list_type: DrawListType::Foreground,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user