use bevy::prelude::*; use bevy::utils::HashMap; use micro_musicbox::prelude::AudioSource; use micro_musicbox::utilities::{SuppliesAudio, TrackType}; #[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)] 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>>, } 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); } 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);