oxygengine_core/assets/
assets_preloader.rs

1use crate::{assets::database::AssetsDatabase, error::*, fetch::FetchEngine};
2
3enum Phase {
4    None,
5    Start(Box<dyn FetchEngine>),
6    Loading,
7    Ready,
8}
9
10pub struct AssetsPreloader {
11    paths: Vec<String>,
12    phase: Phase,
13}
14
15impl AssetsPreloader {
16    pub fn new<E>(engine: E, paths: Vec<&str>) -> Self
17    where
18        E: FetchEngine + 'static,
19    {
20        let paths = paths.into_iter().map(|p| p.to_owned()).collect::<Vec<_>>();
21        Self {
22            paths,
23            phase: Phase::Start(Box::new(engine)),
24        }
25    }
26
27    pub fn process(&mut self, assets: &mut AssetsDatabase) -> Result<bool> {
28        match std::mem::replace(&mut self.phase, Phase::None) {
29            Phase::Start(engine) => {
30                assets.push_fetch_engine(engine);
31                if self.paths.is_empty() {
32                    self.phase = Phase::Ready;
33                } else {
34                    self.phase = Phase::Loading;
35                    for path in &self.paths {
36                        if let Err(error) = assets.load(path) {
37                            return Err(Error::Message(format!(
38                                "Cannot load asset: {}\n{:?}",
39                                path, error
40                            )));
41                        }
42                    }
43                }
44            }
45            Phase::Loading => {
46                if assets.is_ready() && assets.are_ready(self.paths.iter()) {
47                    assets.pop_fetch_engine();
48                    self.phase = Phase::Ready;
49                } else {
50                    self.phase = Phase::Loading;
51                }
52            }
53            Phase::Ready => {
54                self.phase = Phase::Ready;
55                return Ok(true);
56            }
57            Phase::None => {}
58        }
59        Ok(false)
60    }
61
62    pub fn is_ready(&self) -> bool {
63        matches!(self.phase, Phase::Ready)
64    }
65}