Hi,
I have a struct TiledSurface that contains a Vec containing structs of SurfaceTile that I want to mutate in a parallel loop, using Rayon.
The only way I could make this work, is by wrapping the tile list inside a Mutex. But this completely destroys the parallel nature of course, since I need to hold the lock for the full duration of tile.draw_quad().
Rust is very new for me and since this is pretty common thing to have in a job based system, I wonder what the best approach for this is in Rust. I know that I am fetching each tile only once, for each task. So this should not need a Mutex at all. Of course the Borrow checker cannot know that, but what would be the correct way (TM) of writing such a setup in Rust?
I have the following setup (I tried to remove all the non important bits, so this only part of my code):
//A task defining a single draw action in a SurfaceTile
pub struct DrawQuadTask<Format> {
tile_index: usize,
posx: usize,
posy: usize,
width: usize,
height: usize,
color: Format,
}
//A tiled surface, contains a list of SurfaceTiles
pub struct TiledSurface<Format> {
tiles: Vec<SurfaceTile<Format>>,
}
impl<Format> TiledSurface<Format> {
pub fn fill_quads() {
//Create list of tasks, to be executed later
let mut v = Vec::<DrawQuadTask<Format>>::new();
//Depending on some non important prerequisists, I push new Tasks to v.
v.push(DrawQuadTask::<Format> {
tile_index: index,
posx: left,
posy: top,
width: tile_width,
height: tile_height,
color: color,
});
let tiles = Mutex::new(&mut self.tiles);
v.as_slice().par_iter().for_each(|task| { //parallel loop
let tile = &mut tiles.lock().unwrap()[task.tile_index];
tile.draw_quad(task.posx, task.posy, task.width, task.height, task.color);
});
}
}
I tried a whole list of different approaches, using ARC or Cell or RefCell or Box. But nothing can make the Borrow checker happy with this code setup.
So, how should I take this on?
Any input is greatly appreciated