1#![allow(incomplete_features)]
6#![feature(generic_const_exprs)]
7#![feature(clamp_magnitude)]
8
9use std::collections::HashMap;
10
11use crate::{
12 editor::EditorPlugin,
13 game::{camera::CameraPlugin, cursor::CursorPlugin, pausing::PausingPlugin},
14 sim::SimPlugin,
15 ui::UiPlugin,
16};
17
18use bevy::{
19 DefaultPlugins,
20 app::{App, AppExit, PluginGroup, Startup},
21 asset::{Assets, Handle},
22 audio::AudioPlugin,
23 camera::ClearColor,
24 color::Color,
25 ecs::{
26 resource::Resource,
27 system::{Commands, ResMut},
28 },
29 feathers::{FeathersPlugins, dark_theme::create_dark_theme, palette, theme::UiTheme},
30 mesh::Mesh,
31 picking::mesh_picking::MeshPickingPlugin,
32 shape::Circle,
33 sprite_render::ColorMaterial,
34 state::{app::AppExtStates, state::States},
35};
36
37#[cfg(feature = "test_world")]
38pub mod test_world;
39pub mod editor;
41pub mod game;
42pub mod shape;
43pub mod sim;
44pub mod ui;
45pub mod utils;
46
47#[derive(PartialEq, Eq, Hash)]
48pub enum AssetType {
49 BogieNormal,
50 CarriageNormal,
51 TrackNodeNormal,
52 TrackNodeActive,
53 TrackSegmentNormal,
54 TrackSegmentGhost,
55 TrackSegmentHighlight,
56 SignalNormal,
57 Indicator,
58}
59
60#[derive(Resource)]
61pub struct AssetsManager {
62 meshes: HashMap<AssetType, Handle<Mesh>>,
63 materials: HashMap<AssetType, Handle<ColorMaterial>>,
64}
65
66pub fn setup_assets_manager(
67 mut cmd: Commands,
68 mut meshes: ResMut<Assets<Mesh>>,
69 mut materials: ResMut<Assets<ColorMaterial>>,
70) {
71 cmd.insert_resource(AssetsManager {
72 meshes: HashMap::from([
73 (AssetType::TrackNodeNormal, meshes.add(Circle::new(2.0))),
74 (AssetType::Indicator, meshes.add(Circle::new(1.5))),
75 (AssetType::SignalNormal, meshes.add(Circle::new(1.0))),
76 ]),
77 materials: HashMap::from([
78 (
79 AssetType::CarriageNormal,
80 materials.add(Color::hsl(0.0, 0.95, 0.7)),
81 ),
82 (
83 AssetType::TrackNodeNormal,
84 materials.add(Color::hsl(20.0, 0.95, 0.7)),
85 ),
86 (
87 AssetType::TrackNodeActive,
88 materials.add(Color::hsl(0.0, 0.95, 0.7)),
89 ),
90 (
91 AssetType::BogieNormal,
92 materials.add(Color::hsl(0.0, 0.0, 0.7)),
93 ),
94 (
95 AssetType::TrackSegmentNormal,
96 materials.add(Color::hsl(180.0, 0.95, 0.7)),
97 ),
98 (
99 AssetType::TrackSegmentGhost,
100 materials.add(Color::hsl(0.0, 0.0, 0.5)),
101 ),
102 (
103 AssetType::TrackSegmentHighlight,
104 materials.add(Color::hsl(50.0, 1.0, 0.5)),
105 ),
106 (
107 AssetType::Indicator,
108 materials.add(Color::srgb(1.0, 0.0, 0.5)),
109 ),
110 (
111 AssetType::SignalNormal,
112 materials.add(Color::hsl(60.0, 0.95, 0.7)),
113 ),
114 ]),
115 });
116}
117
118#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, States)]
120pub enum AppState {
121 #[default]
122 Main,
123}
124
125fn main() -> AppExit {
126 let mut app = App::new();
127 app.add_plugins((
128 DefaultPlugins.build().disable::<AudioPlugin>(),
130 MeshPickingPlugin,
131 FeathersPlugins,
132 ))
133 .insert_resource(UiTheme(create_dark_theme()))
134 .insert_resource(ClearColor(palette::GRAY_0));
135
136 app.init_state::<AppState>()
140 .add_plugins((CameraPlugin, CursorPlugin, PausingPlugin))
142 .add_plugins(UiPlugin)
144 .add_plugins(EditorPlugin)
145 .add_plugins(SimPlugin)
146 .add_systems(Startup, setup_assets_manager);
147
148 #[cfg(feature = "test_world")]
149 app.add_systems(Startup, test_world::basic_world.after(setup_assets_manager));
150
151 app.run()
152}