Skip to main content

bevy_dlc/
ext.rs

1use bevy::prelude::*;
2
3use crate::{DlcLoader, asset_loader};
4
5pub trait AppExt {
6     /// Register a `DlcLoader` for the given asset type `T`. This is required for any asset type
7    /// that may be loaded from a DLC pack. The plugin registers loaders for common asset types
8    /// (Image, Scene, Mesh, Font, AudioSource, etc.) but you must register loaders for any custom
9    /// asset types.
10    ///
11    /// **Important**: As of `v2.0`, this function also calls `init_asset::<T>()` to register the asset type itself, so you do not need to call `init_asset` separately.
12    ///
13    /// **Suggestion**: If I missed a common asset type that should be supported out-of-the-box,
14    /// please open an issue or PR to add it!
15    fn register_dlc_type<T: Asset>(&mut self) -> &mut Self;
16}
17
18impl AppExt for App {
19    fn register_dlc_type<T: Asset>(&mut self) -> &mut Self {
20        self.init_asset::<T>();
21        self.init_asset_loader::<DlcLoader<T>>();
22
23        // ensure a factory entry exists so `DlcPackLoader` will include a
24        // `TypedSubAssetRegistrar::<T>` when it (re)registers. This allows
25        // `register_dlc_type` to be called *before* or *after* the plugin is
26        // added and still result in the pack loader supporting `T`.
27        let tname = T::type_path();
28        if let Some(factories_res) = self
29            .world_mut()
30            .get_resource_mut::<asset_loader::DlcPackRegistrarFactories>()
31        {
32            let mut inner = factories_res.0.write().unwrap();
33            if !inner.iter().any(|f| f.type_name() == tname) {
34                inner.push(Box::new(asset_loader::TypedRegistrarFactory::<T>::default()));
35            }
36        } else {
37            let mut v: Vec<Box<dyn asset_loader::DlcPackRegistrarFactory>> = Vec::new();
38            v.push(Box::new(asset_loader::TypedRegistrarFactory::<T>::default()));
39            self.insert_resource(asset_loader::DlcPackRegistrarFactories(
40                std::sync::Arc::new(std::sync::RwLock::new(v)),
41            ));
42        }
43        self
44    }
45}