Skip to content

Commit

Permalink
Fix wooting-analog-plugin instability (#70)
Browse files Browse the repository at this point in the history
* Fix instability with wooting-analog-plugin

* Make deinit a bit snappier by checking state bool every 10ms instead of every 500ms, but keep device refresh rate at 500ms

* Oops, didn't mean to remove this
  • Loading branch information
Sainan authored Jul 26, 2024
1 parent 59764f9 commit 4d1ab8a
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 37 deletions.
11 changes: 0 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions wooting-analog-plugin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ wooting-analog-plugin-dev = { path = "../wooting-analog-plugin-dev"}
hidapi = { version = "^1.2", features = ["linux-static-hidraw"], default-features = false }
env_logger = "^0.7"
objekt = "^0.1"
timer = "^0.2"
chrono = "^0.4"

[lib]
crate-type = ["cdylib"]
52 changes: 28 additions & 24 deletions wooting-analog-plugin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ extern crate hidapi;
extern crate wooting_analog_plugin_dev;
#[macro_use]
extern crate objekt;
extern crate chrono;
extern crate timer;

use hidapi::DeviceInfo as DeviceInfoHID;
use hidapi::{HidApi, HidDevice};
Expand All @@ -17,7 +15,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::thread::JoinHandle;
use std::{str, thread};
use timer::{Guard, Timer};
use wooting_analog_plugin_dev::wooting_analog_common::*;
use wooting_analog_plugin_dev::*;

Expand Down Expand Up @@ -404,22 +401,20 @@ impl Drop for Device {
}

pub struct WootingPlugin {
initialised: bool,
initialised: Arc<AtomicBool>,
device_event_cb: Arc<Mutex<Option<Box<dyn Fn(DeviceEventType, &DeviceInfo) + Send>>>>,
devices: Arc<Mutex<HashMap<DeviceID, Device>>>,
timer: Timer,
worker_guard: Option<Guard>,
thread: Option<JoinHandle<()>>,
}

const PLUGIN_NAME: &str = "Wooting Official Plugin";
impl WootingPlugin {
fn new() -> Self {
WootingPlugin {
initialised: false,
initialised: Arc::new(false.into()),
device_event_cb: Arc::new(Mutex::new(None)),
devices: Arc::new(Mutex::new(Default::default())),
timer: timer::Timer::new(),
worker_guard: None,
thread: None,
}
}

Expand Down Expand Up @@ -510,11 +505,15 @@ impl WootingPlugin {
//We wanna call it in this thread first so we can get hold of any connected devices now so we can return an accurate result for initialise
init_device_closure(&hid, &self.devices, &self.device_event_cb, &device_impls);

self.worker_guard = Some({
let t_devices = Arc::clone(&self.devices);
let t_device_event_cb = Arc::clone(&self.device_event_cb);
self.timer
.schedule_repeating(chrono::Duration::milliseconds(500), move || {
let t_initialised = Arc::clone(&self.initialised);
let t_devices = Arc::clone(&self.devices);
let t_device_event_cb = Arc::clone(&self.device_event_cb);
self.thread = Some(thread::spawn(move || {
let mut i = 0;
while t_initialised.load(Ordering::Relaxed) {
if i == 500 {
i = 0;

//Check if any of the devices have disconnected and get rid of them if they have
{
let mut disconnected: Vec<u64> = vec![];
Expand All @@ -537,9 +536,12 @@ impl WootingPlugin {
error!("We got error while refreshing devices. Err: {}", e);
}
init_device_closure(&hid, &t_devices, &t_device_event_cb, &device_impls);
})
});
debug!("Started timer");
}
thread::sleep(std::time::Duration::from_millis(10));
i += 10;
}
}));
debug!("Started thread");
Ok(self.devices.lock().unwrap().len() as u32).into()
}
}
Expand All @@ -559,24 +561,26 @@ impl Plugin for WootingPlugin {

let ret = self.init_worker();
self.device_event_cb.lock().unwrap().replace(callback);
self.initialised = ret.is_ok();
self.initialised.store(ret.is_ok(), Ordering::Relaxed);
ret
}

fn is_initialised(&mut self) -> bool {
self.initialised
self.initialised.load(Ordering::Relaxed)
}

fn unload(&mut self) {
self.initialised.store(false, Ordering::Relaxed);
if let Some(t) = self.thread.take() {
t.join().unwrap();
};
self.devices.lock().unwrap().drain();
drop(self.worker_guard.take());
self.initialised = false;

info!("{} unloaded", PLUGIN_NAME);
}

fn read_analog(&mut self, code: u16, device_id: DeviceID) -> SDKResult<f32> {
if !self.initialised {
if !self.initialised.load(Ordering::Relaxed) {
return Err(WootingAnalogResult::UnInitialized).into();
}

Expand Down Expand Up @@ -623,7 +627,7 @@ impl Plugin for WootingPlugin {
max_length: usize,
device_id: DeviceID,
) -> SDKResult<HashMap<c_ushort, c_float>> {
if !self.initialised {
if !self.initialised.load(Ordering::Relaxed) {
return Err(WootingAnalogResult::UnInitialized).into();
}

Expand Down Expand Up @@ -668,7 +672,7 @@ impl Plugin for WootingPlugin {
}

fn device_info(&mut self) -> SDKResult<Vec<DeviceInfo>> {
if !self.initialised {
if !self.initialised.load(Ordering::Relaxed) {
return Err(WootingAnalogResult::UnInitialized).into();
}

Expand Down

0 comments on commit 4d1ab8a

Please sign in to comment.