我打算创建一个 Pyo3 库来实现一些 RL 环境。我一直在使用 Pyo3 来完成其他任务。我也打算使用 SDL2 渲染,但是它给了我一个错误。
#[pyclass]
pub struct FirstEnv {
pos: f32,
renderer: Renderer,
}
pub struct Renderer {
canvas: sdl2::render::WindowCanvas,
}
错误:
Rc<RendererContext<WindowContext>>
无法在线程之间安全发送
有解决办法吗?还是这种组合不行?
它告诉我在
FirstEnv
内,Send
没有为Rc<RendererContext<WindowContext>>
实现。由于我是 Rust 的新手,因此尝试使用谷歌搜索,它说它不是线程安全的。但是,我不确定该怎么办。
我尝试创建 ThreadSafe 渲染器,但失败了。也许有人可以帮助我。
extern crate sdl2;
extern crate crossbeam_channel;
use crossbeam_channel::Receiver;
use crossbeam_channel::unbounded;
use crossbeam_channel::Sender;
use std::sync::Arc;
pub struct Renderer {
canvas: sdl2::render::WindowCanvas,
commands: Receiver<RendererCommand>,
}
enum RendererCommand {
Draw(f32),
Quit,
}
impl Renderer {
fn new(canvas: sdl2::render::WindowCanvas, commands: Receiver<RendererCommand>) -> Self {
Self { canvas, commands }
}
fn run(&mut self) {
loop {
match self.commands.recv() {
Ok(RendererCommand::Draw(pos)) => {
// Draw the environment
}
Ok(RendererCommand::Quit) | Err(_) => {
// Quit the renderer
break;
}
}
}
}
}
pub struct ThreadSafeRenderer {
renderer_sender: Sender<RendererCommand>,
}
impl ThreadSafeRenderer {
pub fn new() -> Self {
let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap();
let window = video_subsystem
.window("My Window", 800, 600)
.position_centered()
.build()
.unwrap();
let canvas = window.into_canvas().build().unwrap();
let (tx, rx) = unbounded();
let renderer = Renderer::new(canvas, rx);
let renderer_thread = std::thread::spawn(move || {
renderer.run();
});
ThreadSafeRenderer {
renderer_sender: tx,
}
}
pub fn render(&self) {
// send commands to the renderer
self.renderer_sender.send(RendererCommand::Draw(0.0)).unwrap();
}
}
但它仍然无法做到这一点,因为编译器对这一行不满意并出现相同的错误消息:
let renderer_thread = std::thread::spawn(move || {
renderer.run();
});