Now with most elimentary integration into bevy ECS

This commit is contained in:
Ruben van de Ven 2025-04-09 10:21:30 +02:00
parent 9cc11bd1d3
commit debd9925d7

View file

@ -8,6 +8,7 @@ use bevy_nannou::NannouPlugin;
use iyes_perf_ui::prelude::*; use iyes_perf_ui::prelude::*;
use nannou_laser::point::Rgb; use nannou_laser::point::Rgb;
use trap::shapes::PositionAndIntensity; use trap::shapes::PositionAndIntensity;
use trap::tracks::Track;
use trap::zmqplugin::ZmqPlugin; use trap::zmqplugin::ZmqPlugin;
// use iyes_perf_ui::PerfUiPlugin; // use iyes_perf_ui::PerfUiPlugin;
@ -15,6 +16,7 @@ use nannou_laser as laser;
use std::fs; use std::fs;
use std::time::Instant; use std::time::Instant;
use std::time::Duration;
mod trap; mod trap;
@ -42,14 +44,26 @@ fn main() {
.run(); .run();
} }
#[derive(Resource)]
struct LaserModel{ struct LaserModel{
t: Instant, // register start time, so that animations can be moving t: Instant, // register start time, so that animations can be moving
current_points: Vec<laser::Point>
}
impl LaserModel{
pub fn new() -> Self{
Self{
t: Instant::now(),
current_points: Vec::new()
}
}
} }
#[derive(Component)] #[derive(Component)]
struct LaserApi{ struct LaserApi{
_laser_api: laser::Api, _laser_api: laser::Api,
laser_stream: laser::FrameStream<LaserModel>, laser_stream: laser::FrameStream<LaserModel>,
} }
// Because of world.insert_non_send_resource, this is an exclusive system // Because of world.insert_non_send_resource, this is an exclusive system
@ -60,9 +74,7 @@ fn setup_laser(mut commands: Commands) {
// is needed in the laser callback // is needed in the laser callback
// Initialise the state that we want to live on the laser thread and spawn the stream. // Initialise the state that we want to live on the laser thread and spawn the stream.
let laser_model = LaserModel { let laser_model = LaserModel::new();
t: Instant::now()
};
let _laser_api = laser::Api::new(); let _laser_api = laser::Api::new();
// dacs = _laser_api.detect_dacs() // dacs = _laser_api.detect_dacs()
let laser_stream = _laser_api let laser_stream = _laser_api
@ -70,35 +82,22 @@ fn setup_laser(mut commands: Commands) {
.build() .build()
.unwrap(); .unwrap();
let api = LaserApi { let api = LaserApi {
_laser_api, _laser_api,
laser_stream, laser_stream,
// current_points: Vec::new(),
}; };
commands.spawn(api); commands.spawn((api, LaserTimer {
// create the non-repeating fuse timer
timer: Timer::new(Duration::from_millis(1000), TimerMode::Repeating),
}));
} }
fn setup(mut commands: Commands) { fn setup(mut commands: Commands) {
// Spawn a camera for our main window // Spawn a camera for our main window
commands.spawn(render::NannouCamera); commands.spawn(render::NannouCamera);
// let path = "your_future_points_test.json";
// let file = File::open(path)?;
// let data = fs::read_to_string(path).expect("Unable to read file");
// let reader = BufReader::new(file);
// let res: serde_json::Value = serde_json::from_str(&data).expect("Unable to parse");
// let res: serde_json::Value = serde_json::from_str(&data).expect("Unable to parse");
// let max = res[0].iter().cloned().fold(0./0., f64::max);
// println!("{}",res);
// let u = serde_json::from_reader(reader)?;
// create a simple Perf UI with default settings
// and all entries provided by the crate:
// commands.spawn(PerfUiDefaultEntries::default());
} }
@ -122,26 +121,38 @@ fn text2points(position_and_intensity: PositionAndIntensity) -> laser::Point{
fn laser_frame_producer(model: &mut LaserModel, frame: &mut laser::Frame){ fn laser_frame_producer(model: &mut LaserModel, frame: &mut laser::Frame){
let dt = model.t.elapsed().as_millis(); // let dt = model.t.elapsed().as_millis();
let use_second = (dt % 1000) > 500; // let use_second = (dt % 1000) > 500;
// let positions = match use_second {
// true => trap::shapes::YOUR_FUTURE,
// false => trap::shapes::ARE_YOU_SURE,
// };
// let points = positions.iter().cloned().map(text2points);
let points = model.current_points.clone();
frame.add_lines(points);
}
fn get_laser_lines(use_second: bool) -> Vec<nannou_laser::Point>{
let positions = match use_second { let positions = match use_second {
true => trap::shapes::YOUR_FUTURE, true => trap::shapes::YOUR_FUTURE,
false => trap::shapes::ARE_YOU_SURE, false => trap::shapes::ARE_YOU_SURE,
}; };
println!("{}, {}" , use_second, dt); let points = positions.iter().cloned().map(text2points).collect();
// let tl = [-1.0, 1.0]; return points
// let tr = [1.0, 1.0];
// let br = [1.0, -1.0];
// let bl = [-1.0, -1.0];
// let positions = [tl, tr, br, bl, tl];
let points = positions.iter().cloned().map(text2points);
frame.add_lines(points);
} }
#[derive(Component)] #[derive(Component)]
pub struct WindowColor(Color); pub struct WindowColor(Color);
#[derive(Component)]
struct LaserTimer {
timer: Timer,
}
// fn receive_tracks(mut commands: Commands){ // fn receive_tracks(mut commands: Commands){
// } // }
@ -150,14 +161,17 @@ fn update(
mut commands: Commands, mut commands: Commands,
keys: Res<ButtonInput<KeyCode>>, keys: Res<ButtonInput<KeyCode>>,
draws: Query<(&Draw, Option<&WindowColor>)>, draws: Query<(&Draw, Option<&WindowColor>)>,
lasers: Query<&LaserApi>, mut lasers: Query<(&mut LaserApi, &mut LaserTimer)>,
mut count: Local<usize>, mut count: Local<usize>,
time: Res<Time>,
) { ) {
if keys.just_pressed(KeyCode::Space) {
if keys.just_pressed(KeyCode::KeyQ) {
// Increment the count to track the number of windows // Increment the count to track the number of windows
*count += 1; *count += 1;
// We need a render layer to make sure we only render the camera for this window // We need a render layer to make sure we only render the camera for this window
let layer = RenderLayers::layer(*count); let layer = RenderLayers::layer(*count);
// Spawn a new window with a unique title, resolution, and background color // Spawn a new window with a unique title, resolution, and background color
let entity = commands let entity = commands
.spawn(( .spawn((
@ -179,6 +193,20 @@ fn update(
commands.spawn((render::NannouCamera::for_window(entity), layer.clone())); commands.spawn((render::NannouCamera::for_window(entity), layer.clone()));
} }
for (laser_api, mut laser_timer) in lasers.iter_mut() {
laser_timer.timer.tick(time.delta());
// laser_timer.timer.
let version = laser_timer.timer.elapsed().as_millis() > 500;
println!("{} {}", version, laser_timer.timer.elapsed().as_millis());
let lines = get_laser_lines(version);
laser_api.laser_stream.send(|laser| {
laser.current_points = lines; // TODO)) here the render function should run, then in laser_frame_producer, merely take these points and pass along
}).unwrap();
// println!("Test")
}
for (draw, window_color) in draws.iter() { for (draw, window_color) in draws.iter() {
if let Some(window_color) = window_color { if let Some(window_color) = window_color {
draw.background().color(window_color.0); draw.background().color(window_color.0);
@ -188,13 +216,8 @@ fn update(
draw.ellipse().color(LIGHT_GRAY).w_h(100.0, 100.0); draw.ellipse().color(LIGHT_GRAY).w_h(100.0, 100.0);
for (laser_api) in lasers.iter() {
draw.text("test")
.color(BLACK)
// .glyph_colors(glyph_colors)
.font_size(24);
}
} }
} }