Linked context into things, adapted examples.

This commit is contained in:
4bb4 2020-10-11 16:25:48 +02:00
parent 5d4d570507
commit ea960bd30d
7 changed files with 85 additions and 69 deletions

View file

@ -1,5 +1,3 @@
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
@ -22,6 +20,9 @@ use parking_lot::ReentrantMutex;
// 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.
use parking_lot::ReentrantMutex;
use crate::PlotUi;
/// An implot context.
///
@ -32,8 +33,7 @@ pub struct Context {
}
lazy_static! {
// This mutex needs to be used to guard all public functions that can affect the underlying
// ImPlot active context
// This mutex is used to guard any accesses to the context
static ref CTX_MUTEX: ReentrantMutex<()> = ReentrantMutex::new(());
}
@ -57,6 +57,11 @@ impl Context {
}
Self { raw: ctx }
}
/// Get a "plot ui" struct, this will be used to build actual plots.
pub fn get_plot_ui(&self) -> PlotUi {
PlotUi { context: self }
}
}
impl Drop for Context {

View file

@ -12,23 +12,25 @@ 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};
// TODO(4bb4) facade-wrap these?
pub use sys::{imgui::Condition, ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4};
// Plot struct and associated enums
pub mod context;
pub mod plot;
pub mod plot_elements;
pub use self::context::*;
pub use self::plot::*;
pub use self::plot_elements::*;
pub use context::Context;
pub use plot::{AxisFlags, Plot, PlotFlags};
pub use plot_elements::{PlotBars, PlotLine, PlotScatter, PlotText};
mod context;
mod plot;
mod plot_elements;
// --- Enum definitions --------------------------------------------------------------------------
// Things that are to be combined like flags are done using bitflags, and things that are meant
// as enumerations in the traditional sense are plain enums.
/// A temporary reference for building plots. This does not really do anything on its own at
/// this point, but it is used to enforce that a context is created and active for other features,
/// such as creating plots.
pub struct PlotUi<'ui> {
context: &'ui Context,
}
// --- Markers, color maps, style variables----------------------------------------------------
/// Markers, documentation copied from implot.h for convenience.
#[repr(i32)]
#[derive(Copy, Clone, Debug)]
@ -190,11 +192,6 @@ pub enum StyleVar {
PlotMinSize = sys::ImPlotStyleVar__ImPlotStyleVar_PlotMinSize,
}
// --- Context -----------------------------------------------------------------------------------
// --- Main plot structure -----------------------------------------------------------------------
// --- Color maps -----------------------------------------------------------------------------
/// Switch to one of the built-in preset colormaps. If samples is greater than 1, the map will be
/// linearly resampled.
pub fn set_colormap_from_preset(preset: Colormap, samples: u32) {

View file

@ -8,6 +8,8 @@ pub use sys::imgui::Condition;
use sys::imgui::{im_str, ImString};
pub use sys::{ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4};
use crate::{Context, PlotUi};
const DEFAULT_PLOT_SIZE_X: f32 = 400.0;
const DEFAULT_PLOT_SIZE_Y: f32 = 400.0;
@ -375,7 +377,7 @@ impl Plot {
///
/// For a convenient implementation of all this, use [`build()`](struct.Plot.html#method.build)
/// instead.
pub fn begin(&self) -> Option<PlotToken> {
pub fn begin(&self, plot_ui: &PlotUi) -> Option<PlotToken> {
self.maybe_set_axis_limits();
self.maybe_set_tick_labels();
@ -398,8 +400,8 @@ impl Plot {
if should_render {
Some(PlotToken {
context: plot_ui.context,
plot_title: self.title.clone(),
has_ended: false,
})
} else {
// In contrast with imgui windows, end() does not have to be
@ -412,8 +414,8 @@ impl Plot {
///
/// Note: the closure is not called if ImPlot::BeginPlot() returned
/// false - TODO(4bb4) figure out if this is if things are not rendered
pub fn build<F: FnOnce()>(self, f: F) {
if let Some(token) = self.begin() {
pub fn build<F: FnOnce()>(self, plot_ui: &PlotUi, f: F) {
if let Some(token) = self.begin(plot_ui) {
f();
token.end()
}
@ -422,23 +424,22 @@ impl Plot {
/// Tracks a plot that must be ended by calling `.end()`
pub struct PlotToken {
context: *const Context,
/// For better error messages
plot_title: String,
/// Whether end() has been called on this already or not
has_ended: bool,
}
impl PlotToken {
/// End a previously begin()'ed plot.
pub fn end(mut self) {
self.has_ended = true;
self.context = std::ptr::null();
unsafe { sys::ImPlot_EndPlot() };
}
}
impl Drop for PlotToken {
fn drop(&mut self) {
if !self.has_ended && !std::thread::panicking() {
if !self.context.is_null() && !std::thread::panicking() {
panic!(
"Warning: A PlotToken for plot \"{}\" was not called end() on",
self.plot_title