optimize mouse events, refactoring

This commit is contained in:
siikamiika 2018-11-14 01:55:09 +02:00
parent 779947195a
commit a5de77f321
2 changed files with 70 additions and 29 deletions

View File

@ -2,6 +2,7 @@ use std::thread;
use std::time::Duration; use std::time::Duration;
use evdev_rs::util::event_code_to_int; use evdev_rs::util::event_code_to_int;
use evdev_rs::enums::EventType::EV_REL;
use crossbeam::crossbeam_channel::{unbounded, Select, Receiver, Sender}; use crossbeam::crossbeam_channel::{unbounded, Select, Receiver, Sender};
@ -27,42 +28,81 @@ pub fn create_evdev_thread(device_path: &str) -> (String, Receiver<ThreadInputEv
// sleep for testing purposes // sleep for testing purposes
thread::sleep(Duration::from_secs(1)); thread::sleep(Duration::from_secs(1));
// cache mouse movement before consuming all events
let mut mouse_move = vec![0, 0];
loop { loop {
// check for stop requests if stop_requested(&recv_stop_channel) {
let mut sel = Select::new(); continue;
// create stop channel receive operation
let oper1 = sel.recv(&recv_stop_channel);
// try to select from stop channel
let oper = sel.try_select();
match oper {
// no stop requests
Err(_) => (),
// stop request received, break out of the loop
Ok(oper) => match oper.index() {
i if i == oper1 => {
assert_eq!(oper.recv(&recv_stop_channel), Ok(true));
break;
},
// shouldn't happen
_ => (),
},
} }
// read next input event loop {
let event = dev.device.next_event(evdev_rs::NORMAL | evdev_rs::BLOCKING); // block before starting while loop again
match event { let mut first = true;
// send input event to event channel let mut event = dev.device.next_event(evdev_rs::NORMAL | evdev_rs::BLOCKING);
Ok(e) => send_event_channel.send( // pending events not required for first round
ThreadInputEvent { while first || dev.device.has_event_pending() {
typ: e.1.event_type as u32, first = false;
code: event_code_to_int(&e.1.event_code).1, match event {
value: e.1.value, // send input event to event channel
Ok(e) => {
let e = ThreadInputEvent {
typ: e.1.event_type as u32,
code: event_code_to_int(&e.1.event_code).1,
value: e.1.value,
};
if e.typ == 2 && e.code <= 1 {
mouse_move[e.code as usize] += e.value;
} else {
send_event_channel.send(e).unwrap();
}
},
Err(_) => (),
} }
).unwrap(), // read next input event
Err(_) => (), event = dev.device.next_event(evdev_rs::NORMAL | evdev_rs::BLOCKING);
}
// combined mouse event
send_combined_mouse_move(&mut mouse_move, &send_event_channel);
// save cpu by sleeping after consuming all events
thread::sleep(Duration::from_millis(5));
} }
} }
}); });
(return_device_path, recv_event_channel, send_stop_channel) (return_device_path, recv_event_channel, send_stop_channel)
} }
fn stop_requested(chan: &Receiver<bool>) -> bool {
// check for stop requests
let mut sel = Select::new();
// create stop channel receive operation
let oper1 = sel.recv(&chan);
// try to select from stop channel
let oper = sel.try_select();
match oper {
// no stop requests
Err(_) => false,
// stop request received, break out of the loop
Ok(oper) => match oper.index() {
i if i == oper1 => {
oper.recv(&chan).unwrap()
},
// shouldn't happen
_ => false,
},
}
}
fn send_combined_mouse_move(mouse_move: &mut Vec<i32>, chan: &Sender<ThreadInputEvent>) {
// REL_X..=REL_Y
for code in 0..=1 {
if mouse_move[code] != 0 {
chan.send(ThreadInputEvent {
typ: EV_REL as u32,
code: code as u32,
value: mouse_move[code],
}).unwrap();
mouse_move[code] = 0;
}
}
}

View File

@ -2,6 +2,7 @@ extern crate uinput;
extern crate evdev_rs; extern crate evdev_rs;
extern crate crossbeam; extern crate crossbeam;
use std::thread;
use std::env::args; use std::env::args;
use std::time::Duration; use std::time::Duration;
use std::collections::HashMap; use std::collections::HashMap;