gchp / rustbox

Rust implementation of the termbox library
MIT License
469 stars 48 forks source link

How to pass RustBox within threads? #77

Closed ritiek closed 7 years ago

ritiek commented 7 years ago

I'd like to pass Rustbox within threads. I tried using the inbuilt std::thread as well as the crossbeam library but I seem to be running across the following error

the trait bound *mut (): std::marker::Sync is not satisfied in &rustbox::RustBox

I came across #65 which says

For sending the RustBox type between threads, you can now wrap it inside a std::sync::Mutex (which will implement Sync).

I've never worked with threads in Rust before so I am not sure how to initialize RustBox around a Mutex wrap and pass it between threads.

Can someone help me out with a minimal example?

ritiek commented 7 years ago

Here is one I built up with help from stackoverflow.

extern crate rustbox;

use std::thread;
use std::time::Duration;
use std::sync::{Arc,Mutex};

use rustbox::{Color, RustBox};
use rustbox::Key;

fn mark_at(x: usize, y: usize, rustbox: &Arc<Mutex<RustBox>>) {
    rustbox.lock().unwrap().print(x, y, rustbox::RB_BOLD, Color::Black, Color::White, "+");
    rustbox.lock().unwrap().present();
    let rustbox = rustbox.clone();
    thread::spawn(move || {
        let delay = Duration::from_millis(2000);
        thread::sleep(delay);
        rustbox.lock().unwrap().print(x, y, rustbox::RB_BOLD, Color::Black, Color::White, " ");
    });
}

fn main() {
    let rustbox = match RustBox::init(Default::default()) {
        Result::Ok(v) => v,
        Result::Err(e) => panic!("{}", e),
    };
    let rustbox = Arc::new(Mutex::new(rustbox));
    rustbox.lock().unwrap().print(1, 1, rustbox::RB_BOLD, Color::Black, Color::White, " ");
    rustbox.lock().unwrap().print(1, 2, rustbox::RB_BOLD, Color::Black, Color::White, " ");

    loop {
        rustbox.lock().unwrap().present();
        let pe = rustbox.lock().unwrap().poll_event(false);
        match pe {
            Ok(rustbox::Event::KeyEvent(key)) => {
                match key {
                    Key::Char('q') => {
                        mark_at(1, 1, &rustbox);
                    }
                    Key::Char('w') => {
                        mark_at(1, 2, &rustbox);
                    }
                    Key::Esc => { break; }
                    _ => { }
                }
            },
            Err(e) => panic!("{}", e),
            _ => { }
        }
    }
}