diff --git a/Cargo.toml b/Cargo.toml index 0da034c..166f8b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,8 @@ categories = ["gui", "api-bindings"] [dependencies] implot-sys = { version = "0.1.0", path = "implot-sys" } bitflags = "1.0" +parking_lot = "0.11" +lazy_static = "1.1" [workspace] diff --git a/src/context.rs b/src/context.rs index 924498e..d841407 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,3 +1,5 @@ +use parking_lot::ReentrantMutex; + // TODO(4bb4) Do this properly. // I already added a simple Context struct that can be created once and used as long as it is not // dropped here for initial tests - this is of course neither threadsafe nor otherwise safe to use @@ -20,7 +22,7 @@ // I think I'll call this PlotUi to mimmick imgui-rs' Ui. // - Think about what this means in terms of the stacks and things like is_plot_hovered() - // they should also only work when there is a context available. -// + /// An implot context. /// /// A context is required to do most of the things this library provides. While this was created @@ -29,9 +31,26 @@ pub struct Context { raw: *mut sys::ImPlotContext, } +lazy_static! { + // This mutex needs to be used to guard all public functions that can affect the underlying + // ImPlot active context + static ref CTX_MUTEX: ReentrantMutex<()> = ReentrantMutex::new(()); +} + +fn no_current_context() -> bool { + let ctx = unsafe { sys::ImPlot_GetCurrentContext() }; + ctx.is_null() +} + impl Context { /// Create a context. pub fn create() -> Self { + let _guard = CTX_MUTEX.lock(); + assert!( + no_current_context(), + "A new active context cannot be created, because another one already exists" + ); + let ctx = unsafe { sys::ImPlot_CreateContext() }; unsafe { sys::ImPlot_SetCurrentContext(ctx); @@ -42,6 +61,7 @@ impl Context { impl Drop for Context { fn drop(&mut self) { + let _guard = CTX_MUTEX.lock(); unsafe { sys::ImPlot_DestroyContext(self.raw); } diff --git a/src/lib.rs b/src/lib.rs index 43ad920..d0c8124 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,10 @@ //! //! pub extern crate implot_sys as sys; + +#[macro_use] +extern crate lazy_static; + pub use sys::imgui::Condition; // TODO(4bb4) facade-wrap these pub use sys::{ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4};