Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

elegant way of capturing a reference to an integer variable?

I have this snippet:

let mut animation_index = 0 as usize;
let mut ptr : *mut usize = &mut animation_index as _;
{
    io_context.window().add_key_callback(
        Box::new(move |key_states| {
            if key_states[KbKey::Space.to_index()] == KeyActionState::Press
            {
                unsafe {
                *ptr += 1;
                println!("{}", animation_index);
                }
            }
        })
    );
}

Basically it adds a callback such that if and when I press space, the integer variable animation_index goes up by 1. This works, but requires the use of mutable pointers and unsafe, which is very ugly.

I’d like to have the same logic but ideally do it with pure safe rust isntead.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

It looks like you are trying to share a mutable value across threads.

Typically, this is done with atomics, Arc<Mutex<T>> or Arc<RwLock<T>>.

use std::synce::{Arc, RwLock};

let mut animation_index = Arc::new(RwLock::new(0usize));
{
    // a clone of the counter that can be moved into the callback
    let animation_index = animation_index.clone();
    io_context.window().add_key_callback(
        Box::new(move |key_states| {
            if key_states[KbKey::Space.to_index()] == KeyActionState::Press
            {
                let index = animation_index.write().unwrap();
                *index += 1;
                println!("{}", index);
            }
        })
    );
}

With atomics it would look something like this:

use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};

let mut animation_index = Arc::new(AtomicUsize::new(0));
{
    // a clone of the counter that can be moved into the callback
    let animation_index = animation_index.clone();
    io_context.window().add_key_callback(
        Box::new(move |key_states| {
            if key_states[KbKey::Space.to_index()] == KeyActionState::Press
            {
                let index = animation_index.fetch_add(1, Ordering::SeqCst);
                println!("{}", index);
            }
        })
    );
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading