mireforge_game_assets/
lib.rs1use int_math::UVec2;
6
7use limnus_asset_id::{AssetName, Id};
8use limnus_asset_registry::AssetRegistry;
9use limnus_audio_mixer::{StereoSample, StereoSampleRef};
10use limnus_resource::ResourceStorage;
11use mireforge_font::{Font, GlyphDraw};
12use mireforge_render_wgpu::{
13 FixedAtlas, FontAndMaterial, Material, MaterialBase, MaterialKind, MaterialRef,
14 NineSliceAndMaterial, Slices, Texture, TextureRef,
15};
16use monotonic_time_rs::Millis;
17use std::fmt::Debug;
18use std::sync::Arc;
19
20pub trait Assets {
21 #[must_use]
22 fn now(&self) -> Millis;
23
24 #[must_use]
25 fn texture_png(&mut self, name: impl Into<AssetName>) -> TextureRef;
26
27 #[must_use]
28 fn material_png(&mut self, name: impl Into<AssetName>) -> MaterialRef;
29
30 #[must_use]
31 fn material_alpha_mask(
32 &mut self,
33 name: impl Into<AssetName>,
34 mask: impl Into<AssetName>,
35 ) -> MaterialRef;
36
37 #[must_use]
38 fn light_material_png(&mut self, name: impl Into<AssetName>) -> MaterialRef;
39
40 #[must_use]
41 fn frame_fixed_grid_material_png(
42 &mut self,
43 name: impl Into<AssetName>,
44 grid_size: UVec2,
45 texture_size: UVec2,
46 ) -> FixedAtlas;
47
48 #[must_use]
49 fn nine_slice_material_png(
50 &mut self,
51 name: impl Into<AssetName>,
52 slices: Slices,
53 ) -> NineSliceAndMaterial;
54
55 #[must_use]
56 fn bm_font(&mut self, name: impl Into<AssetName>) -> FontAndMaterial;
57
58 #[must_use]
59 fn bm_font_txt(&mut self, name: impl Into<AssetName>) -> FontAndMaterial;
60
61 #[must_use]
62 fn text_glyphs(&self, text: &str, font_and_mat: &FontAndMaterial) -> Option<GlyphDraw>;
63
64 #[must_use]
65 fn font(&self, font_ref: &Id<Font>) -> Option<&Font>;
66 #[must_use]
67 fn audio_sample_wav(&mut self, name: impl Into<AssetName>) -> StereoSampleRef;
68}
69
70pub struct GameAssets<'a> {
71 now: Millis,
72 resource_storage: &'a mut ResourceStorage,
73}
74
75impl Debug for GameAssets<'_> {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 write!(f, "assets")
78 }
79}
80
81impl<'a> GameAssets<'a> {
82 pub const fn new(resource_storage: &'a mut ResourceStorage, now: Millis) -> Self {
83 Self {
84 now,
85 resource_storage,
86 }
87 }
88}
89
90impl Assets for GameAssets<'_> {
91 fn now(&self) -> Millis {
92 self.now
93 }
94
95 fn texture_png(&mut self, name: impl Into<AssetName>) -> TextureRef {
96 let asset_loader = self
97 .resource_storage
98 .get_mut::<AssetRegistry>()
99 .expect("should exist registry");
100
101 let texture_id = asset_loader.load::<Texture>(name.into().with_extension("png"));
102
103 TextureRef::from(texture_id)
104 }
105
106 fn material_png(&mut self, name: impl Into<AssetName>) -> MaterialRef {
107 let asset_loader = self
108 .resource_storage
109 .get_mut::<AssetRegistry>()
110 .expect("should exist registry");
111
112 let texture_ref = asset_loader.load::<Texture>(name.into().with_extension("png"));
113
114 let material = Material {
115 base: MaterialBase {
116 },
118 kind: MaterialKind::NormalSprite {
119 primary_texture: texture_ref,
120 },
121 };
122
123 Arc::new(material)
124 }
125
126 fn material_alpha_mask(
127 &mut self,
128 name: impl Into<AssetName>,
129 mask: impl Into<AssetName>,
130 ) -> MaterialRef {
131 let asset_loader = self
132 .resource_storage
133 .get_mut::<AssetRegistry>()
134 .expect("should exist registry");
135 let diffuse_texture_id = asset_loader.load::<Texture>(name.into().with_extension("png"));
136 let alpha_mask_texture_id = asset_loader.load::<Texture>(mask.into().with_extension("png"));
137 let material = Material {
138 base: MaterialBase {},
139 kind: MaterialKind::AlphaMasker {
140 primary_texture: diffuse_texture_id,
141 alpha_texture: alpha_mask_texture_id,
142 },
143 };
144
145 Arc::new(material)
146 }
147
148 fn light_material_png(&mut self, name: impl Into<AssetName>) -> MaterialRef {
149 let asset_loader = self
150 .resource_storage
151 .get_mut::<AssetRegistry>()
152 .expect("should exist registry");
153
154 let texture_ref = asset_loader.load::<Texture>(name.into().with_extension("png"));
155
156 let material = Material {
157 base: MaterialBase {
158 },
160 kind: MaterialKind::LightAdd {
161 primary_texture: texture_ref,
162 },
163 };
164
165 Arc::new(material)
166 }
167
168 fn frame_fixed_grid_material_png(
169 &mut self,
170 name: impl Into<AssetName>,
171 grid_size: UVec2,
172 texture_size: UVec2,
173 ) -> FixedAtlas {
174 let material_ref = self.material_png(name);
175
176 FixedAtlas::new(grid_size, texture_size, material_ref)
177 }
178
179 fn nine_slice_material_png(
180 &mut self,
181 name: impl Into<AssetName>,
182 slices: Slices,
183 ) -> NineSliceAndMaterial {
184 let material_ref = self.material_png(name);
185
186 NineSliceAndMaterial {
187 slices,
188 material_ref,
189 }
190 }
191
192 fn bm_font(&mut self, name: impl Into<AssetName>) -> FontAndMaterial {
193 let asset_name = name.into();
194 let asset_loader = self
195 .resource_storage
196 .get_mut::<AssetRegistry>()
197 .expect("should exist registry");
198 let font_ref = asset_loader.load::<Font>(asset_name.clone().with_extension("fnt"));
199 let texture_id = asset_loader.load::<Texture>(asset_name.clone().with_extension("png"));
200
201 let material = Material {
202 base: MaterialBase {
203 },
205 kind: MaterialKind::NormalSprite {
206 primary_texture: texture_id,
207 },
208 };
209
210 FontAndMaterial {
211 font_ref,
212 material_ref: Arc::new(material),
213 }
214 }
215
216 fn bm_font_txt(&mut self, name: impl Into<AssetName>) -> FontAndMaterial {
217 let asset_name = name.into();
218 let asset_loader = self
219 .resource_storage
220 .get_mut::<AssetRegistry>()
221 .expect("should exist registry");
222 let font_ref = asset_loader.load::<Font>(asset_name.clone().with_extension("txt.fnt"));
223 let texture_id = asset_loader.load::<Texture>(asset_name.clone().with_extension("png"));
224
225 let material = Material {
226 base: MaterialBase {
227 },
229 kind: MaterialKind::NormalSprite {
230 primary_texture: texture_id,
231 },
232 };
233
234 FontAndMaterial {
235 font_ref,
236 material_ref: Arc::new(material),
237 }
238 }
239
240 fn text_glyphs(&self, text: &str, font_and_mat: &FontAndMaterial) -> Option<GlyphDraw> {
241 match self.font(&font_and_mat.font_ref) {
242 Some(font) => {
243 let glyphs = font.draw(text);
244 Some(glyphs)
245 }
246 _ => None,
247 }
248 }
249
250 fn font(&self, font_ref: &Id<Font>) -> Option<&Font> {
251 let font_assets = self
252 .resource_storage
253 .get::<limnus_assets::Assets<Font>>()
254 .expect("font assets should be a thing");
255
256 font_assets.get(font_ref)
257 }
258
259 fn audio_sample_wav(&mut self, name: impl Into<AssetName>) -> StereoSampleRef {
260 let asset_loader = self
261 .resource_storage
262 .get_mut::<AssetRegistry>()
263 .expect("should exist registry");
264 asset_loader.load::<StereoSample>(name.into().with_extension("wav"))
265 }
266}