laserspace/src/trap/zmqplugin.rs
2025-04-10 16:22:46 +02:00

101 lines
3.2 KiB
Rust

use zmq::Socket;
use serde_json::Result;
use bevy::{ecs::system::SystemState, prelude::*};
use super::tracks::{Frame, Track, TrackBundle};
// use trap::{Frame, Track, TrackBundle};
// use tracks::Frame;
// Because of world.insert_non_send_resource, this is an exclusive system
// see: https://bevy-cheatbook.github.io/programming/exclusive.html
fn setup_zmq(world: &mut World, params: &mut SystemState<Res<ZmqSettings>>) {
let settings = params.get(world);
let url = &settings.url;
let context = zmq::Context::new();
let subscriber = context.socket(zmq::SUB).unwrap();
assert!(subscriber.connect(url).is_ok());
// let filter = "10001";
let filter = &settings.filter; //"msgs";
assert!(subscriber.set_subscribe(filter.as_bytes()).is_ok());
world.insert_non_send_resource(subscriber);
// world.query::<>()
}
fn receive_zmq_messsages(mut commands: Commands, subscriber: NonSend<Socket>, mut tracks_q: Query<&mut Track>) {
let mut items = [
subscriber.as_poll_item(zmq::POLLIN)
];
let _nr = zmq::poll(&mut items, 0).unwrap();
if items[0].is_readable() {
let json = subscriber.recv_string(0).unwrap().unwrap();
// dbg!(&json[4..]);
// let msg: Frame = serde_json::from_str(&json[4..]).expect("No valid json?");
let res: Result<Frame> = serde_json::from_str(&json);
let msg = match res {
Ok(msg) => msg, // if Ok(255), set x to 255
Err(_e) => {
println!("No valid json? {json}");
return
}, // if Err("some message"), panic with error message "some message"
};
for (_track_id, new_track) in msg.tracks.into_iter() {
let mut done = false;
for mut track in tracks_q.iter_mut() {
if track.track_id == new_track.track_id {
// track.nr += 1;
track.history = new_track.history.clone();
track.predictor_history = new_track.predictor_history.clone();
track.predictions = new_track.predictions.clone();
// TODO match lenghts of points and drawn_points
done = true;
// dbg!(&track);
break
}
}
if !done {
// CREATE
// let track = Track{
// id: json.clone(),
// nr: 0,
// points: Vec::new()
// };
dbg!(&new_track.predictor_history);
commands.spawn(TrackBundle::from(new_track));
// commands.spawn(new_track);
}
}
}
}
#[derive(Resource)]
struct ZmqSettings {
url: String,
filter: String
}
pub struct ZmqPlugin {
pub url: String,
pub filter: String
}
impl Plugin for ZmqPlugin {
fn build(&self, app: &mut App) {
let settings = ZmqSettings{
url: self.url.clone(),
filter: self.filter.clone()
};
app
.insert_resource(settings)
.add_systems(Startup, setup_zmq)
.add_systems(Update, receive_zmq_messsages);
}
}