diff options
Diffstat (limited to '')
| -rw-r--r-- | wgpu/src/widget/canvas.rs | 46 | ||||
| -rw-r--r-- | wgpu/src/widget/canvas/cache.rs (renamed from wgpu/src/widget/canvas/layer/cache.rs) | 76 | ||||
| -rw-r--r-- | wgpu/src/widget/canvas/drawable.rs | 9 | ||||
| -rw-r--r-- | wgpu/src/widget/canvas/geometry.rs | 15 | ||||
| -rw-r--r-- | wgpu/src/widget/canvas/layer.rs | 25 | ||||
| -rw-r--r-- | wgpu/src/widget/canvas/program.rs | 16 | ||||
| -rw-r--r-- | wgpu/src/widget/canvas/state.rs | 20 | 
7 files changed, 100 insertions, 107 deletions
| diff --git a/wgpu/src/widget/canvas.rs b/wgpu/src/widget/canvas.rs index 326bc7d5..2b485e18 100644 --- a/wgpu/src/widget/canvas.rs +++ b/wgpu/src/widget/canvas.rs @@ -14,24 +14,26 @@ use iced_native::{  };  use std::hash::Hash; -pub mod layer;  pub mod path; +mod cache;  mod drawable;  mod event;  mod fill;  mod frame; -mod program; +mod geometry; +mod state;  mod stroke;  mod text; +pub use cache::Cache;  pub use drawable::Drawable;  pub use event::Event;  pub use fill::Fill;  pub use frame::Frame; -pub use layer::Layer; +pub use geometry::Geometry;  pub use path::Path; -pub use program::Program; +pub use state::State;  pub use stroke::{LineCap, LineJoin, Stroke};  pub use text::Text; @@ -65,7 +67,7 @@ pub use text::Text;  /// #     pub use iced_wgpu::canvas;  /// #     pub use iced_native::Color;  /// # } -/// use iced::canvas::{self, layer, Canvas, Drawable, Fill, Frame, Path}; +/// use iced::canvas::{self, Cache, Canvas, Drawable, Fill, Frame, Path};  /// use iced::Color;  ///  /// // First, we define the data we need for drawing @@ -86,31 +88,29 @@ pub use text::Text;  /// }  ///  /// // We can use a `Cache` to avoid unnecessary re-tessellation -/// let mut cache: layer::Cache<Circle> = layer::Cache::new(); +/// let cache = Cache::new();  ///  /// // Finally, we simply use our `Cache` to create the `Canvas`! -/// let canvas = Canvas::new(&mut cache, &Circle { radius: 50.0 }); +/// let canvas = Canvas::new(cache.with(Circle { radius: 50.0 }));  /// ```  #[derive(Debug)] -pub struct Canvas<'a, P: Program> { +pub struct Canvas<S: State> {      width: Length,      height: Length, -    program: &'a mut P, -    input: &'a P::Input, +    state: S,  } -impl<'a, P: Program> Canvas<'a, P> { +impl<S: State> Canvas<S> {      const DEFAULT_SIZE: u16 = 100;      /// Creates a new [`Canvas`] with no layers.      ///      /// [`Canvas`]: struct.Canvas.html -    pub fn new(program: &'a mut P, input: &'a P::Input) -> Self { +    pub fn new(state: S) -> Self {          Canvas {              width: Length::Units(Self::DEFAULT_SIZE),              height: Length::Units(Self::DEFAULT_SIZE), -            program, -            input, +            state,          }      } @@ -131,7 +131,7 @@ impl<'a, P: Program> Canvas<'a, P> {      }  } -impl<'a, Message, P: Program> Widget<Message, Renderer> for Canvas<'a, P> { +impl<Message, S: State> Widget<Message, Renderer> for Canvas<S> {      fn width(&self) -> Length {          self.width      } @@ -178,7 +178,7 @@ impl<'a, Message, P: Program> Widget<Message, Renderer> for Canvas<'a, P> {          };          if let Some(canvas_event) = canvas_event { -            self.program.update(canvas_event, bounds.size(), self.input) +            self.state.update(canvas_event, bounds.size())          }      } @@ -196,12 +196,12 @@ impl<'a, Message, P: Program> Widget<Message, Renderer> for Canvas<'a, P> {          (              Primitive::Group {                  primitives: self -                    .program -                    .layers(self.input) -                    .iter() -                    .map(|layer| Primitive::Cached { +                    .state +                    .draw(size) +                    .into_iter() +                    .map(|geometry| Primitive::Cached {                          origin, -                        cache: layer.draw(size), +                        cache: geometry.into_primitive(),                      })                      .collect(),              }, @@ -218,12 +218,12 @@ impl<'a, Message, P: Program> Widget<Message, Renderer> for Canvas<'a, P> {      }  } -impl<'a, Message, P: Program> From<Canvas<'a, P>> +impl<'a, Message, S: State + 'a> From<Canvas<S>>      for Element<'a, Message, Renderer>  where      Message: 'static,  { -    fn from(canvas: Canvas<'a, P>) -> Element<'a, Message, Renderer> { +    fn from(canvas: Canvas<S>) -> Element<'a, Message, Renderer> {          Element::new(canvas)      }  } diff --git a/wgpu/src/widget/canvas/layer/cache.rs b/wgpu/src/widget/canvas/cache.rs index 4ecebb48..c88239af 100644 --- a/wgpu/src/widget/canvas/layer/cache.rs +++ b/wgpu/src/widget/canvas/cache.rs @@ -1,10 +1,10 @@  use crate::{ -    canvas::{Drawable, Frame, Layer}, +    canvas::{Drawable, Frame, Geometry},      Primitive,  };  use iced_native::Size; -use std::{borrow::Borrow, cell::RefCell, marker::PhantomData, sync::Arc}; +use std::{cell::RefCell, sync::Arc};  enum State {      Empty, @@ -48,61 +48,51 @@ impl Cache {          *self.state.borrow_mut() = State::Empty;      } -    /// Binds the [`Cache`] with some data, producing a [`Layer`] that can be -    /// added to a [`Canvas`]. -    /// -    /// [`Cache`]: struct.Cache.html -    /// [`Layer`]: ../trait.Layer.html -    /// [`Canvas`]: ../../struct.Canvas.html -    pub fn with<'a, T>( -        &'a self, -        input: impl Borrow<T> + std::fmt::Debug + 'a, -    ) -> impl Layer + 'a +    pub fn draw<T>(&self, new_bounds: Size, input: T) -> Geometry      where -        T: Drawable + std::fmt::Debug + 'a, +        T: Drawable + std::fmt::Debug,      { -        Bind { -            cache: self, -            input: input, -            drawable: PhantomData, -        } -    } -} - -#[derive(Debug)] -struct Bind<'a, T: Drawable, I: Borrow<T> + 'a> { -    cache: &'a Cache, -    input: I, -    drawable: PhantomData<T>, -} - -impl<'a, T, I> Layer for Bind<'a, T, I> -where -    T: Drawable + std::fmt::Debug, -    I: Borrow<T> + std::fmt::Debug + 'a, -{ -    fn draw(&self, current_bounds: Size) -> Arc<Primitive> {          use std::ops::Deref; -        if let State::Filled { bounds, primitive } = -            self.cache.state.borrow().deref() +        if let State::Filled { bounds, primitive } = self.state.borrow().deref()          { -            if *bounds == current_bounds { -                return primitive.clone(); +            if *bounds == new_bounds { +                return Geometry::from_primitive(primitive.clone());              }          } -        let mut frame = Frame::new(current_bounds.width, current_bounds.height); -        self.input.borrow().draw(&mut frame); +        let mut frame = Frame::new(new_bounds.width, new_bounds.height); +        input.draw(&mut frame);          let primitive = Arc::new(frame.into_primitive()); -        *self.cache.state.borrow_mut() = State::Filled { -            bounds: current_bounds, +        *self.state.borrow_mut() = State::Filled { +            bounds: new_bounds,              primitive: primitive.clone(),          }; -        primitive +        Geometry::from_primitive(primitive) +    } + +    pub fn with<'a, T>(&'a self, input: T) -> impl crate::canvas::State + 'a +    where +        T: Drawable + std::fmt::Debug + 'a, +    { +        Bind { cache: self, input } +    } +} + +struct Bind<'a, T> { +    cache: &'a Cache, +    input: T, +} + +impl<'a, T> crate::canvas::State for Bind<'a, T> +where +    T: Drawable + std::fmt::Debug + 'a, +{ +    fn draw(&self, bounds: Size) -> Vec<Geometry> { +        vec![self.cache.draw(bounds, &self.input)]      }  } diff --git a/wgpu/src/widget/canvas/drawable.rs b/wgpu/src/widget/canvas/drawable.rs index 48ba6b4c..32258b71 100644 --- a/wgpu/src/widget/canvas/drawable.rs +++ b/wgpu/src/widget/canvas/drawable.rs @@ -16,3 +16,12 @@ impl<'a> Drawable for dyn Fn(&mut Frame) + 'a {          self(frame)      }  } + +impl<T> Drawable for &T +where +    T: Drawable, +{ +    fn draw(&self, frame: &mut Frame) { +        T::draw(self, frame) +    } +} diff --git a/wgpu/src/widget/canvas/geometry.rs b/wgpu/src/widget/canvas/geometry.rs new file mode 100644 index 00000000..db7b4054 --- /dev/null +++ b/wgpu/src/widget/canvas/geometry.rs @@ -0,0 +1,15 @@ +use crate::Primitive; +use std::sync::Arc; + +#[derive(Debug)] +pub struct Geometry(Arc<Primitive>); + +impl Geometry { +    pub(crate) fn from_primitive(primitive: Arc<Primitive>) -> Self { +        Self(primitive) +    } + +    pub(crate) fn into_primitive(self) -> Arc<Primitive> { +        self.0 +    } +} diff --git a/wgpu/src/widget/canvas/layer.rs b/wgpu/src/widget/canvas/layer.rs deleted file mode 100644 index a46b7fb1..00000000 --- a/wgpu/src/widget/canvas/layer.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! Produce, store, and reuse geometry. -mod cache; - -pub use cache::Cache; - -use crate::Primitive; -use iced_native::Size; - -use std::sync::Arc; - -/// A layer that can be presented at a [`Canvas`]. -/// -/// [`Canvas`]: ../struct.Canvas.html -pub trait Layer: std::fmt::Debug { -    /// Draws the [`Layer`] in the given bounds and produces a [`Primitive`] as -    /// a result. -    /// -    /// The [`Layer`] may choose to store the produced [`Primitive`] locally and -    /// only recompute it when the bounds change, its contents change, or is -    /// otherwise explicitly cleared by other means. -    /// -    /// [`Layer`]: trait.Layer.html -    /// [`Primitive`]: ../../../enum.Primitive.html -    fn draw(&self, bounds: Size) -> Arc<Primitive>; -} diff --git a/wgpu/src/widget/canvas/program.rs b/wgpu/src/widget/canvas/program.rs deleted file mode 100644 index c65a078b..00000000 --- a/wgpu/src/widget/canvas/program.rs +++ /dev/null @@ -1,16 +0,0 @@ -use crate::canvas::{Event, Layer, Size}; - -pub trait Program { -    type Input; - -    fn layers<'a>(&'a self, input: &'a Self::Input) -        -> Vec<Box<dyn Layer + 'a>>; - -    fn update<'a>( -        &'a mut self, -        _event: Event, -        _bounds: Size, -        _input: &'a Self::Input, -    ) { -    } -} diff --git a/wgpu/src/widget/canvas/state.rs b/wgpu/src/widget/canvas/state.rs new file mode 100644 index 00000000..8388f94d --- /dev/null +++ b/wgpu/src/widget/canvas/state.rs @@ -0,0 +1,20 @@ +use crate::canvas::{Event, Geometry, Size}; + +pub trait State { +    fn update(&mut self, _event: Event, _bounds: Size) {} + +    fn draw(&self, bounds: Size) -> Vec<Geometry>; +} + +impl<T> State for &mut T +where +    T: State, +{ +    fn update(&mut self, event: Event, bounds: Size) { +        T::update(self, event, bounds); +    } + +    fn draw(&self, bounds: Size) -> Vec<Geometry> { +        T::draw(self, bounds) +    } +} | 
