use bevy::prelude::*; use bevy::utils::HashMap; use kayak_font::KayakFont; use micro_asset_io::APack; use micro_musicbox::prelude::AudioSource; use micro_musicbox::utilities::{SuppliesAudio, TrackType}; use crate::assets::asset_types::ldtk_project::LdtkProject; #[derive(Copy, Clone, Debug)] pub struct SpriteSheetConfig { pub tile_width: usize, pub tile_height: usize, pub columns: usize, pub rows: usize, } impl SpriteSheetConfig { pub fn squares(tile_wh: usize, columns: usize, rows: usize) -> Self { Self { tile_width: tile_wh, tile_height: tile_wh, columns, rows, } } pub fn rectangles(tile_width: usize, tile_height: usize, columns: usize, rows: usize) -> Self { Self { tile_width, tile_height, columns, rows, } } } #[derive(Default, Resource)] pub struct AssetHandles { pub images: HashMap<String, Handle<Image>>, pub atlas: HashMap<String, Handle<TextureAtlas>>, pub sounds: HashMap<String, Handle<AudioSource>>, pub fonts: HashMap<String, Handle<Font>>, pub apacks: HashMap<String, Handle<APack>>, pub ldtk: HashMap<String, Handle<LdtkProject>>, pub kayak_fonts: HashMap<String, Handle<KayakFont>>, } macro_rules! fetch_wrapper { ($name: tt, $type: ty => $key: ident) => { pub fn $name<T: ToString>(&self, name: T) -> Handle<$type> { let key = name.to_string(); match self.$key.get(&key) { Some(handle) => handle.clone_weak(), None => { let keys = self.$key.keys(); panic!( "\n\nTried to fetch {} asset with a missing key: {}.\nPossible keys: {}\n\n", stringify!($name), name.to_string(), keys.map(|k| format!("'{}'", k)) .collect::<Vec<String>>() .join(", ") ) } } } }; } impl AssetHandles { fetch_wrapper!(image, Image => images); fetch_wrapper!(atlas, TextureAtlas => atlas); fetch_wrapper!(sound, AudioSource => sounds); fetch_wrapper!(font, Font => fonts); fetch_wrapper!(apack, APack => apacks); fetch_wrapper!(ldtk, LdtkProject => ldtk); fetch_wrapper!(kayak_font, KayakFont => kayak_fonts); } impl SuppliesAudio for AssetHandles { fn resolve_track_name<T: ToString>(&self, name: T) -> TrackType<String> { if self.sounds.contains_key(&name.to_string()) { TrackType::Single(name.to_string()) } else { TrackType::Missing } } fn get_audio_track<T: ToString>(&self, name: T) -> Option<Handle<AudioSource>> { self.sounds.get(&name.to_string()).map(Handle::clone_weak) } } pub type AssetNameMapping = (String, String); pub type FixedAssetNameMapping = (&'static str, &'static str);