1mod 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 for h in &mut self.meshes {
96 if h.mutated() {
97 h.get_mut().update(device);
98 }
99 }
100
101 for h in &mut self.materials {
103 if h.mutated() {
104 h.get_mut().update();
105 }
106 }
107
108 for h in &mut self.canvases {
110 if h.mutated() {
111 h.get_mut().update(device, uniforms);
112 }
113 }
114
115 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}