I have a loop which spawns a set of threads. Each thread is listening to a different key. I want to do something in each thread based on the character pressed event.
This is the function I am using. (InputConfig is just a struct that contains the key, for example and x):
#[cfg(target_os = "windows")]
pub fn wait_until_user_input(input_config: &InputConfig) {
loop {
if let Ok(_) = poll(Duration::from_millis(20)) {
println!("Event polled, expecting '{}'", input_config.key.unwrap());
match read().unwrap() {
Event::Key(KeyEvent {
code,
modifiers: _,
kind,
state: _,
}) => {
if code == KeyCode::Char(input_config.key.unwrap())
&& kind == KeyEventKind::Press
{
break;
}
println!(
"Expected: '{}', Found: '{:?}' {:?}",
input_config.key.unwrap(),
code,
kind
);
}
_ => {
println!("No event");
}
}
}
// Sleep for a short duration to avoid high CPU usage while waiting for input.
thread::sleep(Duration::from_millis(20));
}
}
When I run it like this I get the following output when I press space:
Expected: 'x', Found: 'Char(' ')' Press
Expected: ' ', Found: 'Char(' ')' Release
Event polled, expecting 'x'
Event polled, expecting ' '
So it seems that each thread captures each event and the next thread will not get the same exact event. So in this example, if I want to press space and press to make an action, it will randomly not work because the thread of x will steal that event.
How can I "share" the events between threads?
This is how I spawn the threads:
// The configuration
#[derive(Debug, Clone)]
pub struct InputConfig {
pub key: Option<char>,
// ...
}
let input_configs = vec![
InputConfig {
key: Some(' '),
},
InputConfig {
key: Some('x'),
},
];
// Spawn the threads
let mut handles = vec![];
for (n, config) in input_configs.iter().enumerate() {
// ...
let cloned_config = config.clone();
// ...
let handle = thread::spawn(move || {
// ...
wait_until_user_input(&cloned_config)
// ...
});
handles.push(handle);
}
// Wait for all threads to finish
for handle in handles {
handle.join().expect("Thread panicked");
}