Reputation: 16361
I'm trying to create a simple multi-color mandelbrot generator, extending the example giving in O'Reilly's Programming Rust. The idea is to create three different "planes" of greymap with slightly different escape velocities, then merge those into an RGB-style colormapped image. The main idea is that each plane is independent, so each can be processed by a separate thread using the crossbeam
crate, which is the final goal.
The problem is that I can't seem to vectorize my planes. Let me show you:
pub struct Plane {
bounds: (usize, usize),
velocity: u8,
region: Vec<u16>,
}
impl Plane {
pub fn new(width: usize, height: usize, velocity: u8) -> Plane {
Plane {
bounds: (width, height),
velocity: velocity,
region: vec![0 as u16; width * height],
}
}
}
pub fn main() {
// ... argument processing elided
let width = 1000;
let height = 1000;
let velocity = 10;
let planes = vec![Plane::new(width, height, velocity); 4]; // RGBa
}
When I attempt to build this, I get:
error[E0277]: the trait bound `Plane: std::clone::Clone` is not satisfied
--> src/main.rs:23:18
|
23 | let planes = vec![Plane::new(width, height, velocity); 4]; // RGBa
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Plane`
|
= note: required by `std::vec::from_elem`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
I've tried creating one gigantic plane and then slicing it into subplanes with chunks_mut
and then passing references to the underlying arrays, but then it gives me:
region: &' [u16]: this field does not implement 'Copy'
As far as I can tell, I'm not trying to copy the Plane
object, but the vec![]
macro wants to move it somewhere, for which Copy
must be implemented, but within that I just want the handle to the array moved, not the data, right? And that's just a bitmap itself, shouldn't it have Copy
implemented already?
This works fine on a single plane, even when that plane is sliced into regions for multi-core processing (see example here), although in that case the "one gigantic plane" lives in a parent function and only slices of it are handed off to the renderer(s).
Is there a way to move the array of plane data into the struct for proper encapsulation?
Upvotes: 2
Views: 7147
Reputation: 58735
The Vec
construction macro vec![val; n]
requires that the element type implements Clone
so it can copy the example element into the remaining slots. So, the easy fix is to make Plane
implement Clone
:
#[derive(Clone)]
pub struct Plane {
bounds: (usize, usize),
velocity: u8,
region: Vec<u16>,
}
Alternatively, you can just fill the vector a different way, which doesn't rely on the elements implementing Clone
. For example:
use std::iter;
let planes: Vec<_> = iter::repeat_with(|| Plane::new(width, height, velocity))
.take(4)
.collect();
Upvotes: 10