stim: use a Visitor instead of a FoldOp for eval

boosts perf from 420 -> 530 fps
This commit is contained in:
2022-08-18 02:52:57 -07:00
parent 2a9c065cb0
commit 300c11f5ca

View File

@@ -1,7 +1,7 @@
use crate::real::Real as _; use crate::real::Real as _;
use crate::cross::vec::Vec3; use crate::cross::vec::Vec3;
use crate::geom::{Coord as _, HasCrossSection, Index, Meters, Region}; 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 coremem_cross::dim::OffsetDimSlice;
use rand; 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. /// used as a MapVisitor in order to evaluate each Stimulus in a List at a specific time/place.
struct StimulusEvaluator { struct StimulusEvaluator {
fields: Fields,
t_sec: f32, t_sec: f32,
pos: Meters, pos: Meters,
} }
impl<S: AbstractStimulus> FoldOp<Fields, &S> for StimulusEvaluator { impl<S: AbstractStimulus> Visitor<&S> for &mut StimulusEvaluator {
type Output = Fields; fn visit(&mut self, next: &S) {
fn feed(&mut self, prev: Fields, next: &S) -> Self::Output { self.fields += next.at(self.t_sec, self.pos);
prev + next.at(self.t_sec, self.pos)
} }
} }
impl<L: Sync> AbstractStimulus for L impl<L: Sync> AbstractStimulus for L
where 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 { 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
} }
} }