From 66acd4698fcc997099ebc1ddc6f8e5ddd0e3579c Mon Sep 17 00:00:00 2001 From: Nickiel12 <35903114+Nickiel12@users.noreply.github.com> Date: Sat, 1 Jun 2024 10:41:01 -0500 Subject: [PATCH] added some clear states (and bugs) --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/coordinator/perf_state.rs | 2 +- src/coordinator/remote_video_processor.rs | 18 ++++ src/main.rs | 2 +- src/remote_sources/mod.rs | 11 ++ src/ui/control_panel.rs | 4 +- src/ui/liveview_panel.rs | 7 +- src/ui/mod.rs | 126 ++++++++++++---------- 9 files changed, 111 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a314f5..172c5c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1153,7 +1153,7 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "joystick-controller-client" -version = "1.1.0" +version = "2.0.0" dependencies = [ "async-channel", "config", diff --git a/Cargo.toml b/Cargo.toml index c6f7d37..d0a0133 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "joystick-controller-client" -version = "1.1.0" +version = "2.0.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/coordinator/perf_state.rs b/src/coordinator/perf_state.rs index 16a3f5b..c45c005 100644 --- a/src/coordinator/perf_state.rs +++ b/src/coordinator/perf_state.rs @@ -36,7 +36,7 @@ impl TrackerMetrics { for _ in 0..10 { self.tracker_times.pop_front(); } - self.insert_time(Duration::new(0, 0)); + // self.insert_time(Duration::new(0, 0)); if let Ok(mut writer) = self.header_text.write() { writer.clear(); writer.push_str("Status: Disconnected"); diff --git a/src/coordinator/remote_video_processor.rs b/src/coordinator/remote_video_processor.rs index 2a35602..a620e08 100644 --- a/src/coordinator/remote_video_processor.rs +++ b/src/coordinator/remote_video_processor.rs @@ -146,6 +146,24 @@ pub async fn remote_video_loop( let mut tm = tracker_metrics.lock().await; tm.clear_times(); } + { + if let Ok(mut ts) = tracker_state.lock() { + ts.clear(); + } + // This message forces a redraw after clearing the queue + if let Err(e) = to_mec + .send(ApplicationEvent::MoveEvent( + crate::coordinator::MoveEvent { x: 0, y: 0 }, + crate::coordinator::ConnectionType::Automated, + )) + .await + { + error!( + "Error sending message to MEC during shutdown of tracker thread: {}", + e + ); + } + } socket_state.is_connected.store(false, Ordering::SeqCst); } diff --git a/src/main.rs b/src/main.rs index cb746fb..0f9d637 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ const APP_ID: &str = "net.nickiel.joystick-controller-client"; fn main() -> glib::ExitCode { // set the environment var to make gtk use window's default action bar env::set_var("gtk_csd", "0"); - + // #[cfg(not(debug_assertions))] let file_appender = tracing_appender::rolling::daily(".\\logs", "camera-controller"); let (non_blocking, _gaurd) = tracing_appender::non_blocking(file_appender); diff --git a/src/remote_sources/mod.rs b/src/remote_sources/mod.rs index a81d0ef..c4bc86f 100644 --- a/src/remote_sources/mod.rs +++ b/src/remote_sources/mod.rs @@ -37,6 +37,17 @@ pub struct TrackerState { pub identity_boxes: Vec, } +impl TrackerState { + pub fn clear(&mut self) { + self.tracking_id = 0; + self.highlighted_id = None; + self.last_detect = Instant::now(); + self.enabled = false; + self.update_ids = false; + self.identity_boxes.clear(); + } +} + #[instrument(skip(rt, mec))] pub async fn start_socketserver( rt: Handle, diff --git a/src/ui/control_panel.rs b/src/ui/control_panel.rs index 93b0265..ae344dd 100644 --- a/src/ui/control_panel.rs +++ b/src/ui/control_panel.rs @@ -24,6 +24,7 @@ pub struct ControlPanel { pub current_id: Label, pub items: StringList, + pub list_view: ListView, } #[derive(Debug)] @@ -51,7 +52,7 @@ impl ControlPanel { .bind(&label, "label", Widget::NONE); }); - let items = StringList::new(&["item1", "item2", "item3"]); + let items = StringList::new(&["Please connect automatic source"]); let model = SingleSelection::builder() .model(&items) @@ -114,6 +115,7 @@ impl ControlPanel { current_id, items, + list_view, } } diff --git a/src/ui/liveview_panel.rs b/src/ui/liveview_panel.rs index 24038fc..f1ff004 100644 --- a/src/ui/liveview_panel.rs +++ b/src/ui/liveview_panel.rs @@ -183,11 +183,12 @@ fn calc_box_under_mouse( let overlap_area = (median_two_x[1] - median_two_x[0]) * (median_two_y[1] - median_two_y[0]); - + // We want the one with the largest percentage of it's area as overlap // to be the highlighted one mouse_over.sort_by(|a, b| { - let result = ((a.area() - overlap_area) / a.area()) - ((b.area() - overlap_area) / b.area()); + let result = + ((a.area() - overlap_area) / a.area()) - ((b.area() - overlap_area) / b.area()); if 0.0001 > result && result > -0.0001 { Ordering::Equal } else if result > 0.0 { @@ -195,7 +196,7 @@ fn calc_box_under_mouse( } else { Ordering::Less } - }); + }); } mouse_over diff --git a/src/ui/mod.rs b/src/ui/mod.rs index ca07635..03a9051 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,6 +1,6 @@ use std::fmt::Display; use std::sync::{Arc, Mutex}; -use std::time::Instant; +use std::time::{Duration, Instant}; use gtk::cairo::Context; use gtk::gdk::Paintable; @@ -191,61 +191,73 @@ pub fn build_ui(app: &Application, config: Arc>, runtime: Hand let items = control_panel.items.clone(); let id_label = control_panel.current_id.clone(); + let model = control_panel + .list_view + .model() + .expect("The list view should have a model!"); - glib::timeout_add_seconds_local( - 1, - glib::clone!(@strong items, @strong id_label => move || { - #[cfg(feature = "tracker-state-debug")] - debug!("Getting lock on tracker state for checking identity boxes"); + glib::timeout_add_local(Duration::from_millis(500), move || { + #[cfg(feature = "tracker-state-debug")] + debug!("Getting lock on tracker state for checking identity boxes"); - // don't update the stringlist until after letting go of the tracker state - // due to async interweaving causing a mutex deadlock - let mut ids: Option> = None; - let mut current_id: Option = None; - if let Ok(ts) = tracker_state.lock() { - current_id = Some(ts.tracking_id); - if ts.update_ids { - ids = Some(ts.identity_boxes - .iter() - .map(|t| t.id.to_string()) - .collect()); + // don't update the stringlist until after letting go of the tracker state + // due to async interweaving causing a mutex deadlock + let mut ids: Option> = None; + let mut current_id: u32 = 0; + if let Ok(ts) = tracker_state.lock() { + current_id = ts.tracking_id; + if ts.update_ids { + ids = Some(ts.identity_boxes.iter().map(|t| t.id.to_string()).collect()); + } + } + + if current_id > 0 { + id_label.set_text(current_id.to_string().as_str()); + } + + let current_id: String = current_id.to_string(); + + if let Some(mut ids) = ids { + let mut active_index = 0; + let mut to_delete_indexes: Vec = vec![]; + + // find all indexes where matching item does not exist in + // the ids, list, and remove all items in the ids list + // that already exists in the stringList + for i in 0..items.n_items() { + let item = items.string(i).unwrap_or("Empty".into()).to_string(); + if item == current_id { + active_index = i; } - } - - if let Some(id) = current_id { - id_label.set_text(id.to_string().as_str()); - } - - if let Some(mut ids) = ids { - let mut to_delete_indexes: Vec = vec![]; - - // find all indexes where matching item does not exist in - // the ids, list, and remove all items in the ids list - // that already exists in the stringList - for i in 0..items.n_items() { - let item = items.string(i).unwrap_or("Empty".into()).to_string(); - if !ids.contains(&item) { - to_delete_indexes.push(i); - } else { - if let Some(pos) = ids.iter().position(|x| **x == item) { - ids.remove(pos); - } + if !ids.contains(&item) { + to_delete_indexes.push(i); + } else { + if let Some(pos) = ids.iter().position(|x| **x == item) { + ids.remove(pos); } } - - // invert the order so we don't have to adjust after each deletion - to_delete_indexes.sort(); - to_delete_indexes.reverse(); - - to_delete_indexes.iter().for_each(|x| { - items.remove(*x); - }); - items.splice(items.n_items(), 0, &ids.iter().map(|x| x.as_str()).collect::>()[0..]) } - glib::ControlFlow::Continue - }), - ); + if active_index > 0 { + model.select_item(active_index, true); + } + + // invert the order so we don't have to adjust after each deletion + to_delete_indexes.sort(); + to_delete_indexes.reverse(); + + to_delete_indexes.iter().for_each(|x| { + items.remove(*x); + }); + items.splice( + items.n_items(), + 0, + &ids.iter().map(|x| x.as_str()).collect::>()[0..], + ) + } + + glib::ControlFlow::Continue + }); let tracker_status_label = liveview_panel.tracker_status_label.clone(); let tracker_enable_toggle = control_panel @@ -259,18 +271,21 @@ pub fn build_ui(app: &Application, config: Arc>, runtime: Hand if reader.contains("Failed") || reader.contains("Disconnected") { tracker_status_label.set_css_classes(&["NoConnection"]); - tracker_enable_toggle.set_label("Press to Connect Tracker"); + tracker_enable_toggle.set_label("Connect to Tracker Computer"); tracker_enable_toggle.set_active(false); + tracker_enable_toggle.set_sensitive(true); } else if reader.contains("Degraded") || reader.contains("Connecting") { tracker_status_label.set_css_classes(&["LoadingConnection"]); - tracker_enable_toggle.set_label("Press to Connect"); + tracker_enable_toggle.set_label("Please Wait"); tracker_enable_toggle.set_active(false); + tracker_enable_toggle.set_sensitive(false); } else if reader.contains("Nominal") { tracker_status_label.set_css_classes(&["YesConnection"]); - tracker_enable_toggle.set_label("Press to Disconnect"); + tracker_enable_toggle.set_label("Disconnect Tracker Computer"); tracker_enable_toggle.set_active(true); + tracker_enable_toggle.set_sensitive(true); } glib::ControlFlow::Continue } else { @@ -290,7 +305,7 @@ pub fn build_ui(app: &Application, config: Arc>, runtime: Hand } GuiUpdate::SocketConnected => { control_panel.connection_buttons.camera_connection.set_sensitive(true); - control_panel.connection_buttons.camera_connection.set_label("Press to Disconnect"); + control_panel.connection_buttons.camera_connection.set_label("Disconnect Camera"); liveview_panel.cam_status_label.set_label("Connected"); liveview_panel.cam_status_label.set_css_classes(&["YesConnection"]); @@ -306,7 +321,7 @@ pub fn build_ui(app: &Application, config: Arc>, runtime: Hand }, GuiUpdate::SocketDisconnected => { control_panel.connection_buttons.camera_connection.set_sensitive(true); - control_panel.connection_buttons.camera_connection.set_label("Press to Connect to Camera"); + control_panel.connection_buttons.camera_connection.set_label("Connect to Camera"); liveview_panel.cam_status_label.set_label("Not Connected to Camera"); liveview_panel.cam_status_label.set_css_classes(&["NoConnection"]); @@ -339,6 +354,7 @@ fn draw_boxes(width: i32, height: i32, ctx: &Context, tracker_state: &Arc