#![doc = include_str!("../README.md")]
use std::{thread::{spawn, sleep}, time::Duration, sync::mpsc::Receiver};
use mouse_rs::{Mouse, types::Point};
mod wiggler;
pub struct Meth {
terminate: std::sync::mpsc::Sender<()>
}
impl Drop for Meth {
fn drop(&mut self) {
let _ = self.terminate.send(());
}
}
impl Meth {
const SLEEP_PERIOD: Duration = Duration::from_secs(30);
pub fn new() -> Self {
let (terminate, rx) = std::sync::mpsc::channel();
spawn(move || {
loop {
if let Ok(_) = rx.try_recv() { break }
if Self::keep_awake(&rx).is_ok() { break }
sleep(Self::SLEEP_PERIOD)
}
});
Meth { terminate }
}
fn identical(a: &Point, b: &Point) -> bool {
a.x == b.x &&
a.y == b.y
}
fn keep_awake(rx: &Receiver<()>) -> Result<(), Box<dyn std::error::Error>> {
let mouse = Mouse::new();
let mut position = mouse.get_position().unwrap();
let mut wiggler = wiggler::Wiggler::default();
loop {
if let Ok(_) = rx.try_recv() { break }
{
let mut p = mouse.get_position()?;
if Self::identical(&p, &position) {
wiggler.transform(&mut p);
mouse.move_to(p.x as i32, p.y as i32)?;
}
position = p;
};
sleep(Meth::SLEEP_PERIOD);
}
Ok(())
}
}
#[cfg(test)]
mod test {
use std::time::Duration;
use crate::Meth;
#[test]
fn test_move() {
{
println!("Wiggling soon!");
let _meth = Meth::new();
std::thread::sleep(Duration::from_secs(60));
}
println!("No more wiggles!");
std::thread::sleep(Duration::from_secs(90));
}
#[test]
fn two() {
{
println!("Wiggling soon!");
let _meth_a = Meth::new();
let _meth_b = Meth::new();
std::thread::sleep(Duration::from_secs(60));
}
println!("No more wiggles!");
std::thread::sleep(Duration::from_secs(90));
}
}