So the mutable aliasing in Tracer properly.
Apparently this is what UnsafeCell is for, and the code I wrote before wasn't technically correct, even thought it worked in practice. Hooray for doing things properly!
This commit is contained in:
parent
e747d7fee8
commit
b58ba10f9b
|
@ -1,5 +1,6 @@
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
|
|
||||||
use math::Matrix4x4;
|
use math::Matrix4x4;
|
||||||
use assembly::{Assembly, Object};
|
use assembly::{Assembly, Object};
|
||||||
|
@ -8,7 +9,7 @@ use surface::SurfaceIntersection;
|
||||||
|
|
||||||
pub struct Tracer<'a> {
|
pub struct Tracer<'a> {
|
||||||
root: &'a Assembly,
|
root: &'a Assembly,
|
||||||
rays: Vec<Ray>, // Should only be used from trace(), not any other methods
|
rays: UnsafeCell<Vec<Ray>>, // Should only be used from trace(), not any other methods
|
||||||
xform_stack: Vec<Matrix4x4>,
|
xform_stack: Vec<Matrix4x4>,
|
||||||
isects: Vec<SurfaceIntersection>,
|
isects: Vec<SurfaceIntersection>,
|
||||||
}
|
}
|
||||||
|
@ -18,16 +19,19 @@ impl<'a> Tracer<'a> {
|
||||||
Tracer {
|
Tracer {
|
||||||
root: assembly,
|
root: assembly,
|
||||||
xform_stack: Vec::new(),
|
xform_stack: Vec::new(),
|
||||||
rays: Vec::new(),
|
rays: UnsafeCell::new(Vec::new()),
|
||||||
isects: Vec::new(),
|
isects: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trace<'b>(&'b mut self, wrays: &[Ray]) -> &'b [SurfaceIntersection] {
|
pub fn trace<'b>(&'b mut self, wrays: &[Ray]) -> &'b [SurfaceIntersection] {
|
||||||
// Ready the rays
|
// Ready the rays
|
||||||
self.rays.clear();
|
let rays_ptr = self.rays.get();
|
||||||
self.rays.reserve(wrays.len());
|
unsafe {
|
||||||
self.rays.extend(wrays.iter());
|
(*rays_ptr).clear();
|
||||||
|
(*rays_ptr).reserve(wrays.len());
|
||||||
|
(*rays_ptr).extend(wrays.iter());
|
||||||
|
}
|
||||||
|
|
||||||
// Ready the isects
|
// Ready the isects
|
||||||
self.isects.clear();
|
self.isects.clear();
|
||||||
|
@ -44,7 +48,7 @@ impl<'a> Tracer<'a> {
|
||||||
// NOT be used in any other methods. The rays should only be
|
// NOT be used in any other methods. The rays should only be
|
||||||
// accessed in other methods via the mutable slice passed directly
|
// accessed in other methods via the mutable slice passed directly
|
||||||
// to them in their function parameters.
|
// to them in their function parameters.
|
||||||
slice::from_raw_parts_mut(self.rays.as_mut_ptr(), self.rays.len())
|
&mut (*rays_ptr)[..]
|
||||||
};
|
};
|
||||||
self.trace_assembly(self.root, wrays, ray_refs);
|
self.trace_assembly(self.root, wrays, ray_refs);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user