Ensure a font is loaded (no-op if already cached).
(asset: &'static FontAsset)
| 205 | |
| 206 | /// Ensure a font is loaded (no-op if already cached). |
| 207 | pub async fn ensure(asset: &'static FontAsset) { |
| 208 | // Check if already loaded (quick lock) |
| 209 | { |
| 210 | let mut fm = FONT_MANAGER.lock().unwrap(); |
| 211 | // Already the default font? |
| 212 | if fm.default_font.as_ref().map(|d| d.key) == Some(asset.key()) { |
| 213 | return; |
| 214 | } |
| 215 | // Already in cache? |
| 216 | if let Some(data) = fm.fonts.get_mut(asset.key()) { |
| 217 | data.frames_not_used = 0; |
| 218 | return; |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | // Load outside the lock |
| 223 | let font = match asset { |
| 224 | FontAsset::Bytes { data, .. } => { |
| 225 | macroquad::text::load_ttf_font_from_bytes(data) |
| 226 | .expect("Failed to load font from bytes") |
| 227 | } |
| 228 | FontAsset::Path(path) => { |
| 229 | let resolved = resolve_asset_path(path); |
| 230 | macroquad::text::load_ttf_font(resolved).await |
| 231 | .unwrap_or_else(|e| panic!("Failed to load font '{}': {:?}", path, e)) |
| 232 | } |
| 233 | }; |
| 234 | |
| 235 | // Insert with lock |
| 236 | let mut fm = FONT_MANAGER.lock().unwrap(); |
| 237 | let key = asset.key(); |
| 238 | fm.fonts.entry(key).or_insert(FontData { frames_not_used: 0, font }); |
| 239 | } |
| 240 | |
| 241 | pub fn clean(&mut self) { |
| 242 | self.fonts.retain(|_, data| data.frames_not_used <= self.max_frames_not_used); |
nothing calls this directly
no test coverage detected