use bevy::asset::Handle;
use bevy::prelude::*;
use bevy_rapier2d::prelude::{AdditionalMassProperties, Collider};
use bevy_replicon::prelude::Replicated;
use crate::config::part::PartConfig;
use crate::ecs::Part;
pub fn part_config_plugin(app: &mut App) {
app.add_systems(PreUpdate, handle_spawn_part_requests)
.add_systems(Update, update_part_requests);
}
#[derive(Component, Debug)]
pub struct SpawnPart(pub String);
#[derive(Component)]
struct LoadingPart(Handle<PartConfig>);
#[derive(Component, Debug)]
struct PartType(AssetId<PartConfig>);
#[derive(Component)]
/// STOP DELETING MY ASSET BEVY
struct LiveConfigHandle(Handle<PartConfig>);
// watch for new SpawnPart components and start loading their config files
fn handle_spawn_part_requests(new_parts: Query<(Entity, &SpawnPart), Added<SpawnPart>>, mut commands: Commands, asset_server: Res<AssetServer>, assets: Res<Assets<PartConfig>>) {
for (new_part, request) in &new_parts {
info!(?new_part, ?request, "answering part request");
let hdl: Handle<PartConfig> = asset_server.load(request.0.clone());
commands.entity(new_part)
.remove::<SpawnPart>()
.insert(LiveConfigHandle(hdl.clone()));
if let Some(cfg) = assets.get(&hdl) {
spawn_part(commands.reborrow(), new_part, cfg, &hdl.id(), hdl.clone());
} else {
commands.entity(new_part)
.insert(LoadingPart(hdl.clone()));
}
}
}
fn update_part_requests(
mut ev_config: EventReader<AssetEvent<PartConfig>>,
loading_parts: Query<(Entity, &LoadingPart)>,
existing_parts: Query<(Entity, &PartType)>,
mut assets: ResMut<Assets<PartConfig>>,
mut commands: Commands
) {
for ev in ev_config.read() {
match ev {
AssetEvent::Added { id } => {
info!(?id, "asset added");
for (loading_part, req) in &loading_parts {
if req.0.id() == *id {
let strong_handle = assets.get_strong_handle(*id).unwrap();
let Some(asset) = assets.get(*id) else { continue; };
spawn_part(commands.reborrow(), loading_part, asset, id, strong_handle);
}
}
},
AssetEvent::Modified { id } => {
info!(?id, "updating part");
for (existing_part, ptype) in &existing_parts {
if ptype.0 == *id {
let strong_handle = assets.get_strong_handle(*id).unwrap();
let Some(asset) = assets.get(ptype.0) else { continue; };
spawn_part(commands.reborrow(), existing_part, asset, id, strong_handle);
}
}
}
_ => {}
}
}
}
fn spawn_part(mut commands: Commands, entity: Entity, part: &PartConfig, id: &AssetId<PartConfig>, strong_handle: Handle<PartConfig>) {
commands.entity(entity)
.remove::<LoadingPart>()
.insert(Part {
sprite: part.part.sprite_disconnected.clone(),
width: part.physics.width,
height: part.physics.height,
mass: part.physics.mass,
})
.insert(Collider::cuboid(part.physics.width / 2.0, part.physics.height / 2.0))
.insert(AdditionalMassProperties::Mass(part.physics.mass))
.insert(PartType(*id))
.insert(Replicated);
}