diff options
| author | 2024-04-08 15:04:35 +0200 | |
|---|---|---|
| committer | 2024-04-08 15:04:35 +0200 | |
| commit | d922b478156488a7bc03c6e791e05c040d702634 (patch) | |
| tree | 767e9b9fa2c6527a0b3e3b3dd1c21b29cd533ee8 /wgpu/src/primitive.rs | |
| parent | 6ea763c2a79292e5b10be2240b4b57b920223616 (diff) | |
| download | iced-d922b478156488a7bc03c6e791e05c040d702634.tar.gz iced-d922b478156488a7bc03c6e791e05c040d702634.tar.bz2 iced-d922b478156488a7bc03c6e791e05c040d702634.zip | |
Reintroduce support for custom primitives in `iced_wgpu`
Diffstat (limited to 'wgpu/src/primitive.rs')
| -rw-r--r-- | wgpu/src/primitive.rs | 103 | 
1 files changed, 89 insertions, 14 deletions
| diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs index 8e311d2b..4ba1ed9a 100644 --- a/wgpu/src/primitive.rs +++ b/wgpu/src/primitive.rs @@ -1,20 +1,95 @@ -//! Draw using different graphical primitives. -pub mod pipeline; +//! Draw custom primitives. +use crate::core::{self, Rectangle}; +use crate::graphics::Viewport; -pub use pipeline::Pipeline; +use rustc_hash::FxHashMap; +use std::any::{Any, TypeId}; +use std::fmt::Debug; -use crate::graphics::Mesh; +/// A batch of primitives. +pub type Batch = Vec<Instance>; -use std::fmt::Debug; +/// A set of methods which allows a [`Primitive`] to be rendered. +pub trait Primitive: Debug + Send + Sync + 'static { +    /// Processes the [`Primitive`], allowing for GPU buffer allocation. +    fn prepare( +        &self, +        device: &wgpu::Device, +        queue: &wgpu::Queue, +        format: wgpu::TextureFormat, +        storage: &mut Storage, +        bounds: &Rectangle, +        viewport: &Viewport, +    ); + +    /// Renders the [`Primitive`]. +    fn render( +        &self, +        encoder: &mut wgpu::CommandEncoder, +        storage: &Storage, +        target: &wgpu::TextureView, +        clip_bounds: &Rectangle<u32>, +    ); +} + +#[derive(Debug)] +/// An instance of a specific [`Primitive`]. +pub struct Instance { +    /// The bounds of the [`Instance`]. +    pub bounds: Rectangle, + +    /// The [`Primitive`] to render. +    pub primitive: Box<dyn Primitive>, +} + +impl Instance { +    /// Creates a new [`Pipeline`] with the given [`Primitive`]. +    pub fn new(bounds: Rectangle, primitive: impl Primitive) -> Self { +        Instance { +            bounds, +            primitive: Box::new(primitive), +        } +    } +} + +/// A renderer than can draw custom primitives. +pub trait Renderer: core::Renderer { +    /// Draws a custom primitive. +    fn draw_primitive(&mut self, bounds: Rectangle, primitive: impl Primitive); +} + +/// Stores custom, user-provided types. +#[derive(Default, Debug)] +pub struct Storage { +    pipelines: FxHashMap<TypeId, Box<dyn Any + Send>>, +} + +impl Storage { +    /// Returns `true` if `Storage` contains a type `T`. +    pub fn has<T: 'static>(&self) -> bool { +        self.pipelines.get(&TypeId::of::<T>()).is_some() +    } + +    /// Inserts the data `T` in to [`Storage`]. +    pub fn store<T: 'static + Send>(&mut self, data: T) { +        let _ = self.pipelines.insert(TypeId::of::<T>(), Box::new(data)); +    } -/// The graphical primitives supported by `iced_wgpu`. -pub type Primitive = crate::graphics::Primitive<Custom>; +    /// Returns a reference to the data with type `T` if it exists in [`Storage`]. +    pub fn get<T: 'static>(&self) -> Option<&T> { +        self.pipelines.get(&TypeId::of::<T>()).map(|pipeline| { +            pipeline +                .downcast_ref::<T>() +                .expect("Pipeline with this type does not exist in Storage.") +        }) +    } -/// The custom primitives supported by `iced_wgpu`. -#[derive(Debug, Clone, PartialEq)] -pub enum Custom { -    /// A mesh primitive. -    Mesh(Mesh), -    /// A custom pipeline primitive. -    Pipeline(Pipeline), +    /// Returns a mutable reference to the data with type `T` if it exists in [`Storage`]. +    pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T> { +        self.pipelines.get_mut(&TypeId::of::<T>()).map(|pipeline| { +            pipeline +                .downcast_mut::<T>() +                .expect("Pipeline with this type does not exist in Storage.") +        }) +    }  } | 
