Extract iteration limiting into a function
This commit is contained in:
parent
1c283a6fbe
commit
b10d30c902
|
|
@ -171,22 +171,35 @@ impl Space {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like [`std::iter::successors`] but with an upper limit on iteration count.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the sequence doesn’t terminate in `max_iters` calls of `succ`.
|
||||||
|
fn iterate_with_limit<T>(max_iters: usize, init: T, mut succ: impl FnMut(T) -> Option<T>) {
|
||||||
|
let mut state = init;
|
||||||
|
for _ in 0..max_iters {
|
||||||
|
match succ(state) {
|
||||||
|
Some(next) => state = next,
|
||||||
|
None => return,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("iteration limit exceeded");
|
||||||
|
}
|
||||||
|
|
||||||
impl Traceable for Space {
|
impl Traceable for Space {
|
||||||
fn trace(&self, camera: Location, ray: Ray) -> Vec<Hit> {
|
fn trace(&self, camera: Location, ray: Ray) -> Vec<Hit> {
|
||||||
let ray = self.camera_ray_to_abs(camera, ray);
|
let ray = self.camera_ray_to_abs(camera, ray);
|
||||||
let mut hits = vec![];
|
let mut hits = vec![];
|
||||||
std::iter::successors(Some(ray), |ray: &Ray| {
|
iterate_with_limit(100, ray, |ray| {
|
||||||
let ret = self
|
let ret = self
|
||||||
.trace_iter(*ray)
|
.trace_iter(ray)
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.find_map(|ray| self.obj_hitter(ray.pos).map(|hitter| hitter(self, ray)))
|
.find_map(|ray| self.obj_hitter(ray.pos).map(|hitter| hitter(self, ray)))
|
||||||
.expect("Space::trace_iter does not terminate");
|
.expect("Space::trace_iter does not terminate");
|
||||||
hits.extend(ret.objects); // TODO fix distance
|
hits.extend(ret.objects); // TODO fix distance
|
||||||
ret.end
|
ret.end
|
||||||
})
|
});
|
||||||
.nth(100)
|
|
||||||
.is_some()
|
|
||||||
.then(|| panic!("tracing didn't terminate"));
|
|
||||||
hits
|
hits
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user