From e8eef7b623b4a24a03d27876896189776dc9407e Mon Sep 17 00:00:00 2001 From: Laszlo Lukacs Date: Sun, 15 Jun 2025 16:20:50 +0200 Subject: [PATCH 1/2] black rails --- src/state.rs | 4 +++- src/train.rs | 36 ++++++++++++++++++++++++++---- src/ui.rs | 62 +++++++++++++++++++++++++++++++++------------------- 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/state.rs b/src/state.rs index d17aeda..3833d62 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::sync::atomic::AtomicUsize; use std::sync::{Arc, RwLock}; use crate::dijkstra::{GlobePoints, GridPoint}; @@ -44,7 +45,7 @@ impl Default for Config { } } -#[derive(PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash, Clone, Copy)] pub struct Rail { pub from: GridPoint, pub to: GridPoint, @@ -52,6 +53,7 @@ pub struct Rail { pub struct RailInfo { pub entity: Entity, + pub counter: AtomicUsize, // Other details such as how frequently the rail is used can come here. } diff --git a/src/train.rs b/src/train.rs index 41662fc..92a83f9 100644 --- a/src/train.rs +++ b/src/train.rs @@ -1,8 +1,10 @@ +use crate::state::{Rail, State}; use bevy::prelude::*; +use std::sync::atomic::Ordering; #[derive(Component)] pub struct Train { - pub transforms: Vec, + pub transforms: Vec<(Transform, Rail)>, pub idx: usize, pub next_idx: usize, pub forward: bool, @@ -14,7 +16,7 @@ pub struct Train { pub struct SelectedTrain; impl Train { - pub fn new(transforms: Vec) -> Option { + pub fn new(transforms: Vec<(Transform, Rail)>) -> Option { if transforms.len() < 2 { return None; } @@ -29,7 +31,7 @@ impl Train { } fn transform_at(&self, idx: i32) -> Transform { - self.transforms[idx.clamp(0, self.transforms.len() as i32 - 1) as usize] + self.transforms[idx.clamp(0, self.transforms.len() as i32 - 1) as usize].0 } fn duration_between(&self, start: &Transform, end: &Transform) -> f32 { @@ -107,13 +109,39 @@ impl Train { } } - pub fn update(&mut self, transform: &mut Transform, time_passed_seconds: f32) { + pub fn update( + &mut self, + transform: &mut Transform, + time_passed_seconds: f32, + state: &State, + commands: &mut Commands, + materials: &mut Assets, + ) { if self.segment_duration.is_none() { self.compute_segment_duration(); } self.seconds_spent_within_segment += time_passed_seconds; if self.seconds_spent_within_segment >= self.segment_duration.unwrap() { + let rail_info = state.rails.rails.get(&self.transforms[self.idx].1).unwrap(); + + rail_info.counter.fetch_add(1, Ordering::Relaxed); + + let r = 0u8; + let g = 0u8; + let b = 0u8; + + let material = materials.add(StandardMaterial { + base_color: Color::srgb_u8(r, g, b), + perceptual_roughness: 0.0, + metallic: 0.0, + ..default() + }); + + commands + .entity(rail_info.entity) + .insert((MeshMaterial3d(material),)); + // Move to the next segment. self.idx = self.next_idx; diff --git a/src/ui.rs b/src/ui.rs index 30495d4..8b466c2 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -283,9 +283,7 @@ fn create_path_if_dijkstra_ready( let rotation = Quat::from_mat3(&Mat3::from_cols(Vec3::cross(dir_norm, up), dir_norm, up)); - train_transforms - .push(Transform::from_translation(mid_point * 1.005).with_rotation(rotation)); - + let entity = // If this piece of rail already exists, just change its material // corresponding to the current path. // We don't _really_ need this, but this demonstrates how to update @@ -294,24 +292,32 @@ fn create_path_if_dijkstra_ready( commands .entity(rail_info.entity) .insert((MeshMaterial3d(material.clone()),)); - continue; - } - // Otherwise, create a new entity for the rail and store it in the - // Rails resource. - // - // We first create an empty entity in order to already have its ID - // which we can key the RailInfo with. - // - // We'll update it with all the details the same way as we've updated - // the existing rail piece above. - let entity = commands.spawn_empty().id(); - state.rails.rails.insert( + rail_info.entity + } else { + // Otherwise, create a new entity for the rail and store it in the + // Rails resource. + // + // We first create an empty entity in order to already have its ID + // which we can key the RailInfo with. + // + // We'll update it with all the details the same way as we've updated + // the existing rail piece above. + let entity = commands.spawn_empty().id(); + state.rails.rails.insert( + rail, + RailInfo { + entity, + counter: 0.into(), + // Other details can be added here. + }, + ); + entity + }; + + train_transforms.push(( + Transform::from_translation(mid_point * 1.005).with_rotation(rotation), rail, - RailInfo { - entity, - // Other details can be added here. - }, - ); + )); commands.entity(entity).insert(( Mesh3d(path_mesh.clone()), @@ -686,11 +692,23 @@ fn highlight_city( } } -fn move_trains(time: Res