use bevy::prelude::Component; use bevy::prelude::*; use bevy_rapier2d::prelude::{AdditionalMassProperties, Collider}; use crate::config::part::PartConfig; use crate::ecs::{Part, PartHandle}; pub fn part_management_plugin(app: &mut App) { app.add_systems(PreUpdate, (handle_ready_parts, handle_part_reloading)); } #[derive(Bundle)] pub struct SpawnPartBundle { pub req: SpawnPartRequest, pub transform: Transform, } #[derive(Component)] pub struct SpawnPartRequest(pub Handle); // wait for parts assets to be ready, then spawn the full part fn handle_ready_parts(loading_parts: Query<(Entity, &SpawnPartRequest)>, mut commands: Commands, assets: Res>) { for (entity, loading_part) in &loading_parts { if let Some(strong_config) = assets.get(&loading_part.0) { // config is strong; spawn 'er in! commands.entity(entity) .insert(calculate_bundle(strong_config, &loading_part.0)) .remove::(); } } } fn handle_part_reloading(existing_parts: Query<(Entity, &PartHandle)>, assets: Res>, mut asset_events: EventReader>, mut commands: Commands) { for event in asset_events.read() { match event { AssetEvent::Modified { id } => { let config = assets.get(*id).unwrap(); for existing_part in existing_parts.iter() { if existing_part.1.0.id() == *id { commands.entity(existing_part.0) .insert(calculate_bundle(config, &existing_part.1.0)); } } }, _ => {} } } } fn calculate_bundle(config: &PartConfig, handle: &Handle) -> impl Bundle { let part = Part { strong_config: config.clone(), }; let part_handle = PartHandle(handle.clone()); let collider = Collider::cuboid(config.physics.width / 2.0, config.physics.height / 2.0); let additional_mass_properties = AdditionalMassProperties::Mass(config.physics.mass); ( part, part_handle, collider, additional_mass_properties, ) }