From df90c478e28892537efc0009d468a521d4d7fee5 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 13 Feb 2020 03:45:07 +0100 Subject: Move `layer::Cached` to its own module --- wgpu/src/widget/canvas/layer/cached.rs | 82 ++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 wgpu/src/widget/canvas/layer/cached.rs (limited to 'wgpu/src/widget/canvas/layer') diff --git a/wgpu/src/widget/canvas/layer/cached.rs b/wgpu/src/widget/canvas/layer/cached.rs new file mode 100644 index 00000000..c6741372 --- /dev/null +++ b/wgpu/src/widget/canvas/layer/cached.rs @@ -0,0 +1,82 @@ +use crate::{ + canvas::{layer::Drawable, Frame, Layer}, + triangle, +}; + +use iced_native::Size; +use std::cell::RefCell; +use std::marker::PhantomData; +use std::sync::Arc; + +#[derive(Debug)] +pub struct Cached { + input: PhantomData, + cache: RefCell, +} + +#[derive(Debug)] +enum Cache { + Empty, + Filled { + mesh: Arc, + bounds: Size, + }, +} + +impl Cached +where + T: Drawable + std::fmt::Debug, +{ + pub fn new() -> Self { + Cached { + input: PhantomData, + cache: RefCell::new(Cache::Empty), + } + } + + pub fn clear(&mut self) { + *self.cache.borrow_mut() = Cache::Empty; + } + + pub fn with<'a>(&'a self, input: &'a T) -> impl Layer + 'a { + Bind { + layer: self, + input: input, + } + } +} + +#[derive(Debug)] +struct Bind<'a, T: Drawable> { + layer: &'a Cached, + input: &'a T, +} + +impl<'a, T> Layer for Bind<'a, T> +where + T: Drawable + std::fmt::Debug, +{ + fn draw(&self, current_bounds: Size) -> Arc { + use std::ops::Deref; + + if let Cache::Filled { mesh, bounds } = + self.layer.cache.borrow().deref() + { + if *bounds == current_bounds { + return mesh.clone(); + } + } + + let mut frame = Frame::new(current_bounds.width, current_bounds.height); + self.input.draw(&mut frame); + + let mesh = Arc::new(frame.into_mesh()); + + *self.layer.cache.borrow_mut() = Cache::Filled { + mesh: mesh.clone(), + bounds: current_bounds, + }; + + mesh + } +} -- cgit From 9c067562fa765cfc49d09cd9b12fbba96d5619fa Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 18 Feb 2020 08:48:54 +0100 Subject: Write documentation for new `canvas` module --- wgpu/src/widget/canvas/layer/cache.rs | 101 +++++++++++++++++++++++++++++++++ wgpu/src/widget/canvas/layer/cached.rs | 82 -------------------------- 2 files changed, 101 insertions(+), 82 deletions(-) create mode 100644 wgpu/src/widget/canvas/layer/cache.rs delete mode 100644 wgpu/src/widget/canvas/layer/cached.rs (limited to 'wgpu/src/widget/canvas/layer') diff --git a/wgpu/src/widget/canvas/layer/cache.rs b/wgpu/src/widget/canvas/layer/cache.rs new file mode 100644 index 00000000..3071cce0 --- /dev/null +++ b/wgpu/src/widget/canvas/layer/cache.rs @@ -0,0 +1,101 @@ +use crate::{ + canvas::{Drawable, Frame, Layer}, + triangle, +}; + +use iced_native::Size; +use std::cell::RefCell; +use std::marker::PhantomData; +use std::sync::Arc; + +/// A simple cache that stores generated geometry to avoid recomputation. +/// +/// A [`Cache`] will not redraw its geometry unless the dimensions of its layer +/// change or it is explicitly cleared. +/// +/// [`Layer`]: ../trait.Layer.html +/// [`Cached`]: struct.Cached.html +#[derive(Debug)] +pub struct Cache { + input: PhantomData, + state: RefCell, +} + +#[derive(Debug)] +enum State { + Empty, + Filled { + mesh: Arc, + bounds: Size, + }, +} + +impl Cache +where + T: Drawable + std::fmt::Debug, +{ + /// Creates a new empty [`Cache`]. + /// + /// [`Cache`]: struct.Cache.html + pub fn new() -> Self { + Cache { + input: PhantomData, + state: RefCell::new(State::Empty), + } + } + + /// Clears the cache, forcing a redraw the next time it is used. + /// + /// [`Cached`]: struct.Cached.html + pub fn clear(&mut self) { + *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>(&'a self, input: &'a T) -> impl Layer + 'a { + Bind { + cache: self, + input: input, + } + } +} + +#[derive(Debug)] +struct Bind<'a, T: Drawable> { + cache: &'a Cache, + input: &'a T, +} + +impl<'a, T> Layer for Bind<'a, T> +where + T: Drawable + std::fmt::Debug, +{ + fn draw(&self, current_bounds: Size) -> Arc { + use std::ops::Deref; + + if let State::Filled { mesh, bounds } = + self.cache.state.borrow().deref() + { + if *bounds == current_bounds { + return mesh.clone(); + } + } + + let mut frame = Frame::new(current_bounds.width, current_bounds.height); + self.input.draw(&mut frame); + + let mesh = Arc::new(frame.into_mesh()); + + *self.cache.state.borrow_mut() = State::Filled { + mesh: mesh.clone(), + bounds: current_bounds, + }; + + mesh + } +} diff --git a/wgpu/src/widget/canvas/layer/cached.rs b/wgpu/src/widget/canvas/layer/cached.rs deleted file mode 100644 index c6741372..00000000 --- a/wgpu/src/widget/canvas/layer/cached.rs +++ /dev/null @@ -1,82 +0,0 @@ -use crate::{ - canvas::{layer::Drawable, Frame, Layer}, - triangle, -}; - -use iced_native::Size; -use std::cell::RefCell; -use std::marker::PhantomData; -use std::sync::Arc; - -#[derive(Debug)] -pub struct Cached { - input: PhantomData, - cache: RefCell, -} - -#[derive(Debug)] -enum Cache { - Empty, - Filled { - mesh: Arc, - bounds: Size, - }, -} - -impl Cached -where - T: Drawable + std::fmt::Debug, -{ - pub fn new() -> Self { - Cached { - input: PhantomData, - cache: RefCell::new(Cache::Empty), - } - } - - pub fn clear(&mut self) { - *self.cache.borrow_mut() = Cache::Empty; - } - - pub fn with<'a>(&'a self, input: &'a T) -> impl Layer + 'a { - Bind { - layer: self, - input: input, - } - } -} - -#[derive(Debug)] -struct Bind<'a, T: Drawable> { - layer: &'a Cached, - input: &'a T, -} - -impl<'a, T> Layer for Bind<'a, T> -where - T: Drawable + std::fmt::Debug, -{ - fn draw(&self, current_bounds: Size) -> Arc { - use std::ops::Deref; - - if let Cache::Filled { mesh, bounds } = - self.layer.cache.borrow().deref() - { - if *bounds == current_bounds { - return mesh.clone(); - } - } - - let mut frame = Frame::new(current_bounds.width, current_bounds.height); - self.input.draw(&mut frame); - - let mesh = Arc::new(frame.into_mesh()); - - *self.layer.cache.borrow_mut() = Cache::Filled { - mesh: mesh.clone(), - bounds: current_bounds, - }; - - mesh - } -} -- cgit