1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use ahash::AHashMap;
use bevy::prelude::*;
use de_core::state::AppState;
use de_types::objects::ObjectType;
use enum_iterator::Sequence;
use iyes_progress::prelude::*;

use crate::{
    collection::{AssetCollection, AssetCollectionLoader},
    names::FileStem,
};

pub(crate) struct ScenesPlugin;

impl Plugin for ScenesPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(OnEnter(AppState::AppLoading), setup)
            .add_systems(
                Update,
                check_status
                    .track_progress()
                    .run_if(in_state(AppState::AppLoading)),
            );
    }
}

#[derive(Resource)]
pub struct Scenes(AHashMap<SceneType, Handle<Scene>>);

impl AssetCollection for Scenes {
    type Key = SceneType;
    type Asset = Scene;

    fn get(&self, key: Self::Key) -> &Handle<Self::Asset> {
        self.0.get(&key).unwrap()
    }
}

impl AssetCollectionLoader for Scenes {
    const DIRECTORY: &'static str = "models";
    const SUFFIX: &'static str = "glb";

    fn new(map: AHashMap<Self::Key, Handle<Self::Asset>>) -> Self {
        Self(map)
    }

    fn label() -> Option<String> {
        Some("Scene0".to_owned())
    }
}

#[derive(Sequence, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SceneType {
    Solid(ObjectType),
    Pole,
}

impl FileStem for SceneType {
    fn stem(self) -> &'static str {
        match self {
            Self::Solid(object_type) => object_type.stem(),
            Self::Pole => "pole",
        }
    }
}

fn setup(mut commands: Commands, server: Res<AssetServer>) {
    commands.insert_resource(Scenes::init(server.as_ref()));
}

fn check_status(server: Res<AssetServer>, scenes: Res<Scenes>) -> Progress {
    scenes.progress(server.as_ref())
}