Skip to main content

duku/resources/
mod.rs

1// Oliver Berzs
2// https://github.com/oberzs/duku
3
4mod builtins;
5mod handle;
6
7use crate::device::Device;
8use crate::font::Font;
9use crate::image::Canvas;
10use crate::image::Cubemap;
11use crate::image::Texture;
12use crate::mesh::Mesh;
13use crate::mesh::Model;
14use crate::pipeline::Material;
15use crate::pipeline::Shader;
16use crate::pipeline::Uniforms;
17
18pub(crate) use builtins::create_cube;
19pub(crate) use builtins::create_ico_sphere;
20pub(crate) use builtins::create_uv_sphere;
21pub(crate) use builtins::Builtins;
22pub use handle::Handle;
23pub use handle::ReadGuard;
24pub use handle::WriteGuard;
25
26#[derive(Default)]
27pub(crate) struct Resources {
28    shaders: Vec<Handle<Shader>>,
29    fonts: Vec<Handle<Font>>,
30    textures: Vec<Handle<Texture>>,
31    cubemaps: Vec<Handle<Cubemap>>,
32    canvases: Vec<Handle<Canvas>>,
33    materials: Vec<Handle<Material>>,
34    meshes: Vec<Handle<Mesh>>,
35    models: Vec<Handle<Model>>,
36}
37
38impl Resources {
39    pub(crate) fn add_shader(&mut self, value: Shader) -> Handle<Shader> {
40        add(&mut self.shaders, value)
41    }
42
43    pub(crate) fn add_font(&mut self, value: Font) -> Handle<Font> {
44        add(&mut self.fonts, value)
45    }
46
47    pub(crate) fn add_texture(&mut self, value: Texture) -> Handle<Texture> {
48        add(&mut self.textures, value)
49    }
50
51    pub(crate) fn add_cubemap(&mut self, value: Cubemap) -> Handle<Cubemap> {
52        add(&mut self.cubemaps, value)
53    }
54
55    pub(crate) fn add_canvas(&mut self, value: Canvas) -> Handle<Canvas> {
56        add(&mut self.canvases, value)
57    }
58
59    pub(crate) fn add_material(&mut self, value: Material) -> Handle<Material> {
60        add(&mut self.materials, value)
61    }
62
63    pub(crate) fn add_mesh(&mut self, value: Mesh) -> Handle<Mesh> {
64        add(&mut self.meshes, value)
65    }
66
67    pub(crate) fn add_model(&mut self, value: Model) -> Handle<Model> {
68        add(&mut self.models, value)
69    }
70
71    pub(crate) fn clear_unused(&mut self, device: &Device, uniforms: &mut Uniforms) {
72        clear_unused(&mut self.models, |_| {});
73        clear_unused(&mut self.fonts, |v| v.destroy(device, uniforms));
74        clear_unused(&mut self.shaders, |v| v.destroy(device));
75        clear_unused(&mut self.textures, |v| v.destroy(device, uniforms));
76        clear_unused(&mut self.cubemaps, |v| v.destroy(device, uniforms));
77        clear_unused(&mut self.canvases, |v| v.destroy(device, uniforms));
78        clear_unused(&mut self.materials, |v| v.destroy(device));
79        clear_unused(&mut self.meshes, |v| v.destroy(device));
80    }
81
82    pub(crate) fn clear(&mut self, device: &Device, uniforms: &mut Uniforms) {
83        clear(&mut self.models, |_| {});
84        clear(&mut self.fonts, |v| v.destroy(device, uniforms));
85        clear(&mut self.shaders, |v| v.destroy(device));
86        clear(&mut self.textures, |v| v.destroy(device, uniforms));
87        clear(&mut self.cubemaps, |v| v.destroy(device, uniforms));
88        clear(&mut self.canvases, |v| v.destroy(device, uniforms));
89        clear(&mut self.materials, |v| v.destroy(device));
90        clear(&mut self.meshes, |v| v.destroy(device));
91    }
92
93    pub(crate) fn update_if_needed(&mut self, device: &Device, uniforms: &mut Uniforms) {
94        // update meshes
95        for h in &mut self.meshes {
96            if h.mutated() {
97                h.get_mut().update(device);
98            }
99        }
100
101        // update materials
102        for h in &mut self.materials {
103            if h.mutated() {
104                h.get_mut().update();
105            }
106        }
107
108        // update canvases
109        for h in &mut self.canvases {
110            if h.mutated() {
111                h.get_mut().update(device, uniforms);
112            }
113        }
114
115        // update textures
116        for h in &mut self.textures {
117            if h.mutated() {
118                h.get_mut().update(device);
119            }
120        }
121    }
122}
123
124fn add<T>(handles: &mut Vec<Handle<T>>, value: T) -> Handle<T> {
125    let handle = Handle::new(value);
126    handles.push(handle.clone());
127    handle
128}
129
130fn clear_unused<T>(handles: &mut Vec<Handle<T>>, mut clear_fn: impl FnMut(&T)) {
131    handles.retain(|h| {
132        if h.count() == 0 {
133            clear_fn(&h.read());
134            false
135        } else {
136            true
137        }
138    });
139}
140
141fn clear<T>(handles: &mut Vec<Handle<T>>, mut clear_fn: impl FnMut(&T)) {
142    for h in handles.iter() {
143        clear_fn(&h.read());
144    }
145    handles.clear();
146}