2020-10-11 13:22:55 +00:00
|
|
|
// 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
|
|
|
|
// unless one "does it right", so it's not a real solution.
|
|
|
|
//
|
|
|
|
// The context should have to be created, and ideally it should be difficult to impossible
|
|
|
|
// to do things without having a context. implot-rs makes it so that there is a context and
|
|
|
|
// that context has a "frame()" function that returns a Ui, and that Ui is then used to create
|
|
|
|
// widgets. Windows are built with a build() function that takes a reference to that Ui as an
|
|
|
|
// argument, but also have a begin() function that take a context and put it in their token.
|
|
|
|
//
|
|
|
|
// I think I'll mirror that here, except that we don't need a frame() function, it's enough
|
|
|
|
// to create a context once and then keep passing it around. I'll hence need a mutex and
|
|
|
|
// a mechansim similar (or equal) to what imgui-rs does for making sure there can only be
|
|
|
|
// a single context. Implementation could go roughly like this:
|
|
|
|
//
|
|
|
|
// - Add a mutex for modifying context things
|
|
|
|
// - Make creation and drop functions use that mutex
|
|
|
|
// - Change Plot, PlotLine, PlotScatter, PlotBars, PlotText to all require a context.
|
|
|
|
// 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.
|
2020-10-11 14:25:48 +00:00
|
|
|
use parking_lot::ReentrantMutex;
|
|
|
|
|
|
|
|
use crate::PlotUi;
|
2020-10-11 13:42:30 +00:00
|
|
|
|
2020-10-11 13:22:55 +00:00
|
|
|
/// An implot context.
|
|
|
|
///
|
|
|
|
/// A context is required to do most of the things this library provides. While this was created
|
|
|
|
/// implicitly in earlier versions of the library, it is now created explicitly.
|
|
|
|
pub struct Context {
|
|
|
|
raw: *mut sys::ImPlotContext,
|
|
|
|
}
|
|
|
|
|
2020-10-11 13:42:30 +00:00
|
|
|
lazy_static! {
|
2020-10-11 14:25:48 +00:00
|
|
|
// This mutex is used to guard any accesses to the context
|
2020-10-11 13:42:30 +00:00
|
|
|
static ref CTX_MUTEX: ReentrantMutex<()> = ReentrantMutex::new(());
|
|
|
|
}
|
|
|
|
|
|
|
|
fn no_current_context() -> bool {
|
|
|
|
let ctx = unsafe { sys::ImPlot_GetCurrentContext() };
|
|
|
|
ctx.is_null()
|
|
|
|
}
|
|
|
|
|
2020-10-11 13:22:55 +00:00
|
|
|
impl Context {
|
|
|
|
/// Create a context.
|
|
|
|
pub fn create() -> Self {
|
2020-10-11 13:42:30 +00:00
|
|
|
let _guard = CTX_MUTEX.lock();
|
|
|
|
assert!(
|
|
|
|
no_current_context(),
|
|
|
|
"A new active context cannot be created, because another one already exists"
|
|
|
|
);
|
|
|
|
|
2020-10-11 13:22:55 +00:00
|
|
|
let ctx = unsafe { sys::ImPlot_CreateContext() };
|
|
|
|
unsafe {
|
|
|
|
sys::ImPlot_SetCurrentContext(ctx);
|
|
|
|
}
|
|
|
|
Self { raw: ctx }
|
|
|
|
}
|
2020-10-11 14:25:48 +00:00
|
|
|
|
|
|
|
/// Get a "plot ui" struct, this will be used to build actual plots.
|
|
|
|
pub fn get_plot_ui(&self) -> PlotUi {
|
|
|
|
PlotUi { context: self }
|
|
|
|
}
|
2020-10-11 13:22:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for Context {
|
|
|
|
fn drop(&mut self) {
|
2020-10-11 13:42:30 +00:00
|
|
|
let _guard = CTX_MUTEX.lock();
|
2020-10-11 13:22:55 +00:00
|
|
|
unsafe {
|
|
|
|
sys::ImPlot_DestroyContext(self.raw);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|