1

i need to have a thread that recursively checks a variable while the main thread changes the variable. however, it appears that with move, the variable is not being changes by the lambda in register. (i checked and the function works, its just that move makes it so i cannot change the original variable)

the code i currently have created:

use std::io::stdin;
use std::thread;

use enigo::{self, Enigo, MouseControllable};
use enigo::MouseButton;

use livesplit_hotkey::*;


fn main() {
    let mut input = String::new();
    let mut started = false;

    println!("How many clicks per tick? (too many will lag)");

    stdin().read_line(&mut input).expect("Unable to read line");

    let input2 = input.trim().parse::<u16>().unwrap();

    for _ in 0 .. input2 {
        thread::spawn(move || {
            let mut enigo = Enigo::new();

            loop {
                if started {
                    println!("clicking"); // debug
                    enigo.mouse_click(MouseButton::Left);
                }
            }
        });
    }

    println!("Press f8 to toggle clicking");

    let hook = Hook::new().unwrap();

    hook.register(Hotkey { key_code: KeyCode::F8, modifiers: Modifiers::empty() },  move || {
        started = !started;
    }).expect("Unable to assign hotkey");

    loop {}
}

i know that there are things such as Arc and Mutex, but i'm unsure how to use them correctly.

1 Answer 1

0

Just use a static AtomicBool in place of started:

use std::io::stdin;
use std::thread;

use enigo::{self, Enigo, MouseControllable};
use enigo::MouseButton;

use livesplit_hotkey::*;

static STARTED: atomic::AtomicBool = atomic::AtomicBool::new(false);

fn main() {
    let mut input = String::new();

    println!("How many clicks per tick? (too many will lag)");

    stdin().read_line(&mut input).expect("Unable to read line");

    let input2 = input.trim().parse::<u16>().unwrap();

    for _ in 0 .. input2 {
        thread::spawn(move || {
            let mut enigo = Enigo::new();

            loop {
                if STARTED.load(atomic::Ordering::SeqCst) {
                    println!("clicking"); // debug
                    enigo.mouse_click(MouseButton::Left);
                }
            }
        });
    }

    println!("Press f8 to toggle clicking");

    let hook = Hook::new().unwrap();

    hook.register(Hotkey { key_code: KeyCode::F8, modifiers: Modifiers::empty() },  move || {
        // use xor(true) to emulate "NOT" operation
        // true ^ true -> false
        // false ^ true -> true
        STARTED.fetch_xor(true, atomic::Ordering::SeqCst);
    }).expect("Unable to assign hotkey");

    loop {}
}

Note: Ordering::SeqCst may not be the ideal atomic ordering for this. You could use one of the less strict orderings, but I'll leave that to you.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.