oxygengine_core/assets/
assets_preloader.rs1use 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}