added some clear states (and bugs)

This commit is contained in:
Nickiel12 2024-06-01 10:41:01 -05:00
parent 386e632efb
commit 66acd4698f
9 changed files with 111 additions and 63 deletions

2
Cargo.lock generated
View file

@ -1153,7 +1153,7 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]] [[package]]
name = "joystick-controller-client" name = "joystick-controller-client"
version = "1.1.0" version = "2.0.0"
dependencies = [ dependencies = [
"async-channel", "async-channel",
"config", "config",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "joystick-controller-client" name = "joystick-controller-client"
version = "1.1.0" version = "2.0.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -36,7 +36,7 @@ impl TrackerMetrics {
for _ in 0..10 { for _ in 0..10 {
self.tracker_times.pop_front(); 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() { if let Ok(mut writer) = self.header_text.write() {
writer.clear(); writer.clear();
writer.push_str("Status: Disconnected"); writer.push_str("Status: Disconnected");

View file

@ -146,6 +146,24 @@ pub async fn remote_video_loop(
let mut tm = tracker_metrics.lock().await; let mut tm = tracker_metrics.lock().await;
tm.clear_times(); 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); socket_state.is_connected.store(false, Ordering::SeqCst);
} }

View file

@ -37,6 +37,17 @@ pub struct TrackerState {
pub identity_boxes: Vec<NormalizedBoxCoords>, pub identity_boxes: Vec<NormalizedBoxCoords>,
} }
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))] #[instrument(skip(rt, mec))]
pub async fn start_socketserver( pub async fn start_socketserver(
rt: Handle, rt: Handle,

View file

@ -24,6 +24,7 @@ pub struct ControlPanel {
pub current_id: Label, pub current_id: Label,
pub items: StringList, pub items: StringList,
pub list_view: ListView,
} }
#[derive(Debug)] #[derive(Debug)]
@ -51,7 +52,7 @@ impl ControlPanel {
.bind(&label, "label", Widget::NONE); .bind(&label, "label", Widget::NONE);
}); });
let items = StringList::new(&["item1", "item2", "item3"]); let items = StringList::new(&["Please connect automatic source"]);
let model = SingleSelection::builder() let model = SingleSelection::builder()
.model(&items) .model(&items)
@ -114,6 +115,7 @@ impl ControlPanel {
current_id, current_id,
items, items,
list_view,
} }
} }

View file

@ -187,7 +187,8 @@ fn calc_box_under_mouse(
// We want the one with the largest percentage of it's area as overlap // We want the one with the largest percentage of it's area as overlap
// to be the highlighted one // to be the highlighted one
mouse_over.sort_by(|a, b| { 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 { if 0.0001 > result && result > -0.0001 {
Ordering::Equal Ordering::Equal
} else if result > 0.0 { } else if result > 0.0 {
@ -195,7 +196,7 @@ fn calc_box_under_mouse(
} else { } else {
Ordering::Less Ordering::Less
} }
}); });
} }
mouse_over mouse_over

View file

@ -1,6 +1,6 @@
use std::fmt::Display; use std::fmt::Display;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::Instant; use std::time::{Duration, Instant};
use gtk::cairo::Context; use gtk::cairo::Context;
use gtk::gdk::Paintable; use gtk::gdk::Paintable;
@ -191,61 +191,73 @@ pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Hand
let items = control_panel.items.clone(); let items = control_panel.items.clone();
let id_label = control_panel.current_id.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( glib::timeout_add_local(Duration::from_millis(500), move || {
1, #[cfg(feature = "tracker-state-debug")]
glib::clone!(@strong items, @strong id_label => move || { debug!("Getting lock on tracker state for checking identity boxes");
#[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 // don't update the stringlist until after letting go of the tracker state
// due to async interweaving causing a mutex deadlock // due to async interweaving causing a mutex deadlock
let mut ids: Option<Vec<String>> = None; let mut ids: Option<Vec<String>> = None;
let mut current_id: Option<u32> = None; let mut current_id: u32 = 0;
if let Ok(ts) = tracker_state.lock() { if let Ok(ts) = tracker_state.lock() {
current_id = Some(ts.tracking_id); current_id = ts.tracking_id;
if ts.update_ids { if ts.update_ids {
ids = Some(ts.identity_boxes ids = Some(ts.identity_boxes.iter().map(|t| t.id.to_string()).collect());
.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<u32> = 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 !ids.contains(&item) {
to_delete_indexes.push(i);
if let Some(id) = current_id { } else {
id_label.set_text(id.to_string().as_str()); if let Some(pos) = ids.iter().position(|x| **x == item) {
} ids.remove(pos);
if let Some(mut ids) = ids {
let mut to_delete_indexes: Vec<u32> = 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);
}
} }
} }
// 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::<Vec<&str>>()[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::<Vec<&str>>()[0..],
)
}
glib::ControlFlow::Continue
});
let tracker_status_label = liveview_panel.tracker_status_label.clone(); let tracker_status_label = liveview_panel.tracker_status_label.clone();
let tracker_enable_toggle = control_panel let tracker_enable_toggle = control_panel
@ -259,18 +271,21 @@ pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Hand
if reader.contains("Failed") || reader.contains("Disconnected") { if reader.contains("Failed") || reader.contains("Disconnected") {
tracker_status_label.set_css_classes(&["NoConnection"]); 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_active(false);
tracker_enable_toggle.set_sensitive(true);
} else if reader.contains("Degraded") || reader.contains("Connecting") { } else if reader.contains("Degraded") || reader.contains("Connecting") {
tracker_status_label.set_css_classes(&["LoadingConnection"]); 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_active(false);
tracker_enable_toggle.set_sensitive(false);
} else if reader.contains("Nominal") { } else if reader.contains("Nominal") {
tracker_status_label.set_css_classes(&["YesConnection"]); 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_active(true);
tracker_enable_toggle.set_sensitive(true);
} }
glib::ControlFlow::Continue glib::ControlFlow::Continue
} else { } else {
@ -290,7 +305,7 @@ pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Hand
} }
GuiUpdate::SocketConnected => { GuiUpdate::SocketConnected => {
control_panel.connection_buttons.camera_connection.set_sensitive(true); 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_label("Connected");
liveview_panel.cam_status_label.set_css_classes(&["YesConnection"]); liveview_panel.cam_status_label.set_css_classes(&["YesConnection"]);
@ -306,7 +321,7 @@ pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Hand
}, },
GuiUpdate::SocketDisconnected => { GuiUpdate::SocketDisconnected => {
control_panel.connection_buttons.camera_connection.set_sensitive(true); 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_label("Not Connected to Camera");
liveview_panel.cam_status_label.set_css_classes(&["NoConnection"]); 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<Mutex<
#[cfg(feature = "tracker-state-debug")] #[cfg(feature = "tracker-state-debug")]
debug!("Getting tracker state for drawing boxes"); debug!("Getting tracker state for drawing boxes");
if let Ok(ts) = tracker_state.lock() { if let Ok(ts) = tracker_state.lock() {
println!("ts currently tracking: {}", ts.tracking_id);
let active = ts.tracking_id; let active = ts.tracking_id;
let highlighted_id = ts.highlighted_id.unwrap_or(0); let highlighted_id = ts.highlighted_id.unwrap_or(0);
for nb in ts.identity_boxes.iter() { for nb in ts.identity_boxes.iter() {