this repo has no description
1use bevy::prelude::*;
2use bevy_brp_extras::BrpExtrasPlugin;
3use bevy_hanabi::HanabiPlugin;
4use bevy_panorbit_camera::{PanOrbitCamera, PanOrbitCameraPlugin};
5
6mod db;
7mod event_card;
8mod helix;
9mod ingest;
10mod interaction;
11mod net;
12mod particles;
13pub mod slides;
14
15
16fn main() {
17 App::new()
18 .add_plugins(DefaultPlugins.set(bevy::log::LogPlugin {
19 filter: "bevy_asset::server::loaders=error".to_string(),
20 ..default()
21 }))
22 .add_plugins(HanabiPlugin)
23 .add_plugins(PanOrbitCameraPlugin)
24 .add_plugins(BrpExtrasPlugin)
25 .add_plugins(bevy_tokio_tasks::TokioTasksPlugin::default())
26 .init_resource::<helix::HelixHierarchy>()
27 .init_resource::<helix::HelixGizmoCache>()
28 .insert_resource(helix::HelixState {
29 focal_time: 0.0,
30 active_level: 0,
31 target_level: 0.0,
32 interpolated_level: 0.0,
33 auto_follow: true,
34 time_scale: 1.0,
35 })
36 .init_resource::<interaction::DragState>()
37 .init_resource::<interaction::ZoomConfig>()
38 .init_resource::<interaction::SelectedEvent>()
39 .init_resource::<interaction::LastCursorPosition>()
40 .init_resource::<event_card::ProfileCache>()
41 .init_resource::<event_card::ProfileRequestState>()
42 .init_resource::<event_card::RecordCache>()
43 .init_resource::<event_card::CardRenderState>()
44 .init_resource::<UiFont>()
45 .insert_resource(ingest::TimeWindow {
46 anchor_us: 0,
47 latest_t: 0.0,
48 is_initialized: false,
49 })
50 .init_resource::<ingest::LoadedRanges>()
51 .init_resource::<ingest::HistoryQueryState>()
52 .init_resource::<particles::CleanupTimer>()
53 .init_asset::<slides::SlideDeckAsset>()
54 .init_asset_loader::<slides::SlideDeckLoader>()
55 .init_resource::<slides::SlideDeck>()
56 .init_resource::<slides::SlideMode>()
57 .insert_resource(ClearColor(Color::BLACK))
58 .add_systems(
59 Startup,
60 (
61 setup,
62 ingest::setup_event_dots,
63 helix::setup_helix_geometry,
64 net::setup_atp_client,
65 db::spawn_db_thread,
66 ingest::spawn_jetstream_consumer.after(db::spawn_db_thread),
67 ingest::load_historical_events
68 .after(db::spawn_db_thread)
69 .before(ingest::spawn_jetstream_consumer),
70 particles::setup_particle_effects,
71 event_card::setup_detail_card,
72 slides::load_slide_deck,
73 ),
74 )
75 .add_systems(
76 Update,
77 (
78 ingest::drain_jetstream_events,
79 ingest::poll_history_responses.after(ingest::drain_jetstream_events),
80 particles::spawn_event_particles.after(ingest::poll_history_responses),
81 particles::adjust_particle_zoom,
82 particles::cleanup_expired_events.after(particles::spawn_event_particles),
83 interaction::scroll_zoom_level,
84 interaction::button_zoom_level,
85 interaction::drag_pan_time,
86 interaction::check_pan_triggers_history_load.after(interaction::drag_pan_time),
87 interaction::toggle_pause,
88 interaction::toggle_slow_time,
89 slides::sync_slide_deck,
90 slides::slide_navigation,
91 interaction::auto_follow_latest,
92 interaction::interpolate_zoom_level,
93 interaction::update_camera_focus,
94 ),
95 )
96 .add_systems(
97 Update,
98 (
99 interaction::track_cursor,
100 interaction::pick_event.after(interaction::track_cursor),
101 event_card::update_detail_card.after(interaction::pick_event),
102 interaction::highlight_selected.after(interaction::pick_event),
103 event_card::request_profile_for_selected.after(event_card::update_detail_card),
104 event_card::request_enrichment_for_selected.after(event_card::update_detail_card),
105 helix::extend_helix_geometry,
106 helix::draw_helix,
107 ),
108 )
109 .run();
110}
111
112#[derive(Resource)]
113pub struct UiFont {
114 pub primary: bevy::asset::Handle<bevy::text::Font>,
115 pub bold: bevy::asset::Handle<bevy::text::Font>,
116 pub italic: bevy::asset::Handle<bevy::text::Font>,
117 pub emoji: bevy::asset::Handle<bevy::text::Font>,
118}
119
120impl FromWorld for UiFont {
121 fn from_world(world: &mut World) -> Self {
122 let asset_server = world.resource::<AssetServer>();
123 UiFont {
124 primary: asset_server.load("fonts/IosevkaIoskeley-Regular.ttf"),
125 bold: asset_server.load("fonts/IosevkaIoskeley-Bold.ttf"),
126 italic: asset_server.load("fonts/IosevkaIoskeley-Italic.ttf"),
127 emoji: asset_server.load("fonts/NotoColorEmoji.ttf"),
128 }
129 }
130}
131
132fn setup(mut commands: Commands) {
133 // Orbiting camera
134 commands.spawn((
135 Camera3d::default(),
136 Camera {
137 clear_color: ClearColorConfig::Custom(Color::BLACK),
138 ..default()
139 },
140 bevy::render::view::Hdr,
141 bevy::post_process::bloom::Bloom {
142 intensity: 0.08,
143 low_frequency_boost: 0.3,
144 low_frequency_boost_curvature: 0.3,
145 ..default()
146 },
147 Transform::from_translation(Vec3::new(0.0, 2.0, 8.0)).looking_at(Vec3::ZERO, Vec3::Y),
148 PanOrbitCamera {
149 focus: Vec3::ZERO,
150 button_zoom: Some(MouseButton::Middle),
151 modifier_pan: Some(KeyCode::ShiftLeft),
152 ..default()
153 },
154 ));
155
156 // Ambient light so gizmos are visible
157 commands.spawn(AmbientLight {
158 color: Color::WHITE,
159 brightness: 300.0,
160 affects_lightmapped_meshes: false,
161 });
162}