Skip to main content

10_references/
10_references.rs

1use keket::{
2    database::{AssetDatabase, reference::AssetRef},
3    fetch::file::FileAssetFetch,
4    protocol::bundle::{
5        BundleAssetProtocol, BundleWithDependencies, BundleWithDependenciesProcessor,
6    },
7};
8use serde::Deserialize;
9use std::error::Error;
10
11fn main() -> Result<(), Box<dyn Error>> {
12    /* ANCHOR: main */
13    let mut database = AssetDatabase::default()
14        .with_protocol(BundleAssetProtocol::new("custom", CustomAssetProcessor))
15        .with_fetch(FileAssetFetch::default().with_root("resources"));
16
17    let handle = database.ensure("custom://part1.json")?;
18
19    while database.is_busy() {
20        database.maintain()?;
21    }
22
23    let contents = handle.access::<&CustomAsset>(&database).contents(&database);
24    println!("Custom chain contents: {contents:?}");
25    /* ANCHOR_END: main */
26
27    Ok(())
28}
29
30/* ANCHOR: custom_asset */
31#[derive(Debug, Default, Deserialize)]
32struct CustomAsset {
33    content: String,
34    // Asset references are used to store path and cached handle. They serialize as asset paths.
35    // They can be used where we need to have an ability to reference asset by path, and ask
36    // for handle once instead of everytime as with asset paths.
37    #[serde(default)]
38    next: Option<AssetRef>,
39}
40
41impl CustomAsset {
42    fn contents(&self, database: &AssetDatabase) -> String {
43        let mut result = self.content.as_str().to_owned();
44        if let Some(next) = self.next.as_ref() {
45            result.push(' ');
46            if let Ok(resolved) = next.resolve(database) {
47                result.push_str(&resolved.access::<&Self>().contents(database));
48            }
49        }
50        result
51    }
52}
53/* ANCHOR_END: custom_asset */
54
55struct CustomAssetProcessor;
56
57impl BundleWithDependenciesProcessor for CustomAssetProcessor {
58    type Bundle = (CustomAsset,);
59
60    fn process_bytes(
61        &mut self,
62        bytes: Vec<u8>,
63    ) -> Result<BundleWithDependencies<Self::Bundle>, Box<dyn Error>> {
64        let asset = serde_json::from_slice::<CustomAsset>(&bytes)?;
65        let dependency = asset
66            .next
67            .as_ref()
68            .map(|reference| reference.path().clone());
69        Ok(BundleWithDependencies::new((asset,)).maybe_dependency(dependency))
70    }
71}