rantz_proto 1.2.4

An opinionated rust library for transforming on-disk assets into Entities in Bevy.
Documentation
use crate::prelude::*;
use bevy::{prelude::*, utils::HashMap};
#[cfg(feature = "progress_tracking")]
use iyes_progress::Progress;
use std::{
    any::{type_name, TypeId},
    path::PathBuf,
};

#[derive(Default, Resource, Debug)]
pub struct ManifestLoader {
    to_load: HashMap<TypeId, PathBuf>,
    loaded: HashMap<TypeId, UntypedHandle>,
    processed: HashMap<TypeId, UntypedHandle>,
    #[cfg(feature = "progress_tracking")]
    progress: Progress,
}

impl ManifestLoader {
    pub fn new() -> Self {
        Default::default()
    }

    #[cfg(feature = "progress_tracking")]
    fn inc_progress_todo(&mut self) {
        self.progress.total += 2;
    }

    #[cfg(feature = "progress_tracking")]
    fn inc_progress_done(&mut self) {
        self.progress.done += 1;
    }

    #[cfg(feature = "progress_tracking")]
    pub fn progress(&self) -> &Progress {
        &self.progress
    }

    pub fn register<M: Manifest>(&mut self, path: impl Into<PathBuf>) {
        let path: PathBuf = path.into();
        let type_id = std::any::TypeId::of::<ManifestCollection<M>>();

        self.to_load.insert(type_id, path);

        #[cfg(feature = "progress_tracking")]
        self.inc_progress_todo();
    }

    pub fn load<M: Manifest>(&mut self, asset_server: &mut AssetServer) {
        let type_id = std::any::TypeId::of::<ManifestCollection<M>>();
        let Some(path) = self.to_load.get(&type_id) else {
            error!("Load called without path: {:?}", type_name::<M>());
            return;
        };

        let handle = asset_server
            .load::<ManifestCollection<M>>(path.clone())
            .untyped();

        self.loaded.insert(type_id, handle);
        self.to_load.remove(&type_id);

        #[cfg(feature = "progress_tracking")]
        self.inc_progress_done();
    }

    pub fn is_loaded<M: Manifest>(&self) -> bool {
        let type_id = std::any::TypeId::of::<ManifestCollection<M>>();
        self.loaded.contains_key(&type_id)
    }

    pub fn process<M: Manifest<Output = P>, P: Prototype>(
        &mut self,
        assets: &mut Assets<ManifestCollection<M>>,
        protos: &mut PrototypeLibrary<P>,
    ) {
        let id = std::any::TypeId::of::<ManifestCollection<M>>();
        let untyped_handle = self.loaded.get(&id).unwrap();
        let typed_handle = untyped_handle.clone_weak().typed::<ManifestCollection<M>>();

        let Some(manifest) = assets.get(&typed_handle) else {
            error!("Failed to get manifest: {:?}", id);
            return;
        };

        protos.clear();
        for m in manifest {
            let item: P = m.reify();
            protos.insert(item);
        }

        self.processed.insert(id, untyped_handle.clone());

        #[cfg(feature = "progress_tracking")]
        self.inc_progress_done();
    }
}