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 nannou_laser::point::Rgb;
use trap::shapes::PositionAndIntensity;
use trap::tracks::Track;
use trap::zmqplugin::ZmqPlugin;
// use iyes_perf_ui::PerfUiPlugin;
@ -15,6 +16,7 @@ use nannou_laser as laser;
use std::fs;
use std::time::Instant;
use std::time::Duration;
mod trap;
@ -42,14 +44,26 @@ fn main() {
.run();
}
#[derive(Resource)]
struct LaserModel{
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)]
struct LaserApi{
_laser_api: laser::Api,
laser_stream: laser::FrameStream<LaserModel>,
}
// 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
// Initialise the state that we want to live on the laser thread and spawn the stream.
let laser_model = LaserModel {
t: Instant::now()
};
let laser_model = LaserModel::new();
let _laser_api = laser::Api::new();
// dacs = _laser_api.detect_dacs()
let laser_stream = _laser_api
@ -70,35 +82,22 @@ fn setup_laser(mut commands: Commands) {
.build()
.unwrap();
let api = LaserApi {
_laser_api,
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) {
// Spawn a camera for our main window
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){
let dt = model.t.elapsed().as_millis();
let use_second = (dt % 1000) > 500;
// let dt = model.t.elapsed().as_millis();
// 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 {
true => trap::shapes::YOUR_FUTURE,
false => trap::shapes::ARE_YOU_SURE,
};
println!("{}, {}" , use_second, dt);
// let tl = [-1.0, 1.0];
// 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);
let points = positions.iter().cloned().map(text2points).collect();
return points
}
#[derive(Component)]
pub struct WindowColor(Color);
#[derive(Component)]
struct LaserTimer {
timer: Timer,
}
// fn receive_tracks(mut commands: Commands){
// }
@ -150,14 +161,17 @@ fn update(
mut commands: Commands,
keys: Res<ButtonInput<KeyCode>>,
draws: Query<(&Draw, Option<&WindowColor>)>,
lasers: Query<&LaserApi>,
mut lasers: Query<(&mut LaserApi, &mut LaserTimer)>,
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
*count += 1;
// We need a render layer to make sure we only render the camera for this window
let layer = RenderLayers::layer(*count);
// Spawn a new window with a unique title, resolution, and background color
let entity = commands
.spawn((
@ -179,6 +193,20 @@ fn update(
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() {
if let Some(window_color) = window_color {
draw.background().color(window_color.0);
@ -188,13 +216,8 @@ fn update(
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);
}
}
}