Skip to main content

traaains/sim/train/
commands.rs

1use bevy::{
2    ecs::{entity::Entity, system::Command, world::World},
3    log::tracing,
4    state::state::{NextState, State},
5};
6
7use crate::{
8    sim::train::{Carriage, CarriageBogies, Train},
9    ui::UiState,
10};
11
12pub struct RemoveTrain {
13    target: Entity,
14}
15
16impl RemoveTrain {
17    pub fn new(target: Entity) -> Self {
18        RemoveTrain { target }
19    }
20}
21
22impl Command for RemoveTrain {
23    type Out = ();
24
25    fn apply(self, world: &mut World) -> Self::Out {
26        // despawn UI if it belongs to our train
27        let ui_state = world.resource::<State<UiState>>();
28        if let UiState::TrainWindow { target } = ui_state.get()
29            && *target == self.target
30        {
31            world
32                .resource_mut::<NextState<UiState>>()
33                .set(UiState::Default);
34        }
35
36        let Some(train) = world.entity_mut(self.target).take::<Train>() else {
37            tracing::warn!("RemoveTrain called on a non-train entity, simply despawning!");
38            world.despawn(self.target);
39            return;
40        };
41
42        for ce in train.carriages {
43            let carriage = world.entity_mut(ce).take::<Carriage>().unwrap();
44
45            match carriage.bogies {
46                CarriageBogies::Single(entity) => {
47                    world.despawn(entity);
48                }
49                CarriageBogies::Double { front, back } => {
50                    world.despawn(front);
51                    world.despawn(back);
52                }
53            }
54
55            world.despawn(ce);
56        }
57
58        world.despawn(self.target);
59    }
60}