I've been working in understanding and using structs and impl as I mostly stick to mod and fn at most. I want to implement this window struct which impl's would manage every function a window may need. In making this I've realized I may need to launch the updating event in a separate thread, wherein I've ran into a problem. I think it may have to do with the crate I'm using in itself, although I'd love to know what's the proper way to do this (if it even is one and this isn't very bad code practice or idea).
This is my code:
#![allow(unused_imports)]
#![allow(dead_code)]
use minifb::*;
use std::io;
use std::thread;
use std::time::Duration;
struct WindowGui {
name: String,
height: usize, //i32
width: usize, //i32
buffer: Vec<u32>,
}
impl WindowGui {
fn window(&self) -> Window {
let window = Window::new(
&self.name,
self.width,
self.height,
WindowOptions {
resize: true,
..WindowOptions::default()
}, //WindowOptions::default(),
)
.expect("Error Creating windows");
return window;
}
fn update(&self, mut window: Window) {
while window.is_open() && !window.is_key_down(Key::Escape) {
window
.update_with_buffer(&self.buffer, self.width, self.height)
.expect("Couldn't update window with current pixel buffer");
thread::sleep(Duration::from_millis(1));
}
}
}
fn main() {
let name = String::from("yoo");
let buffer: Vec<u32> = Vec::new();
let win = WindowGui {
name,
height: 1,
width: 2,
buffer,
};
let mut window_instance = win.window();
let screen = thread::spawn(move || {
win.update(window_instance);
});
let mut bla = String::new();
io::stdin().read_line(&mut bla).expect("no");
println!("Hello, world!");
}
Which, as I exeute it, yields 8 errors which I'm unsure how to deal with as I'm not very confident with how to deal with threads and possesion/borrowing etc (also static) in this context:
error[E0277]: `*mut winapi::shared::windef::HBRUSH__` cannot be sent between threads safely
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ------------- ^------
| | |
| __________________|_____________within this `[closure@src\main.rs:50:32: 50:39]`
| | |
| | required by a bound introduced by this call
51 | | win.update(window_instance);
52 | | });
| |_____^ `*mut winapi::shared::windef::HBRUSH__` cannot be sent between threads safely
|
= help: within `[closure@src\main.rs:50:32: 50:39]`, the trait `Send` is not implemented for `*mut winapi::shared::windef::HBRUSH__`
= note: required because it appears within the type `Window`
= note: required because it appears within the type `Window`
note: required because it's used within this closure
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ^^^^^^^
note: required by a bound in `spawn`
--> C:\Users\hecto\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:714:8
|
714 | F: Send + 'static,
| ^^^^ required by this bound in `spawn`
error[E0277]: `*mut winapi::shared::windef::HACCEL__` cannot be sent between threads safely
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ------------- ^------
| | |
| __________________|_____________within this `[closure@src\main.rs:50:32: 50:39]`
| | |
| | required by a bound introduced by this call
51 | | win.update(window_instance);
52 | | });
| |_____^ `*mut winapi::shared::windef::HACCEL__` cannot be sent between threads safely
|
= help: within `[closure@src\main.rs:50:32: 50:39]`, the trait `Send` is not implemented for `*mut winapi::shared::windef::HACCEL__`
= note: required because it appears within the type `Window`
= note: required because it appears within the type `Window`
note: required because it's used within this closure
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ^^^^^^^
note: required by a bound in `spawn`
--> C:\Users\hecto\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:714:8
|
714 | F: Send + 'static,
| ^^^^ required by this bound in `spawn`
error[E0277]: `*mut winapi::shared::windef::HDC__` cannot be sent between threads safely
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ------------- ^------
| | |
| __________________|_____________within this `[closure@src\main.rs:50:32: 50:39]`
| | |
| | required by a bound introduced by this call
51 | | win.update(window_instance);
52 | | });
| |_____^ `*mut winapi::shared::windef::HDC__` cannot be sent between threads safely
|
= help: within `[closure@src\main.rs:50:32: 50:39]`, the trait `Send` is not implemented for `*mut winapi::shared::windef::HDC__`
= note: required because it appears within the type `Option<*mut HDC__>`
= note: required because it appears within the type `Window`
= note: required because it appears within the type `Window`
note: required because it's used within this closure
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ^^^^^^^
note: required by a bound in `spawn`
--> C:\Users\hecto\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:714:8
|
714 | F: Send + 'static,
| ^^^^ required by this bound in `spawn`
error[E0277]: `*mut winapi::shared::windef::HWND__` cannot be sent between threads safely
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ------------- ^------
| | |
| __________________|_____________within this `[closure@src\main.rs:50:32: 50:39]`
| | |
| | required by a bound introduced by this call
51 | | win.update(window_instance);
52 | | });
| |_____^ `*mut winapi::shared::windef::HWND__` cannot be sent between threads safely
|
= help: within `[closure@src\main.rs:50:32: 50:39]`, the trait `Send` is not implemented for `*mut winapi::shared::windef::HWND__`
= note: required because it appears within the type `Option<*mut HWND__>`
= note: required because it appears within the type `Window`
= note: required because it appears within the type `Window`
note: required because it's used within this closure
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ^^^^^^^
note: required by a bound in `spawn`
--> C:\Users\hecto\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:714:8
|
714 | F: Send + 'static,
| ^^^^ required by this bound in `spawn`
error[E0277]: `*mut winapi::shared::windef::HICON__` cannot be sent between threads safely
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ------------- ^------
| | |
| __________________|_____________within this `[closure@src\main.rs:50:32: 50:39]`
| | |
| | required by a bound introduced by this call
51 | | win.update(window_instance);
52 | | });
| |_____^ `*mut winapi::shared::windef::HICON__` cannot be sent between threads safely
|
= help: within `[closure@src\main.rs:50:32: 50:39]`, the trait `Send` is not implemented for `*mut winapi::shared::windef::HICON__`
= note: required because it appears within the type `[*mut HICON__; 8]`
= note: required because it appears within the type `Window`
= note: required because it appears within the type `Window`
note: required because it's used within this closure
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ^^^^^^^
note: required by a bound in `spawn`
--> C:\Users\hecto\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:714:8
|
714 | F: Send + 'static,
| ^^^^ required by this bound in `spawn`
error[E0277]: `*const u32` cannot be sent between threads safely
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ------------- ^------
| | |
| __________________|_____________within this `[closure@src\main.rs:50:32: 50:39]`
| | |
| | required by a bound introduced by this call
51 | | win.update(window_instance);
52 | | });
| |_____^ `*const u32` cannot be sent between threads safely
|
= help: within `[closure@src\main.rs:50:32: 50:39]`, the trait `Send` is not implemented for `*const u32`
= note: required because it appears within the type `DrawParameters`
= note: required because it appears within the type `Window`
= note: required because it appears within the type `Window`
note: required because it's used within this closure
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ^^^^^^^
note: required by a bound in `spawn`
--> C:\Users\hecto\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:714:8
|
714 | F: Send + 'static,
| ^^^^ required by this bound in `spawn`
error[E0277]: `*mut winapi::shared::windef::HMENU__` cannot be sent between threads safely
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| __________________-------------_^
| | |
| | required by a bound introduced by this call
51 | | win.update(window_instance);
52 | | });
| |_____^ `*mut winapi::shared::windef::HMENU__` cannot be sent between threads safely
|
= help: within `minifb::os::windows::Menu`, the trait `Send` is not implemented for `*mut winapi::shared::windef::HMENU__`
= note: required because it appears within the type `Menu`
= note: required for `Unique<minifb::os::windows::Menu>` to implement `Send`
= note: required because it appears within the type `RawVec<Menu>`
= note: required because it appears within the type `Vec<Menu>`
= note: required because it appears within the type `Window`
= note: required because it appears within the type `Window`
note: required because it's used within this closure
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ^^^^^^^
note: required by a bound in `spawn`
--> C:\Users\hecto\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:714:8
|
714 | F: Send + 'static,
| ^^^^ required by this bound in `spawn`
error[E0277]: `(dyn InputCallback + 'static)` cannot be sent between threads safely
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| __________________-------------_^
| | |
| | required by a bound introduced by this call
51 | | win.update(window_instance);
52 | | });
| |_____^ `(dyn InputCallback + 'static)` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `(dyn InputCallback + 'static)`
= note: required for `Unique<(dyn InputCallback + 'static)>` to implement `Send`
= note: required because it appears within the type `Box<dyn InputCallback>`
= note: required because it appears within the type `Option<Box<dyn InputCallback>>`
= note: required because it appears within the type `KeyHandler`
= note: required because it appears within the type `Window`
= note: required because it appears within the type `Window`
note: required because it's used within this closure
--> src\main.rs:50:32
|
50 | let screen = thread::spawn(move || {
| ^^^^^^^
note: required by a bound in `spawn`
--> C:\Users\hecto\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:714:8
|
714 | F: Send + 'static,
| ^^^^ required by this bound in `spawn`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `gui_program` due to 8 previous errors
Edit 1: I've come to realize it probably is an implementation issue of the crate, still, is there a way I could make this work?
Edit 2: Neither the Send or Copy traits are implemented for minifb::Window, can I intercede in that and or make it work without these?