#![allow(clippy::tabs_in_doc_comments)]
mod atlas;
mod config;
mod loader;
mod vertex;
pub use crate::{
atlas::*,
config::*,
loader::*
};
use bevy_asset::*;
use bevy_app::*;
use bevy_ecs::prelude::*;
use bevy_render::prelude::Image;
use bevy_sprite::TextureAtlasLayout;
use log::*;
use tokio::sync::oneshot::*;
#[derive(Default)]
pub struct ChairPlugin;
impl Plugin for ChairPlugin {
fn build(&self, app: &mut App) {
if !app.world.contains_resource::<ChairConfig>() {
app.world.init_resource::<ChairConfig>();
}
let (atlas_tx, atlas_rx) = channel();
app.register_asset_loader(ChairLoader::new(atlas_rx))
.init_state::<ChairState>()
.insert_resource(AtlasSender(atlas_tx))
.add_systems(OnEnter(ChairState::Setup), create_atlas)
.add_systems(Update, check_ready.run_if(in_state(ChairState::Setup)))
.add_systems(OnEnter(ChairState::Load), load_atlas)
.add_systems(OnEnter(ChairState::Packed), send_atlas);
}
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq, States)]
pub enum ChairState {
#[default]
Setup,
Load,
Packed,
Ready
}
#[derive(Resource)]
struct AtlasSender(Sender<ChairAtlas>);
fn create_atlas(
mut commands: Commands,
assets: Res<AssetServer>,
config: Res<ChairConfig>
) {
let atlas = RawChairAtlas::new(&assets, config.textures);
debug!("Created atlas");
commands.insert_resource(MutChairAtlas::new(atlas));
}
fn check_ready(
mut state: ResMut<NextState<ChairState>>,
atlas: Res<MutChairAtlas>,
assets: Res<AssetServer>,
folders: Res<Assets<LoadedFolder>>
) {
if assets.load_state(atlas.0.folder.id()) != LoadState::Loaded {
return;
}
let Some(folder) = folders.get(&atlas.0.folder) else {
error!("Folder handle does not exist?!");
return;
};
for handle in &folder.handles {
if assets.load_state(handle.id()) != LoadState::Loaded {
return;
}
}
info!("Atlas textures loaded");
state.set(ChairState::Load);
}
fn load_atlas(
mut atlas_mut: ResMut<MutChairAtlas>,
mut folders: ResMut<Assets<LoadedFolder>>,
mut textures: ResMut<Assets<Image>>,
mut atlases: ResMut<Assets<TextureAtlasLayout>>,
mut state: ResMut<NextState<ChairState>>
) {
atlas_mut.0.load(&mut folders, &mut textures, &mut atlases);
state.set(ChairState::Packed);
info!("Packed atlas");
}
fn send_atlas(world: &mut World) {
let atlas_mut = world.remove_resource::<MutChairAtlas>().unwrap();
let atlas = ChairAtlas(atlas_mut.0);
world.insert_resource(atlas.clone());
let sender = world.remove_resource::<AtlasSender>().unwrap();
sender.0.send(atlas)
.expect("ChairLoader died");
let mut state = world.resource_mut::<NextState<ChairState>>();
state.set(ChairState::Ready);
debug!("Sent atlas");
}