paiagram/rw_data/
mod.rs

1//! Module for reading and writing various data formats.
2
3pub 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// TODO: make this an Event instead
50#[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}