Skip to content
Snippets Groups Projects
lib.rs 2.89 KiB
Newer Older
#![allow(clippy::type_complexity)]

// use bevy::prelude::*;
use std::time::Duration;
use bevy_app::{App, Plugin, Update};
use bevy_ecs::prelude::*;

pub use crate::components::SplashSettings;
use crate::components::{SplashTime, TweenClearColor};

mod components;
mod system;

#[derive(Default, Debug, Resource)]
struct SplashManager {
    elapsed: Duration,
}

#[derive(PartialOrd, PartialEq, Copy, Clone, Resource, Default)]
pub enum SplashState {
    #[default]
    Loading,
    Running,
}

impl SplashState {
    pub fn is_loading(&self) -> bool {
        matches!(&self, SplashState::Loading)
    }
    pub fn is_running(&self) -> bool {
        matches!(&self, SplashState::Running)
    }
}
pub fn is_loading(state: Res<SplashState>) -> bool {
    state.is_loading()
}
pub fn is_running(state: Res<SplashState>) -> bool {
    state.is_running()
}
pub fn started_running(state: Res<SplashState>) -> bool {
    state.is_changed() && state.is_running()
}

pub struct AdventSplashPlugin<StateType: States> {
    settings: SplashSettings<StateType>,
}
impl<StateType: States> AdventSplashPlugin<StateType> {
    pub fn with_settings(settings: SplashSettings<StateType>) -> AdventSplashPlugin<StateType> {
        Self { settings }
    }
}
impl<StateType: States + Copy> Plugin for AdventSplashPlugin<StateType> {
    fn build(&self, app: &mut App) {
        app.init_resource::<SplashState>()
            .insert_resource(SplashTime(Duration::from_secs(5)))
            .insert_resource(self.settings.clone())
            .add_systems(
                OnEnter(self.settings.run_in),
                system::load_assets::<StateType>,
            )
            .add_systems(
                Update,
                system::monitor_asset_loading
                    .run_if(is_loading)
                    .run_if(in_state(self.settings.run_in)),
            )
            .add_systems(
                Update,
                system::spawn_splash_assets::<StateType>
                    .run_if(started_running)
                    .run_if(in_state(self.settings.run_in)),
            )
            .add_systems(
                Update,
                (system::apply_window_scale, system::tick_time::<StateType>)
                    .run_if(is_running)
                    .run_if(in_state(self.settings.run_in)),
            )
            .add_systems(
                Update,
                system::tween_clear_color
                    .run_if(is_running)
                    .run_if(in_state(self.settings.run_in))
                    .run_if(resource_exists::<TweenClearColor>),
            )
            .add_systems(OnExit(self.settings.run_in), system::cleanup_assets);

        if self.settings.skip_on_input {
            app.add_systems(
                Update,
                system::window_skip::<StateType>
                    .run_if(is_running)
                    .run_if(in_state(self.settings.run_in)),
            );
        }
    }
}