Skip to main content

traaains/sim/track/node/
commands.rs

1use bevy::{
2    ecs::{entity::Entity, system::Command, world::World},
3    log::tracing,
4    state::state::{NextState, State},
5};
6
7use crate::{sim::track::node::TrackNode, ui::UiState};
8
9pub struct RemoveNode {
10    pub target: Entity,
11}
12
13impl RemoveNode {
14    pub fn new(target: Entity) -> Self {
15        Self { target }
16    }
17}
18
19impl Command for RemoveNode {
20    type Out = ();
21
22    fn apply(self, world: &mut World) -> Self::Out {
23        // despawn UI if it belongs to our node
24        let ui_state = world.resource::<State<UiState>>();
25        if let UiState::NodeWindow { target } = ui_state.get()
26            && *target == self.target
27        {
28            world
29                .resource_mut::<NextState<UiState>>()
30                .set(UiState::Default);
31        }
32
33        world.despawn(self.target);
34    }
35}
36
37/// Removes a node's connection with `segment` and despawns it if no connections remain
38pub struct RemoveConnectionFor {
39    pub node: Entity,
40    pub segment: Entity,
41    pub despawn_node: bool,
42}
43
44impl RemoveConnectionFor {
45    pub fn new(node: Entity, segment: Entity) -> Self {
46        Self {
47            node,
48            segment,
49            despawn_node: true,
50        }
51    }
52
53    pub fn with_despawn(mut self, despawn_node: bool) -> Self {
54        self.despawn_node = despawn_node;
55        self
56    }
57}
58
59impl Command for RemoveConnectionFor {
60    type Out = Result<bool, &'static str>;
61
62    /// Returns true if the node was despawned.
63    /// Always false if `despawn_node` was set to false.
64    fn apply(self, world: &mut World) -> Self::Out {
65        let mut tn = world
66            .query::<&mut TrackNode>()
67            .get_mut(world, self.node)
68            .map_err(|_| "Applied RemoveConnectionFor on a non-track node entity!")?;
69
70        tn.connections.remove_for(self.segment);
71        if self.despawn_node && tn.connections.is_empty() {
72            tracing::debug!(
73                "Despawning node {} due to having no connected segments",
74                self.node
75            );
76
77            RemoveNode::new(self.node).apply(world);
78
79            Ok(true)
80        } else {
81            Ok(false)
82        }
83    }
84}