This commit is contained in:
4yn
2022-02-07 10:10:36 +08:00
parent a5c89f00cb
commit 98509250d6
14 changed files with 199 additions and 53 deletions

View File

@@ -140,9 +140,12 @@ fn main() {
let manager_clone = Arc::clone(&manager);
app.listen_global("queryState", move |_| {
// app_handle.emit_all("showState", "@@@");
let snapshot = {
let (snapshot, timer) = {
let manager_handle = manager_clone.lock().unwrap();
manager_handle.try_get_state().map(|x| x.snapshot())
(
manager_handle.try_get_state().map(|x| x.snapshot()),
manager_handle.get_timer_state(),
)
};
match snapshot {
Some(snapshot) => {
@@ -150,6 +153,8 @@ fn main() {
}
_ => {}
}
app_handle.emit_all("showTimerState", timer).ok();
});
// Config set event

View File

@@ -1,4 +1,6 @@
use atomic_float::AtomicF64;
use log::info;
use std::sync::{atomic::Ordering, Arc};
use crate::slider_io::{
brokenithm::BrokenithmJob,
@@ -7,6 +9,7 @@ use crate::slider_io::{
device::HidDeviceJob,
led::LedJob,
output::OutputJob,
utils::LoopTimer,
worker::{AsyncWorker, ThreadWorker},
};
@@ -18,6 +21,7 @@ pub struct Context {
brokenithm_worker: Option<AsyncWorker>,
output_worker: Option<ThreadWorker>,
led_worker: Option<ThreadWorker>,
timers: Vec<(&'static str, Arc<AtomicF64>)>,
}
impl Context {
@@ -28,6 +32,7 @@ impl Context {
info!("LED config {:?}", config.led_mode);
let state = FullState::new();
let mut timers = vec![];
let (device_worker, brokenithm_worker) = match &config.device_mode {
DeviceMode::None => (None, None),
@@ -42,26 +47,41 @@ impl Context {
)),
),
_ => (
Some(ThreadWorker::new(
"device",
HidDeviceJob::from_config(&state, &config.device_mode),
)),
{
let timer = LoopTimer::new();
timers.push(("d", timer.fork()));
Some(ThreadWorker::new(
"device",
HidDeviceJob::from_config(&state, &config.device_mode),
timer,
))
},
None,
),
};
let output_worker = match &config.output_mode {
OutputMode::None => None,
_ => Some(ThreadWorker::new(
"output",
OutputJob::new(&state, &config.output_mode),
)),
_ => {
let timer = LoopTimer::new();
timers.push(("o", timer.fork()));
Some(ThreadWorker::new(
"output",
OutputJob::new(&state, &config.output_mode),
timer,
))
}
};
let led_worker = match &config.led_mode {
LedMode::None => None,
_ => Some(ThreadWorker::new(
"led",
LedJob::new(&state, &config.led_mode),
)),
_ => {
let timer = LoopTimer::new();
timers.push(("l", timer.fork()));
Some(ThreadWorker::new(
"led",
LedJob::new(&state, &config.led_mode),
timer,
))
}
};
Self {
@@ -71,10 +91,20 @@ impl Context {
brokenithm_worker,
output_worker,
led_worker,
timers,
}
}
pub fn clone_state(&self) -> FullState {
self.state.clone()
}
pub fn timer_state(&self) -> String {
self
.timers
.iter()
.map(|(s, f)| format!("{}:{:.1}/s", s, f.load(Ordering::SeqCst)))
.collect::<Vec<String>>()
.join(" ")
}
}

View File

@@ -101,9 +101,9 @@ impl HidDeviceJob {
.take(31)
.zip(led_state.led_state.chunks(3).rev())
{
buf_chunk[0] = state_chunk[2];
buf_chunk[0] = state_chunk[1];
buf_chunk[1] = state_chunk[0];
buf_chunk[2] = state_chunk[1];
buf_chunk[2] = state_chunk[2];
}
buf.data[96..240].fill(0);
},
@@ -139,9 +139,9 @@ impl HidDeviceJob {
.take(31)
.zip(led_state.led_state.chunks(3).rev())
{
buf_chunk[0] = state_chunk[2];
buf_chunk[0] = state_chunk[1];
buf_chunk[1] = state_chunk[0];
buf_chunk[2] = state_chunk[1];
buf_chunk[2] = state_chunk[2];
}
buf.data[96..240].fill(0);
},
@@ -224,9 +224,10 @@ impl ThreadJob for HidDeviceJob {
}
}
fn tick(&mut self) {
fn tick(&mut self) -> bool {
// Input loop
let handle = self.handle.as_mut().unwrap();
let mut work = false;
{
let res = handle
@@ -239,6 +240,7 @@ impl ThreadJob for HidDeviceJob {
self.read_buf.len = res;
// debug!("{:?}", self.read_buf.slice());
if self.read_buf.len != 0 {
work = true;
let mut controller_state_handle = self.state.controller_state.lock().unwrap();
(self.read_callback)(&self.read_buf, controller_state_handle.deref_mut());
}
@@ -267,12 +269,13 @@ impl ThreadJob for HidDeviceJob {
})
.unwrap_or(0);
if res == self.led_buf.len + 1 {
work = true;
self.led_buf.len = 0;
}
}
}
// thread::sleep(Duration::from_millis(10));
work
}
fn teardown(&mut self) {

View File

@@ -174,7 +174,7 @@ impl ThreadJob for LedJob {
}
}
fn tick(&mut self) {
fn tick(&mut self) -> bool {
let mut flat_controller_state: Option<Vec<bool>> = None;
let mut serial_buffer: Option<Buffer> = None;
@@ -217,7 +217,10 @@ impl ThreadJob for LedJob {
led_state_handle.deref_mut(),
);
}
thread::sleep(Duration::from_millis(30));
// thread::sleep(Duration::from_millis(30));
spin_sleep::sleep(Duration::from_millis(30));
true
}
fn teardown(&mut self) {}

View File

@@ -14,6 +14,7 @@ use super::controller_state::FullState;
pub struct Manager {
state: Arc<Mutex<Option<FullState>>>,
context: Arc<Mutex<Option<Context>>>,
join_handle: Option<JoinHandle<()>>,
tx_config: mpsc::UnboundedSender<Config>,
tx_stop: Option<oneshot::Sender<()>>,
@@ -70,6 +71,7 @@ impl Manager {
Self {
state,
context,
join_handle: Some(join_handle),
tx_config,
tx_stop: Some(tx_stop),
@@ -84,6 +86,14 @@ impl Manager {
let state_handle = self.state.lock().unwrap();
state_handle.as_ref().map(|x| x.clone())
}
pub fn get_timer_state(&self) -> String {
let context_handle = self.context.lock().unwrap();
context_handle
.as_ref()
.map(|context| context.timer_state())
.unwrap_or("".to_string())
}
}
impl Drop for Manager {

View File

@@ -50,7 +50,7 @@ impl ThreadJob for OutputJob {
true
}
fn tick(&mut self) {
fn tick(&mut self) -> bool {
let flat_controller_state: Vec<bool>;
{
let controller_state_handle = self.state.controller_state.lock().unwrap();
@@ -58,7 +58,10 @@ impl ThreadJob for OutputJob {
}
self.handler.tick(&flat_controller_state);
thread::sleep(Duration::from_millis(self.t));
// thread::sleep(Duration::from_millis(self.t));
spin_sleep::sleep(Duration::from_millis(self.t));
true
}
fn teardown(&mut self) {

View File

@@ -1,4 +1,10 @@
use std::{error::Error, fmt};
use atomic_float::AtomicF64;
use std::{
error::Error,
fmt,
sync::{atomic::Ordering, Arc},
time::{Duration, Instant},
};
pub struct Buffer {
pub data: [u8; 256],
@@ -44,3 +50,45 @@ pub fn list_ips() -> Result<Vec<String>, Box<dyn Error>> {
Ok(ips)
}
pub struct LoopTimer {
cap: usize,
cur: usize,
buf: Vec<Instant>,
freq: Arc<AtomicF64>,
}
impl LoopTimer {
pub fn new() -> Self {
Self {
cap: 100,
cur: 0,
buf: vec![Instant::now() - Duration::from_secs(10); 100],
freq: Arc::new(AtomicF64::new(0.0)),
}
}
pub fn tick(&mut self) {
let last = self.buf[self.cur];
let now = Instant::now();
self.buf[self.cur] = now;
let delta = (now - last) / 100 + Duration::from_micros(1);
let freq = Duration::from_millis(1000)
.div_duration_f64(delta)
.clamp(0.0, 9999.0);
self.freq.store(freq, Ordering::SeqCst);
self.cur = match self.cur + 1 {
cur if cur == self.cap => 0,
cur => cur,
}
}
// pub fn reset(&mut self) {
// self.buf = vec![Instant::now(); 100];
// }
pub fn fork(&self) -> Arc<AtomicF64> {
Arc::clone(&self.freq)
}
}

View File

@@ -11,9 +11,11 @@ use std::{
use tokio::{sync::oneshot, task};
use crate::slider_io::utils::LoopTimer;
pub trait ThreadJob: Send {
fn setup(&mut self) -> bool;
fn tick(&mut self);
fn tick(&mut self) -> bool;
fn teardown(&mut self);
}
@@ -24,7 +26,7 @@ pub struct ThreadWorker {
}
impl ThreadWorker {
pub fn new<T: 'static + ThreadJob>(name: &'static str, mut job: T) -> Self {
pub fn new<T: 'static + ThreadJob>(name: &'static str, mut job: T, mut timer: LoopTimer) -> Self {
info!("Thread worker starting {}", name);
let stop_signal = Arc::new(AtomicBool::new(false));
@@ -40,7 +42,9 @@ impl ThreadWorker {
if stop_signal_clone.load(Ordering::SeqCst) {
break;
}
job.tick();
if job.tick() {
timer.tick();
}
}
info!("Thread worker stopping internal {}", name);
job.teardown();