Compare commits

..

No commits in common. "386e632efb5a7eaef272b00a739cbda614fe70cb" and "f6b9c50e7ebb7b330037ab8aef3e2d58e7eef7aa" have entirely different histories.

10 changed files with 82 additions and 93 deletions

1
.gitignore vendored
View file

@ -1,4 +1,3 @@
/target /target
settings.toml settings.toml
.direnv/* .direnv/*
logs/*

View file

@ -1,4 +1,4 @@
camera_ip = "localhost" camera_ip = "10.0.0.33"
camera_port = 8765 camera_port = 8765
tracker_ip = "localhost" tracker_ip = "localhost"
tracker_port = 6543 tracker_port = 6543

View file

@ -95,7 +95,7 @@ impl<'a> CoordState<'a> {
this this
} }
#[instrument(skip(self))] #[instrument]
pub async fn socket_send(&mut self, message: Message) { pub async fn socket_send(&mut self, message: Message) {
if let Some(mut socket) = self.sck_outbound.take() { if let Some(mut socket) = self.sck_outbound.take() {
if let Err(e) = socket.send(message).await { if let Err(e) = socket.send(message).await {

View file

@ -48,7 +48,7 @@ pub enum ApplicationEvent {
EnableAutomatic(bool), EnableAutomatic(bool),
} }
#[instrument(skip_all)] #[instrument]
pub async fn start_coordinator( pub async fn start_coordinator(
// Main_Event_Channel // Main_Event_Channel
mec: Receiver<ApplicationEvent>, mec: Receiver<ApplicationEvent>,

View file

@ -23,7 +23,7 @@ use super::{
SocketState, SocketState,
}; };
#[instrument(skip_all)] #[instrument]
pub async fn remote_video_loop( pub async fn remote_video_loop(
conn_string: String, conn_string: String,
appsink: Arc<Mutex<AppSink>>, appsink: Arc<Mutex<AppSink>>,

View file

@ -35,7 +35,7 @@ impl FilterFn for UnknownSlayer {
} }
} }
#[tracing::instrument(skip(tx))] #[tracing::instrument]
pub async fn joystick_loop(tx: Sender<ApplicationEvent>, is_alive: Arc<AtomicBool>) { pub async fn joystick_loop(tx: Sender<ApplicationEvent>, is_alive: Arc<AtomicBool>) {
let mut gilrs = GilrsBuilder::new().set_update_state(false).build().unwrap(); let mut gilrs = GilrsBuilder::new().set_update_state(false).build().unwrap();

View file

@ -3,6 +3,8 @@ use gtk::{glib, Application};
use std::{env, sync::Arc}; use std::{env, sync::Arc};
use tokio::{runtime, sync::RwLock}; use tokio::{runtime, sync::RwLock};
use tracing::{self, info, Level}; use tracing::{self, info, Level};
#[cfg(not(debug_assertions))]
use tracing_appender;
use tracing_subscriber; use tracing_subscriber;
use crate::config::{load_config, AppConfig}; use crate::config::{load_config, AppConfig};
@ -19,14 +21,23 @@ fn main() -> glib::ExitCode {
// set the environment var to make gtk use window's default action bar // set the environment var to make gtk use window's default action bar
env::set_var("gtk_csd", "0"); env::set_var("gtk_csd", "0");
// #[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
let file_appender = tracing_appender::rolling::daily(".\\logs", "camera-controller"); {
let (non_blocking, _gaurd) = tracing_appender::non_blocking(file_appender); let file_appender = tracing_appender::rolling::daily(".", "joystick-log");
tracing_subscriber::fmt() let (non_blocking, _gaurd) = tracing_appender::non_blocking(file_appender);
.with_writer(non_blocking) tracing_subscriber::fmt()
.with_max_level(tracing::Level::DEBUG) .with_writer(non_blocking)
.with_ansi(false) .with_max_level(tracing::Level::DEBUG)
.init(); .init();
}
#[cfg(debug_assertions)]
{
tracing_subscriber::fmt()
// .compact()
.pretty()
.with_max_level(tracing::Level::DEBUG)
.init();
}
let span = tracing::span!(Level::TRACE, "main"); let span = tracing::span!(Level::TRACE, "main");
let _enter = span.enter(); let _enter = span.enter();

View file

@ -37,7 +37,7 @@ pub struct TrackerState {
pub identity_boxes: Vec<NormalizedBoxCoords>, pub identity_boxes: Vec<NormalizedBoxCoords>,
} }
#[instrument(skip(rt, mec))] #[instrument]
pub async fn start_socketserver( pub async fn start_socketserver(
rt: Handle, rt: Handle,
mec: Sender<ApplicationEvent>, mec: Sender<ApplicationEvent>,
@ -70,7 +70,7 @@ pub async fn start_socketserver(
connection_state.is_connected.store(false, Ordering::SeqCst); connection_state.is_connected.store(false, Ordering::SeqCst);
} }
#[instrument(skip(stream, mec))] #[instrument]
async fn accept_connection( async fn accept_connection(
peer: SocketAddr, peer: SocketAddr,
stream: TcpStream, stream: TcpStream,
@ -85,7 +85,7 @@ async fn accept_connection(
} }
} }
#[instrument(skip(stream, mec))] #[instrument]
async fn handle_connection( async fn handle_connection(
peer: SocketAddr, peer: SocketAddr,
stream: TcpStream, stream: TcpStream,

View file

@ -74,7 +74,7 @@ impl LiveViewPanel {
click_handler.connect_pressed(move |gesture, _id, x, y| { click_handler.connect_pressed(move |gesture, _id, x, y| {
gesture.set_state(gtk::EventSequenceState::Claimed); gesture.set_state(gtk::EventSequenceState::Claimed);
LiveViewPanel::click_gesture_callback(&handler_picture, &tracker_state, x, y) LiveViewPanel::gesture_callback(&handler_picture, &tracker_state, x, y)
}); });
overlay_box.add_controller(click_handler); overlay_box.add_controller(click_handler);
@ -101,7 +101,24 @@ impl LiveViewPanel {
} }
} }
fn click_gesture_callback( fn gesture_callback(
overlay: &Picture,
tracker_state: &Arc<Mutex<TrackerState>>,
x_coord: f64,
y_coord: f64,
) {
let x_size = overlay.size(gtk::Orientation::Horizontal);
let y_size = overlay.size(gtk::Orientation::Vertical);
let x_coord = x_coord as f32 / x_size as f32;
let y_coord = y_coord as f32 / y_size as f32;
if let Ok(mut ts) = tracker_state.lock() {
ts.highlighted_id = calc_box_under_mouse(&ts.identity_boxes, x_coord, y_coord);
}
}
fn motion_callback(
overlay: &Picture, overlay: &Picture,
tracker_state: &Arc<Mutex<TrackerState>>, tracker_state: &Arc<Mutex<TrackerState>>,
x_coord: f64, x_coord: f64,
@ -119,22 +136,6 @@ impl LiveViewPanel {
} }
} }
fn motion_callback(
overlay: &Picture,
tracker_state: &Arc<Mutex<TrackerState>>,
x_coord: f64,
y_coord: f64,
) {
let x_size = overlay.size(gtk::Orientation::Horizontal);
let y_size = overlay.size(gtk::Orientation::Vertical);
let x_coord = x_coord as f32 / x_size as f32;
let y_coord = y_coord as f32 / y_size as f32;
if let Ok(mut ts) = tracker_state.lock() {
ts.highlighted_id = calc_box_under_mouse(&ts.identity_boxes, x_coord, y_coord);
}
}
pub fn get_top_level(&self) -> &Box { pub fn get_top_level(&self) -> &Box {
&self.top_level &self.top_level
} }
@ -148,14 +149,10 @@ impl LiveViewPanel {
} }
} }
fn calc_box_under_mouse( fn calc_box_under_mouse(boxes: &Vec<NormalizedBoxCoords>, x_coord: f32, y_coord: f32) -> Option<u32> {
boxes: &Vec<NormalizedBoxCoords>,
x_coord: f32,
y_coord: f32,
) -> Option<u32> {
let mut mouse_over: Vec<NormalizedBoxCoords> = vec![]; let mut mouse_over: Vec<NormalizedBoxCoords> = vec![];
for nb in boxes.iter() { for nb in boxes.iter() {
if nb.x1 < x_coord as f32 if nb.x1 < x_coord as f32
&& nb.y1 < y_coord as f32 && nb.y1 < y_coord as f32
&& nb.x2 > x_coord as f32 && nb.x2 > x_coord as f32
@ -164,7 +161,11 @@ fn calc_box_under_mouse(
mouse_over.push(nb.clone()); mouse_over.push(nb.clone());
} }
} }
if mouse_over.len() > 1 { if mouse_over.len() == 1 {
// the length is one, why would the unwrap fail
let new_id = mouse_over.first().expect("Length one vec had no first");
return Some(new_id.id);
} else if mouse_over.len() > 1 {
let mut x_coords = mouse_over let mut x_coords = mouse_over
.iter() .iter()
.flat_map(|b| [b.x1, b.x2]) .flat_map(|b| [b.x1, b.x2])
@ -184,24 +185,28 @@ fn calc_box_under_mouse(
let overlap_area = let overlap_area =
(median_two_x[1] - median_two_x[0]) * (median_two_y[1] - median_two_y[0]); (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| { mouse_over.sort_by(|a, b| {
let result = ((a.area() - overlap_area) / a.area()) - ((b.area() - overlap_area) / b.area()); // a is valid for cutting in line if the
if 0.0001 > result && result > -0.0001 { // overlap area is greater than 75% of a's area
Ordering::Equal let a_overlap = overlap_area >= 0.75 * a.area();
} else if result > 0.0 { let b_overlap = overlap_area >= 0.75 * b.area();
Ordering::Greater
} else { match (a_overlap, b_overlap) {
Ordering::Less // if the areas are not valid for cutting in line or both are
// do the sorting based on the id, and let the hover affect
// force the user to decide
(true, true) | (false, false) => {
if a.id > b.id {
Ordering::Greater
} else {
Ordering::Less
}
}
(false, true) => Ordering::Less,
(true, false) => Ordering::Greater,
} }
}); });
} }
mouse_over mouse_over.iter().map(|x| x.id).collect::<Vec<u32>>().first().copied()
.iter()
.map(|x| x.id)
.collect::<Vec<u32>>()
.first()
.copied()
} }

View file

@ -216,31 +216,9 @@ pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Hand
id_label.set_text(id.to_string().as_str()); id_label.set_text(id.to_string().as_str());
} }
if let Some(mut ids) = ids { if let Some (ids) = ids {
let mut to_delete_indexes: Vec<u32> = vec![]; let old_len = items.n_items();
items.splice(0, old_len, &ids.iter().map(|x| x.as_str()).collect::<Vec<&str>>()[0..])
// 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 glib::ControlFlow::Continue
@ -350,10 +328,6 @@ fn draw_boxes(width: i32, height: i32, ctx: &Context, tracker_state: &Arc<Mutex<
ctx.set_source_rgb(0.0, 0.0, 1.0); 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);
}
let b = nb.into_relative(width, height); let b = nb.into_relative(width, height);
ctx.rectangle( ctx.rectangle(
b.x1 as f64, b.x1 as f64,