Remove Layer trait and simplify Canvas
This commit is contained in:
parent
bb424e54c5
commit
592cc68506
9 changed files with 181 additions and 174 deletions
|
|
@ -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)]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15
wgpu/src/widget/canvas/geometry.rs
Normal file
15
wgpu/src/widget/canvas/geometry.rs
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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>;
|
||||
}
|
||||
|
|
@ -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,
|
||||
) {
|
||||
}
|
||||
}
|
||||
20
wgpu/src/widget/canvas/state.rs
Normal file
20
wgpu/src/widget/canvas/state.rs
Normal file
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue