1use crate::vehicles::entries::TimetableEntry;
2use bevy::prelude::*;
3use smallvec::{SmallVec, smallvec};
4mod calculate_estimates;
5pub mod entries;
6pub mod services;
7pub mod vehicle_set;
8
9#[derive(Debug, Component)]
10#[require(Name, entries::VehicleSchedule)]
11pub struct Vehicle;
12pub struct VehiclesPlugin;
13
14impl Plugin for VehiclesPlugin {
15 fn build(&self, app: &mut App) {
16 app.add_message::<AdjustTimetableEntry>()
17 .add_message::<AdjustVehicle>()
18 .add_systems(
19 FixedUpdate,
20 (
21 adjust_timetable_entry,
22 entries::calculate_actual_route,
23 calculate_estimates::calculate_estimates,
24 entries::populate_services,
25 )
26 .chain()
27 .run_if(on_message::<AdjustTimetableEntry>),
28 );
29 }
30}
31
32pub enum TimetableAdjustment {
33 SetArrivalType(entries::TravelMode),
34 AdjustArrivalTime(crate::units::time::Duration),
35 SetDepartureType(Option<entries::TravelMode>),
36 AdjustDepartureTime(crate::units::time::Duration),
37 SetStation(Entity),
38 SetService(Option<Entity>),
39 SetTrack(Option<Entity>),
40 SetNote(Option<String>),
41 PassThrough,
42}
43
44#[derive(Message)]
45pub struct AdjustTimetableEntry {
46 pub entity: Entity,
47 pub adjustment: TimetableAdjustment,
48}
49
50pub enum VehicleAdjustment {
51 AddEntry(usize, Entity),
52 RemoveEntry(Entity),
53 Rename(String),
54 Remove,
55}
56
57#[derive(Message)]
58pub struct AdjustVehicle {
59 pub entity: Entity,
60 pub adjustment: VehicleAdjustment,
61}
62
63pub fn adjust_timetable_entry(
64 mut commands: Commands,
65 mut reader: MessageReader<AdjustTimetableEntry>,
66 mut entries: Populated<&mut entries::TimetableEntry>,
67) {
68 for msg in reader.read() {
69 let AdjustTimetableEntry { entity, adjustment } = msg;
70 let mut entry = match entries.get_mut(*entity) {
71 Ok(a) => a,
72 Err(e) => {
73 warn!("Failed to adjust timetable entry {entity:?}: {e:?}");
74 continue;
75 }
76 };
77
78 use TimetableAdjustment::*;
79 match adjustment {
80 AdjustArrivalTime(dt) => entry.arrival.adjust_time(*dt),
81 SetArrivalType(nt) => entry.arrival = *nt,
82 AdjustDepartureTime(dt) => {
83 entry.departure.as_mut().map(|d| d.adjust_time(*dt));
84 }
85 SetDepartureType(nt) => entry.departure = *nt,
86 SetStation(ns) => entry.station = *ns,
87 SetService(ns) => entry.service = *ns,
88 SetTrack(nt) => entry.track = *nt,
89 SetNote(note) => {}
90 PassThrough => (),
91 }
92 }
93}