use bevy_utils::Uuid; use std::{ops::Deref, sync::Arc}; #[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)] pub struct TextureId(Uuid); #[derive(Clone, Debug)] pub struct Texture { id: TextureId, value: Arc, } impl Texture { #[inline] pub fn id(&self) -> TextureId { self.id } pub fn create_view(&self, desc: &wgpu::TextureViewDescriptor) -> TextureView { TextureView::from(self.value.create_view(desc)) } } impl From for Texture { fn from(value: wgpu::Texture) -> Self { Texture { id: TextureId(Uuid::new_v4()), value: Arc::new(value), } } } impl Deref for Texture { type Target = wgpu::Texture; #[inline] fn deref(&self) -> &Self::Target { &self.value } } #[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)] pub struct TextureViewId(Uuid); #[derive(Clone, Debug)] pub enum TextureViewValue { TextureView(Arc), SurfaceTexture { // NOTE: The order of these fields is important because the view must be dropped before the // frame is dropped view: Arc, texture: Arc, }, } #[derive(Clone, Debug)] pub struct TextureView { id: TextureViewId, value: TextureViewValue, } impl TextureView { #[inline] pub fn id(&self) -> TextureViewId { self.id } #[inline] pub fn take_surface_texture(self) -> Option { match self.value { TextureViewValue::TextureView(_) => None, TextureViewValue::SurfaceTexture { texture, .. } => Arc::try_unwrap(texture).ok(), } } } impl From for TextureView { fn from(value: wgpu::TextureView) -> Self { TextureView { id: TextureViewId(Uuid::new_v4()), value: TextureViewValue::TextureView(Arc::new(value)), } } } impl From for TextureView { fn from(value: wgpu::SurfaceTexture) -> Self { let texture = Arc::new(value); let view = Arc::new(texture.texture.create_view(&Default::default())); TextureView { id: TextureViewId(Uuid::new_v4()), value: TextureViewValue::SurfaceTexture { texture, view }, } } } impl Deref for TextureView { type Target = wgpu::TextureView; #[inline] fn deref(&self) -> &Self::Target { match &self.value { TextureViewValue::TextureView(value) => value, TextureViewValue::SurfaceTexture { view, .. } => view, } } } #[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)] pub struct SamplerId(Uuid); #[derive(Clone, Debug)] pub struct Sampler { id: SamplerId, value: Arc, } impl Sampler { #[inline] pub fn id(&self) -> SamplerId { self.id } } impl From for Sampler { fn from(value: wgpu::Sampler) -> Self { Sampler { id: SamplerId(Uuid::new_v4()), value: Arc::new(value), } } } impl Deref for Sampler { type Target = wgpu::Sampler; #[inline] fn deref(&self) -> &Self::Target { &self.value } }