rust 使用sdl2的Pyo3文库

8cdiaqws  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(133)

我打算创建一个Pyo3库来实现一些RL环境。我一直在使用Pyo3来完成其他任务。我还打算使用SDL2渲染,但它给了我一个错误。

#[pyclass]
pub struct FirstEnv {
   pos: f32,
   renderer: Renderer,
}

pub struct Renderer {
    canvas: sdl2::render::WindowCanvas,
}

错误:Rc<RendererContext<WindowContext>>无法在线程之间安全发送
有什么办法解决这个问题吗?或者这种组合不起作用?
它告诉我,在FirstEnv中,trait Send没有为Rc<RendererContext<WindowContext>>实现。因为我是rust的新手,所以我尝试了google,它说它不是线程安全的。但是,我不知道我应该怎么做。

ldioqlga

ldioqlga1#

我尝试创建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();
    }
}

但它仍然无法做到这一点,因为编译器对这一行不满意,并带有相同的错误msg:

let renderer_thread = std::thread::spawn(move || {
            renderer.run();
        });

相关问题