Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add PlotPoints::Borrowed
Browse files Browse the repository at this point in the history
mo8it committed Jul 30, 2024
1 parent d00fa85 commit d9030dc
Showing 6 changed files with 73 additions and 56 deletions.
26 changes: 13 additions & 13 deletions demo/src/plot_demo.rs
Original file line number Diff line number Diff line change
@@ -209,9 +209,9 @@ impl LineDemo {
});
}

fn circle(&self) -> Line {
fn circle<'a>(&self) -> Line<'a> {
let n = 512;
let circle_points: PlotPoints = (0..=n)
let circle_points: PlotPoints<'_> = (0..=n)
.map(|i| {
let t = remap(i as f64, 0.0..=(n as f64), 0.0..=TAU);
let r = self.circle_radius;
@@ -227,7 +227,7 @@ impl LineDemo {
.name("circle")
}

fn sin(&self) -> Line {
fn sin<'a>(&self) -> Line<'a> {
let time = self.time;
Line::new(PlotPoints::from_explicit_callback(
move |x| 0.5 * (2.0 * x).sin() * time.sin(),
@@ -239,7 +239,7 @@ impl LineDemo {
.name("wave")
}

fn thingy(&self) -> Line {
fn thingy<'a>(&self) -> Line<'a> {
let time = self.time;
Line::new(PlotPoints::from_parametric_callback(
move |t| ((2.0 * t + time).sin(), (3.0 * t).sin()),
@@ -304,7 +304,7 @@ impl Default for MarkerDemo {
}

impl MarkerDemo {
fn markers(&self) -> Vec<Points> {
fn markers<'a>(&self) -> Vec<Points<'a>> {
MarkerShape::all()
.enumerate()
.map(|(i, marker)| {
@@ -367,23 +367,23 @@ struct LegendDemo {
}

impl LegendDemo {
fn line_with_slope(slope: f64) -> Line {
fn line_with_slope<'a>(slope: f64) -> Line<'a> {
Line::new(PlotPoints::from_explicit_callback(
move |x| slope * x,
..,
100,
))
}

fn sin() -> Line {
fn sin<'a>() -> Line<'a> {
Line::new(PlotPoints::from_explicit_callback(
move |x| x.sin(),
..,
100,
))
}

fn cos() -> Line {
fn cos<'a>() -> Line<'a> {
Line::new(PlotPoints::from_explicit_callback(
move |x| x.cos(),
..,
@@ -444,7 +444,7 @@ impl CustomAxesDemo {
const MINS_PER_DAY: f64 = 24.0 * 60.0;
const MINS_PER_H: f64 = 60.0;

fn logistic_fn() -> Line {
fn logistic_fn<'a>() -> Line<'a> {
fn days(min: f64) -> f64 {
CustomAxesDemo::MINS_PER_DAY * min
}
@@ -598,31 +598,31 @@ impl Default for LinkedAxesDemo {
}

impl LinkedAxesDemo {
fn line_with_slope(slope: f64) -> Line {
fn line_with_slope<'a>(slope: f64) -> Line<'a> {
Line::new(PlotPoints::from_explicit_callback(
move |x| slope * x,
..,
100,
))
}

fn sin() -> Line {
fn sin<'a>() -> Line<'a> {
Line::new(PlotPoints::from_explicit_callback(
move |x| x.sin(),
..,
100,
))
}

fn cos() -> Line {
fn cos<'a>() -> Line<'a> {
Line::new(PlotPoints::from_explicit_callback(
move |x| x.cos(),
..,
100,
))
}

fn configure_plot(plot_ui: &mut egui_plot::PlotUi) {
fn configure_plot(plot_ui: &mut egui_plot::PlotUi<'_>) {
plot_ui.line(Self::line_with_slope(0.5));
plot_ui.line(Self::line_with_slope(1.0));
plot_ui.line(Self::line_with_slope(2.0));
42 changes: 21 additions & 21 deletions egui_plot/src/items/mod.rs
Original file line number Diff line number Diff line change
@@ -420,8 +420,8 @@ impl PlotItem for VLine {
}

/// A series of values forming a path.
pub struct Line {
pub(super) series: PlotPoints,
pub struct Line<'a> {
pub(super) series: PlotPoints<'a>,
pub(super) stroke: Stroke,
pub(super) name: String,
pub(super) highlight: bool,
@@ -431,8 +431,8 @@ pub struct Line {
id: Option<Id>,
}

impl Line {
pub fn new(series: impl Into<PlotPoints>) -> Self {
impl<'a> Line<'a> {
pub fn new(series: impl Into<PlotPoints<'a>>) -> Self {
Self {
series: series.into(),
stroke: Stroke::new(1.5, Color32::TRANSPARENT), // Note: a stroke of 1.0 (or less) can look bad on low-dpi-screens
@@ -522,7 +522,7 @@ fn y_intersection(p1: &Pos2, p2: &Pos2, y: f32) -> Option<f32> {
.then_some(((y * (p1.x - p2.x)) - (p1.x * p2.y - p1.y * p2.x)) / (p1.y - p2.y))
}

impl PlotItem for Line {
impl<'a> PlotItem for Line<'a> {
fn shapes(&self, _ui: &Ui, transform: &PlotTransform, shapes: &mut Vec<Shape>) {
let Self {
series,
@@ -620,8 +620,8 @@ impl PlotItem for Line {
}

/// A convex polygon.
pub struct Polygon {
pub(super) series: PlotPoints,
pub struct Polygon<'a> {
pub(super) series: PlotPoints<'a>,
pub(super) stroke: Stroke,
pub(super) name: String,
pub(super) highlight: bool,
@@ -631,8 +631,8 @@ pub struct Polygon {
id: Option<Id>,
}

impl Polygon {
pub fn new(series: impl Into<PlotPoints>) -> Self {
impl<'a> Polygon<'a> {
pub fn new(series: impl Into<PlotPoints<'a>>) -> Self {
Self {
series: series.into(),
stroke: Stroke::new(1.0, Color32::TRANSPARENT),
@@ -709,7 +709,7 @@ impl Polygon {
}
}

impl PlotItem for Polygon {
impl<'a> PlotItem for Polygon<'a> {
fn shapes(&self, _ui: &Ui, transform: &PlotTransform, shapes: &mut Vec<Shape>) {
let Self {
series,
@@ -918,8 +918,8 @@ impl PlotItem for Text {
}

/// A set of points.
pub struct Points {
pub(super) series: PlotPoints,
pub struct Points<'a> {
pub(super) series: PlotPoints<'a>,

pub(super) shape: MarkerShape,

@@ -942,8 +942,8 @@ pub struct Points {
id: Option<Id>,
}

impl Points {
pub fn new(series: impl Into<PlotPoints>) -> Self {
impl<'a> Points<'a> {
pub fn new(series: impl Into<PlotPoints<'a>>) -> Self {
Self {
series: series.into(),
shape: MarkerShape::Circle,
@@ -1028,7 +1028,7 @@ impl Points {
}
}

impl PlotItem for Points {
impl<'a> PlotItem for Points<'a> {
#[allow(clippy::too_many_lines)] // TODO(emilk): shorten this function
fn shapes(&self, _ui: &Ui, transform: &PlotTransform, shapes: &mut Vec<Shape>) {
let sqrt_3 = 3_f32.sqrt();
@@ -1196,9 +1196,9 @@ impl PlotItem for Points {
}

/// A set of arrows.
pub struct Arrows {
pub(super) origins: PlotPoints,
pub(super) tips: PlotPoints,
pub struct Arrows<'a> {
pub(super) origins: PlotPoints<'a>,
pub(super) tips: PlotPoints<'a>,
pub(super) tip_length: Option<f32>,
pub(super) color: Color32,
pub(super) name: String,
@@ -1207,8 +1207,8 @@ pub struct Arrows {
id: Option<Id>,
}

impl Arrows {
pub fn new(origins: impl Into<PlotPoints>, tips: impl Into<PlotPoints>) -> Self {
impl<'a> Arrows<'a> {
pub fn new(origins: impl Into<PlotPoints<'a>>, tips: impl Into<PlotPoints<'a>>) -> Self {
Self {
origins: origins.into(),
tips: tips.into(),
@@ -1270,7 +1270,7 @@ impl Arrows {
}
}

impl PlotItem for Arrows {
impl<'a> PlotItem for Arrows<'a> {
fn shapes(&self, _ui: &Ui, transform: &PlotTransform, shapes: &mut Vec<Shape>) {
let Self {
origins,
31 changes: 24 additions & 7 deletions egui_plot/src/items/values.rs
Original file line number Diff line number Diff line change
@@ -154,37 +154,45 @@ impl Default for Orientation {
/// Represents many [`PlotPoint`]s.
///
/// These can be an owned `Vec` or generated with a function.
pub enum PlotPoints {
pub enum PlotPoints<'a> {
Owned(Vec<PlotPoint>),
Generator(ExplicitGenerator),
// Borrowed(&[PlotPoint]), // TODO(EmbersArc): Lifetimes are tricky in this case.
Borrowed(&'a [PlotPoint]),
}

impl Default for PlotPoints {
impl<'a> Default for PlotPoints<'a> {
fn default() -> Self {
Self::Owned(Vec::new())
}
}

impl From<[f64; 2]> for PlotPoints {
impl<'a> From<[f64; 2]> for PlotPoints<'a> {
fn from(coordinate: [f64; 2]) -> Self {
Self::new(vec![coordinate])
}
}

impl From<Vec<[f64; 2]>> for PlotPoints {
impl<'a> From<Vec<[f64; 2]>> for PlotPoints<'a> {
#[inline]
fn from(coordinates: Vec<[f64; 2]>) -> Self {
Self::new(coordinates)
}
}

impl FromIterator<[f64; 2]> for PlotPoints {
impl<'a> From<&'a [PlotPoint]> for PlotPoints<'a> {
#[inline]
fn from(points: &'a [PlotPoint]) -> Self {
Self::Borrowed(points)
}
}

impl<'a> FromIterator<[f64; 2]> for PlotPoints<'a> {
fn from_iter<T: IntoIterator<Item = [f64; 2]>>(iter: T) -> Self {
Self::Owned(iter.into_iter().map(|point| point.into()).collect())
}
}

impl PlotPoints {
impl<'a> PlotPoints<'a> {
pub fn new(points: Vec<[f64; 2]>) -> Self {
Self::from_iter(points)
}
@@ -193,6 +201,7 @@ impl PlotPoints {
match self {
Self::Owned(points) => points.as_slice(),
Self::Generator(_) => &[],
Self::Borrowed(points) => points,
}
}

@@ -271,6 +280,7 @@ impl PlotPoints {
match self {
Self::Owned(points) => points.is_empty(),
Self::Generator(_) => false,
Self::Borrowed(points) => points.is_empty(),
}
}

@@ -314,6 +324,13 @@ impl PlotPoints {
bounds
}
Self::Generator(generator) => generator.estimate_bounds(),
Self::Borrowed(points) => {
let mut bounds = PlotBounds::NOTHING;
for point in *points {
bounds.extend_with(point);
}
bounds
}
}
}
}
4 changes: 2 additions & 2 deletions egui_plot/src/legend.rs
Original file line number Diff line number Diff line change
@@ -187,10 +187,10 @@ pub(super) struct LegendWidget {
impl LegendWidget {
/// Create a new legend from items, the names of items that are hidden and the style of the
/// text. Returns `None` if the legend has no entries.
pub(super) fn try_new(
pub(super) fn try_new<'a>(
rect: Rect,
config: Legend,
items: &[Box<dyn PlotItem>],
items: &[Box<dyn PlotItem + 'a>],
hidden_items: &ahash::HashSet<String>, // Existing hidden items in the plot memory.
) -> Option<Self> {
// If `config.hidden_items` is not `None`, it is used.
10 changes: 5 additions & 5 deletions egui_plot/src/lib.rs
Original file line number Diff line number Diff line change
@@ -728,20 +728,20 @@ impl<'a> Plot<'a> {
}

/// Interact with and add items to the plot and finally draw it.
pub fn show<R>(
pub fn show<'b, R>(
self,
ui: &mut Ui,
build_fn: impl FnOnce(&mut PlotUi) -> R + 'a,
build_fn: impl FnOnce(&mut PlotUi<'b>) -> R + 'a,
) -> PlotResponse<R> {
self.show_dyn(ui, Box::new(build_fn))
}

#[allow(clippy::too_many_lines)] // TODO(emilk): shorten this function
#[allow(clippy::type_complexity)] // build_fn
fn show_dyn<R>(
fn show_dyn<'b, R>(
self,
ui: &mut Ui,
build_fn: Box<dyn FnOnce(&mut PlotUi) -> R + 'a>,
build_fn: Box<dyn FnOnce(&mut PlotUi<'b>) -> R + 'a>,
) -> PlotResponse<R> {
let Self {
id_source,
@@ -1467,7 +1467,7 @@ pub fn uniform_grid_spacer<'a>(spacer: impl Fn(GridInput) -> [f64; 3] + 'a) -> G
// ----------------------------------------------------------------------------

struct PreparedPlot<'a> {
items: Vec<Box<dyn PlotItem>>,
items: Vec<Box<dyn PlotItem + 'a>>,
show_x: bool,
show_y: bool,
label_formatter: LabelFormatter<'a>,
16 changes: 8 additions & 8 deletions egui_plot/src/plot_ui.rs
Original file line number Diff line number Diff line change
@@ -7,17 +7,17 @@ use crate::Plot;

/// Provides methods to interact with a plot while building it. It is the single argument of the closure
/// provided to [`Plot::show`]. See [`Plot`] for an example of how to use it.
pub struct PlotUi {
pub struct PlotUi<'a> {
pub(crate) ctx: egui::Context,
pub(crate) items: Vec<Box<dyn PlotItem>>,
pub(crate) items: Vec<Box<dyn PlotItem + 'a>>,
pub(crate) next_auto_color_idx: usize,
pub(crate) last_plot_transform: PlotTransform,
pub(crate) last_auto_bounds: Vec2b,
pub(crate) response: Response,
pub(crate) bounds_modifications: Vec<BoundsModification>,
}

impl PlotUi {
impl<'a> PlotUi<'a> {
fn auto_color(&mut self) -> Color32 {
let i = self.next_auto_color_idx;
self.next_auto_color_idx += 1;
@@ -122,12 +122,12 @@ impl PlotUi {
}

/// Add an arbitrary item.
pub fn add(&mut self, item: impl PlotItem + 'static) {
pub fn add(&mut self, item: impl PlotItem + 'a) {
self.items.push(Box::new(item));
}

/// Add a data line.
pub fn line(&mut self, mut line: crate::Line) {
pub fn line(&mut self, mut line: crate::Line<'a>) {
if line.series.is_empty() {
return;
};
@@ -140,7 +140,7 @@ impl PlotUi {
}

/// Add a polygon. The polygon has to be convex.
pub fn polygon(&mut self, mut polygon: crate::Polygon) {
pub fn polygon(&mut self, mut polygon: crate::Polygon<'a>) {
if polygon.series.is_empty() {
return;
};
@@ -162,7 +162,7 @@ impl PlotUi {
}

/// Add data points.
pub fn points(&mut self, mut points: crate::Points) {
pub fn points(&mut self, mut points: crate::Points<'a>) {
if points.series.is_empty() {
return;
};
@@ -175,7 +175,7 @@ impl PlotUi {
}

/// Add arrows.
pub fn arrows(&mut self, mut arrows: crate::Arrows) {
pub fn arrows(&mut self, mut arrows: crate::Arrows<'a>) {
if arrows.origins.is_empty() || arrows.tips.is_empty() {
return;
};

0 comments on commit d9030dc

Please sign in to comment.