Newer
Older
use std::marker::PhantomData;
use bevy::asset::LoadState;
use bevy::ecs::system::SystemParam;
use bevy::prelude::*;
use bevy::reflect::TypeUuid;
use crate::assets::asset_types::ldtk_project::LdtkProject;
use crate::assets::{AssetHandles, FixedAssetNameMapping, SpriteSheetConfig};
#[derive(SystemParam)]
pub struct AssetTypeLoader<'w, 's> {
pub handles: ResMut<'w, AssetHandles>,
pub asset_server: Res<'w, AssetServer>,
pub atlas: ResMut<'w, Assets<TextureAtlas>>,
pub apack: ResMut<'w, Assets<APack>>,
#[system_param(ignore)]
marker: PhantomData<&'s usize>,
}
macro_rules! load_basic_type {
($name: tt, $type: ty => $key: ident) => {
pub fn $name(&mut self, assets: &[FixedAssetNameMapping]) -> Vec<Handle<$type>> {
self.load_list(assets, |loader, path, key| {
let handle: Handle<$type> = loader.asset_server.load(&path);
loader.handles.$key.insert(key, handle.clone());
handle
})
}
};
}
macro_rules! load_state {
($container: expr => $key: ident) => {
$container
.asset_server
.get_group_load_state($container.handles.$key.values().map(|f| f.id()))
};
}
impl<'w, 's> AssetTypeLoader<'w, 's> {
fn load_list<
T: Sync + Send + TypeUuid + 'static,
Loader: Fn(&mut AssetTypeLoader, String, String) -> Handle<T>,
>(
&mut self,
files: &[FixedAssetNameMapping],
load: Loader,
) -> Vec<Handle<T>> {
files
.iter()
.map(|(path, key)| load(self, path.to_string(), key.to_string()))
.collect()
}
load_basic_type!(load_images, Image => images);
load_basic_type!(load_audio, AudioSource => sounds);
load_basic_type!(load_font, Font => fonts);
load_basic_type!(load_ldtk, LdtkProject => ldtk);
load_basic_type!(load_kayak_font, KayakFont => kayak_fonts);
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
pub fn load_spritesheet(
&mut self,
config: &SpriteSheetConfig,
assets: &[FixedAssetNameMapping],
) -> Vec<Handle<Image>> {
self.load_list(assets, |loader, path, key| {
let handle: Handle<Image> = loader.asset_server.load(&path);
loader
.handles
.images
.insert(key.to_string(), handle.clone());
let atlas = TextureAtlas::from_grid(
handle.clone(),
Vec2::new(config.tile_width as f32, config.tile_height as f32),
config.columns,
config.rows,
None,
None,
);
let atlas_handle = loader.atlas.add(atlas);
loader.handles.atlas.insert(key, atlas_handle);
handle
})
}
pub fn get_all_load_state(&self) -> Vec<LoadState> {
let image_state = self
.asset_server
.get_group_load_state(self.handles.images.values().map(|f| f.id()));
let atlas_state = self
.asset_server
.get_group_load_state(self.handles.images.values().map(|f| f.id()));
vec![image_state, atlas_state]
}
pub fn check_apack_process_status(&self) -> bool {
self.handles
.apacks
.values()
.all(|handle| match self.apack.get(handle) {
Some(pack) => pack.processed && pack.loaded,
_ => false,
})
}