oxygengine_core/assets/
asset_pack_preloader.rs

1use crate::{
2    assets::{database::AssetsDatabase, protocols::pack::PackAsset},
3    error::*,
4};
5
6#[derive(Debug)]
7pub struct AssetPackPreloader {
8    paths: Vec<String>,
9    ready_pack: bool,
10    ready_from_pack: bool,
11}
12
13impl AssetPackPreloader {
14    pub fn new(
15        path: &str,
16        assets: &mut AssetsDatabase,
17        assets_from_pack: Vec<&str>,
18    ) -> Result<Self> {
19        let path = format!("pack://{}", path);
20        if let Err(error) = assets.load(&path) {
21            Err(Error::Message(format!(
22                "Could not load asset pack: {}\n{:?}",
23                path, error
24            )))
25        } else {
26            let paths = std::iter::once(path)
27                .chain(assets_from_pack.into_iter().map(|p| p.to_owned()))
28                .collect::<Vec<_>>();
29            Ok(Self {
30                paths,
31                ready_pack: false,
32                ready_from_pack: false,
33            })
34        }
35    }
36
37    pub fn process(&mut self, assets: &mut AssetsDatabase) -> Result<bool> {
38        if !self.ready_pack {
39            if assets.are_ready(self.paths.iter().take(1)) {
40                let path = &self.paths[0];
41                if let Some(asset) = assets.asset_by_path(path) {
42                    if let Some(pack) = asset.get::<PackAsset>() {
43                        let engine = pack.make_fetch_engine();
44                        assets.push_fetch_engine(Box::new(engine));
45                        self.ready_pack = true;
46                        if self.paths.len() > 1 {
47                            for path in self.paths.iter().skip(1) {
48                                if let Err(error) = assets.load(path) {
49                                    return Err(Error::Message(format!(
50                                        "Cannot load asset from pack: {}\n{:?}",
51                                        path, error
52                                    )));
53                                }
54                            }
55                        } else {
56                            self.ready_from_pack = true;
57                        }
58                    } else {
59                        return Err(Error::Message(format!("Asset is not a pack: {}", path)));
60                    }
61                } else {
62                    return Err(Error::Message(format!(
63                        "Asset pack is not loaded: {}",
64                        path
65                    )));
66                }
67            }
68            if !self.ready_pack {
69                return Ok(false);
70            }
71        }
72        if !assets.is_ready() {
73            return Ok(false);
74        }
75        if !self.ready_from_pack {
76            if assets.are_ready(self.paths.iter().skip(1)) {
77                self.ready_from_pack = true;
78            } else {
79                return Ok(false);
80            }
81        }
82        Ok(true)
83    }
84
85    pub fn is_ready(&self) -> bool {
86        self.ready_pack && self.ready_from_pack
87    }
88}