1pub mod custom;
4pub mod gtfs;
5pub mod jgrpp;
6pub mod oudiasecond;
7pub mod qetrc;
8pub mod saveload;
9pub mod write;
10
11use bevy::prelude::*;
12use serde::Deserialize;
13
14use crate::units::time::{Duration, TimetableTime};
15
16pub struct RwDataPlugin;
17
18impl Plugin for RwDataPlugin {
19 fn build(&self, app: &mut App) {
20 app.add_message::<ModifyData>().add_systems(
21 FixedUpdate,
22 (
23 clear_resources,
24 qetrc::load_qetrc,
25 oudiasecond::load_oud2,
26 custom::load_qetrc,
27 jgrpp::load_jgrpp_timetable_export,
28 )
29 .chain()
30 .run_if(on_message::<ModifyData>),
31 );
32 app.add_observer(gtfs::load_gtfs_static);
33 #[cfg(target_arch = "wasm32")]
34 app.add_systems(
35 Update,
36 saveload::consume_autosave_load_task
37 .run_if(resource_exists::<saveload::AutosaveLoadTask>),
38 );
39 }
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43pub enum DataType {
44 QETRC,
45 OuDiaSecond,
46 Custom,
47}
48
49#[derive(Message)]
51pub enum ModifyData {
52 ClearAllData,
53 LoadQETRC(String),
54 LoadOuDiaSecond(String),
55 LoadCustom(String),
56 LoadJGRPP(Vec<String>),
57 LoadOnlineData(String, DataType),
58}
59
60fn clear_resources(
61 mut commands: Commands,
62 mut reader: MessageReader<ModifyData>,
63 vehicles: Query<Entity, With<crate::vehicles::Vehicle>>,
64 intervals: Query<Entity, With<crate::graph::Interval>>,
65 stations: Query<Entity, With<crate::graph::Station>>,
66) {
67 let mut delete = false;
68 for modification in reader.read() {
69 if let ModifyData::ClearAllData = modification {
70 delete = true;
71 }
72 }
73 if !delete {
74 return;
75 }
76 for vehicle in vehicles.iter() {
77 commands.entity(vehicle).despawn_children().despawn();
78 }
79 for interval in intervals.iter() {
80 commands.entity(interval).despawn_children().despawn();
81 }
82 for station in stations.iter() {
83 commands.entity(station).despawn_children().despawn();
84 }
85 info!("Cleared all data from the application.");
86}
87
88fn normalize_times<'a>(mut time_iter: impl Iterator<Item = &'a mut TimetableTime> + 'a) {
89 let Some(mut previous_time) = time_iter.next().copied() else {
90 return;
91 };
92 for time in time_iter {
93 if *time < previous_time {
94 *time += Duration(86400);
95 }
96 previous_time = *time;
97 }
98}
99
100#[derive(Asset, TypePath, Debug, Deserialize)]
101pub struct UnparsedOnlineData(String);
102
103fn load_online_data(url: In<String>, asset_server: Res<AssetServer>) {
104 let handle: Handle<UnparsedOnlineData> = asset_server.load(url.0);
105}