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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::dynamic_asset::{DynamicAssetCollection, DynamicAssetCollections, DynamicAssets};
use crate::loading_state::{AssetLoaderConfiguration, InternalLoadingState, LoadingAssetHandles};
use bevy::asset::{Asset, AssetServer, Assets, LoadState};
use bevy::ecs::change_detection::ResMut;
use bevy::ecs::schedule::{NextState, State, States};
use bevy::ecs::system::{Res, SystemState};
use bevy::ecs::world::World;
use bevy::log::debug;
use std::any::TypeId;

#[allow(clippy::type_complexity)]
pub(crate) fn load_dynamic_asset_collections<S: States, C: DynamicAssetCollection + Asset>(
    world: &mut World,
    system_state: &mut SystemState<(
        Res<DynamicAssetCollections<S>>,
        Res<AssetServer>,
        Res<State<S>>,
        ResMut<AssetLoaderConfiguration<S>>,
    )>,
) {
    let (dynamic_asset_collections, asset_server, state, mut asset_loader_config) =
        system_state.get_mut(world);
    let mut loading_collections: LoadingAssetHandles<(S, C)> = LoadingAssetHandles::default();

    if let Some(files) = dynamic_asset_collections.get_files::<C>(state.get()) {
        for file in files {
            loading_collections
                .handles
                .push(asset_server.load::<C>(file).untyped());
        }
    }
    if let Some(config) = asset_loader_config
        .state_configurations
        .get_mut(state.get())
    {
        config.loading_dynamic_collections.insert(TypeId::of::<C>());
    }
    world.insert_resource(loading_collections);
}

#[allow(clippy::type_complexity)]
pub(crate) fn check_dynamic_asset_collections<S: States, C: DynamicAssetCollection + Asset>(
    world: &mut World,
    system_state: &mut SystemState<(
        Res<AssetServer>,
        Option<ResMut<LoadingAssetHandles<(S, C)>>>,
        Res<State<S>>,
        Res<Assets<C>>,
        ResMut<DynamicAssets>,
        ResMut<AssetLoaderConfiguration<S>>,
    )>,
) {
    {
        let (
            asset_server,
            mut loading_collections,
            state,
            dynamic_asset_collections,
            mut asset_keys,
            mut asset_loader_config,
        ) = system_state.get_mut(world);

        if loading_collections.is_none() {
            return;
        }
        let loading_collections = loading_collections.as_mut().unwrap();
        for handle in &loading_collections.handles {
            if let Some(load_state) = asset_server.get_load_state(handle.id()) {
                if load_state != LoadState::Loaded {
                    return;
                }
            } else {
                return;
            }
        }
        for collection in loading_collections.handles.drain(..) {
            let collection = dynamic_asset_collections
                .get(collection.typed::<C>())
                .unwrap();
            collection.register(&mut asset_keys);
        }
        let config = asset_loader_config
            .state_configurations
            .get_mut(state.get())
            .expect("No asset loader configuration for current state");
        config
            .loading_dynamic_collections
            .remove(&TypeId::of::<C>());
    }
    world.remove_resource::<LoadingAssetHandles<(S, C)>>();
}

pub(crate) fn resume_to_loading_asset_collections<S: States>(
    state: Res<State<S>>,
    mut loading_state: ResMut<NextState<InternalLoadingState<S>>>,
    asset_loader_config: Res<AssetLoaderConfiguration<S>>,
) {
    let config = asset_loader_config
        .state_configurations
        .get(state.get())
        .expect("No asset loader configuration for current state");
    if config.loading_dynamic_collections.is_empty() {
        debug!("No dynamic asset collection file left loading. Resuming to 'LoadingAssets'");
        loading_state.set(InternalLoadingState::LoadingAssets);
    }
}