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]]
name = "joystick-controller-client"
version = "1.1.0"
version = "2.0.0"
dependencies = [
"async-channel",
"config",

View file

@ -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

View file

@ -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");

View file

@ -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);
}

View file

@ -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);

View file

@ -37,6 +37,17 @@ pub struct TrackerState {
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))]
pub async fn start_socketserver(
rt: Handle,

View file

@ -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,
}
}

View file

@ -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

View file

@ -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<RwLock<AppConfig>>, 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<Vec<String>> = None;
let mut current_id: Option<u32> = 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<Vec<String>> = 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<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 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<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);
}
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_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") {
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<RwLock<AppConfig>>, 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<RwLock<AppConfig>>, 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<Mutex<
#[cfg(feature = "tracker-state-debug")]
debug!("Getting tracker state for drawing boxes");
if let Ok(ts) = tracker_state.lock() {
println!("ts currently tracking: {}", ts.tracking_id);
let active = ts.tracking_id;
let highlighted_id = ts.highlighted_id.unwrap_or(0);
for nb in ts.identity_boxes.iter() {
@ -349,7 +365,7 @@ fn draw_boxes(width: i32, height: i32, ctx: &Context, tracker_state: &Arc<Mutex<
} else {
ctx.set_source_rgb(0.0, 0.0, 1.0);
}
if nb.id == active && nb.id == highlighted_id {
ctx.set_source_rgb(1.0, 1.0, 0.0);
}