use assets_manager::{Asset, AssetCache, BoxedError, FileAsset, SharedString};
use serde::Deserialize;
use std::sync::Arc;
#[derive(Deserialize, Debug)]
#[allow(dead_code)]
struct Monster {
name: String,
description: String,
health: u32,
}
impl FileAsset for Monster {
const EXTENSION: &'static str = "ron";
fn from_bytes(bytes: std::borrow::Cow<[u8]>) -> Result<Self, BoxedError> {
assets_manager::asset::load_ron(&bytes)
}
}
#[derive(Deserialize, Debug)]
struct LevelManifest {
name: String,
spawn_table: Vec<(String, u32)>,
}
impl FileAsset for LevelManifest {
const EXTENSION: &'static str = "ron";
fn from_bytes(bytes: std::borrow::Cow<[u8]>) -> Result<Self, BoxedError> {
assets_manager::asset::load_ron(&bytes)
}
}
#[derive(Debug)]
#[allow(dead_code)]
struct Level {
id: SharedString,
name: String,
spawn_table: Vec<(Arc<Monster>, f32)>,
}
impl Asset for Level {
fn load(cache: &AssetCache, id: &SharedString) -> Result<Self, BoxedError> {
let raw_level = cache.load::<LevelManifest>(id)?.read();
let mut spawn_table = Vec::with_capacity(raw_level.spawn_table.len());
let total = raw_level.spawn_table.iter().map(|(_, n)| *n).sum::<u32>() as f32;
for &(ref monster_id, spawn_chance) in &raw_level.spawn_table {
let monster = cache.load::<Arc<Monster>>(monster_id)?.cloned();
let spawn_chance = spawn_chance as f32 / total;
spawn_table.push((monster, spawn_chance));
}
Ok(Level {
id: id.clone(),
name: raw_level.name.clone(),
spawn_table,
})
}
}
fn main() -> Result<(), BoxedError> {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.init();
let cache = AssetCache::new("assets")?;
let level = cache.load::<Level>("example.levels.forest")?;
let mut watcher = level.reload_watcher();
println!("{level:#?}");
loop {
if watcher.reloaded() {
println!("{level:#?}");
}
std::thread::sleep(std::time::Duration::from_millis(100));
}
}