stim: use a Visitor instead of a FoldOp for eval
boosts perf from 420 -> 530 fps
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use crate::real::Real as _;
|
||||
use crate::cross::vec::Vec3;
|
||||
use crate::geom::{Coord as _, HasCrossSection, Index, Meters, Region};
|
||||
use coremem_cross::compound::list::{Fold, FoldOp};
|
||||
use coremem_cross::compound::list::{Visit, Visitor};
|
||||
use coremem_cross::dim::OffsetDimSlice;
|
||||
use rand;
|
||||
|
||||
@@ -48,23 +48,25 @@ pub trait AbstractStimulus: Sync {
|
||||
|
||||
/// used as a MapVisitor in order to evaluate each Stimulus in a List at a specific time/place.
|
||||
struct StimulusEvaluator {
|
||||
fields: Fields,
|
||||
t_sec: f32,
|
||||
pos: Meters,
|
||||
}
|
||||
|
||||
impl<S: AbstractStimulus> FoldOp<Fields, &S> for StimulusEvaluator {
|
||||
type Output = Fields;
|
||||
fn feed(&mut self, prev: Fields, next: &S) -> Self::Output {
|
||||
prev + next.at(self.t_sec, self.pos)
|
||||
impl<S: AbstractStimulus> Visitor<&S> for &mut StimulusEvaluator {
|
||||
fn visit(&mut self, next: &S) {
|
||||
self.fields += next.at(self.t_sec, self.pos);
|
||||
}
|
||||
}
|
||||
|
||||
impl<L: Sync> AbstractStimulus for L
|
||||
where
|
||||
for<'a> &'a L: Fold<StimulusEvaluator, Fields, Output=Fields>,
|
||||
for<'a, 'b> &'a L: Visit<&'b mut StimulusEvaluator>,
|
||||
{
|
||||
fn at(&self, t_sec: f32, pos: Meters) -> Fields {
|
||||
self.fold(StimulusEvaluator { t_sec, pos}, Fields::default())
|
||||
let mut ev = StimulusEvaluator { t_sec, pos, fields: Fields::default()};
|
||||
self.visit(&mut ev);
|
||||
ev.fields
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user