use std::{hash::Hash, path::PathBuf};
use ahash::AHashMap;
use bevy::{
asset::{AssetPath, RecursiveDependencyLoadState},
prelude::*,
};
use enum_iterator::Sequence;
use iyes_progress::Progress;
use crate::names::FileStem;
pub trait AssetCollection {
type Key;
type Asset: Asset;
fn get(&self, scene_type: Self::Key) -> &Handle<Self::Asset>;
}
pub(crate) trait AssetCollectionLoader
where
Self: Sized + AssetCollection,
Self::Key: Eq + Hash + FileStem + Sequence,
{
const DIRECTORY: &'static str;
const SUFFIX: &'static str;
fn new(map: AHashMap<Self::Key, Handle<Self::Asset>>) -> Self;
fn label() -> Option<String>;
fn init(server: &AssetServer) -> Self {
Self::new(AHashMap::from_iter(enum_iterator::all::<Self::Key>().map(
|key| {
let mut model_path = PathBuf::new();
model_path.push(Self::DIRECTORY);
model_path.push(format!("{}.{}", key.stem(), Self::SUFFIX));
let mut asset_path = AssetPath::from(model_path);
if let Some(label) = Self::label() {
asset_path = asset_path.with_label(label);
}
let handle = server.load(asset_path);
(key, handle)
},
)))
}
fn progress(&self, server: &AssetServer) -> Progress {
enum_iterator::all::<Self::Key>()
.map(
|key| match server.get_recursive_dependency_load_state(self.get(key)) {
Some(load_state) => match load_state {
RecursiveDependencyLoadState::Failed => panic!("Model loading failed"),
RecursiveDependencyLoadState::NotLoaded => false.into(),
RecursiveDependencyLoadState::Loading => false.into(),
RecursiveDependencyLoadState::Loaded => true.into(),
},
None => panic!(
"Unknown asset: {}/{}.{}",
Self::DIRECTORY,
key.stem(),
Self::SUFFIX
),
},
)
.reduce(|a, b| a + b)
.unwrap_or(Progress { done: 0, total: 0 })
}
}