I am an absolute beginner with rust, so apologies if my question is not phrased in the correct terms, I am happy to provide more clarification if needed.
I am writing a program using sdl and rlua. This program will load and run a lua script, and provide functions that the script can use. These functions will enable drawing to the SDL renderer.
In order to do that, the rust functions that I register with lua need to have access to the SDL renderer (or canvas as it is called by this SDL wrapper).
The only way I have found to access canvas in my lua callback is to wrap it in a reference counted mutex. This allows me to maintain multiple mutable references to it, so I can continue to access it in the rest of the enclosing scope. Here is a stripped back version of what I have:
extern crate rlua;
extern crate sdl2;
use std::rc::Rc;
use std::sync::Mutex;
fn main() {
let lua = rlua::Lua::new();
let sdl = sdl2::init().unwrap();
let video = sdl.video().unwrap();
let window = video.window("", 640, 320).resizable().build().unwrap();
let canvas = Rc::new(Mutex::new(window.into_canvas().build().unwrap()));
let draw_rect_canvas = canvas.clone();
let draw_rect = lua
.create_function_mut(move |_, (x, y, w, h): (i32, i32, u32, u32)| {
draw_rect_canvas
.lock()
.unwrap()
.draw_rect(sdl2::rect::Rect::new(x, y, w, h))
.unwrap();
Ok(())
})
.unwrap();
lua.globals().set("draw_rect", draw_rect).unwrap();
canvas
.lock()
.unwrap()
.set_draw_color(sdl2::pixels::Color::RGB(0, 0, 0));
}
This compiles, and does what I need it to. However, I am left wondering if either the reference counting or mutex are really necessary here, as I assume they introduce a small runtime overhead.
Is there any other way I can tell the compiler the following?
canvaswill be present as long as thedraw_rectlua function is- The lua function will not be executed at the same time as any other code that accesses
canvas
Reference counting and interior mutability look like the correct call here, but you should definitely replace
MutexwithRefCell, for better performance and debuggability.If you have had only one function that needs access to the canvas and no need to access it in the main function, you could've
moveit directly into the closure withoutRc<RefCell>, but it looks like this isn't the case.