Skip to content

Instantly share code, notes, and snippets.

@zkat
Last active September 24, 2022 23:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zkat/ede7fef78926bd709283b95a9fa2cddc to your computer and use it in GitHub Desktop.
Save zkat/ede7fef78926bd709283b95a9fa2cddc to your computer and use it in GitHub Desktop.
WeightedMeasure impl example
use crate::Score;
pub trait Measure: std::fmt::Debug + Sync + Send {
fn calculate(&self, scores: Vec<(&Score, f32)>) -> f32;
}
#[derive(Debug, Clone, Default)]
pub struct WeightedMeasure;
impl Measure for WeightedMeasure {
fn calculate(&self, scores: Vec<(&Score, f32)>) -> f32 {
let wsum: f32 = utilities.iter().map(|(_score, weight)| weight).sum();
if wsum == 0.0 {
0.0
} else {
scores
.iter()
.map(|(_score, weight)| weight / wsum * score.get().powf(2.0))
.sum::<f32>()
.powf(1.0 / 2.0)
}
}
}
#[derive(Component, Debug)]
pub struct MeasuredScorer {
threshold: f32,
measure: Arc<dyn Measure>,
scorers: Vec<(Scorer, f32)>,
}
impl MeasuredScorer {
pub fn build(threshold: f32) -> MeasuredScorerBuilder {
MeasuredScorerBuilder {
threshold,
measure: Arc::new(SumMeasure),
scorers: Vec::new(),
label: None,
}
}
}
impl ScorerBuilder for MeasuredScorerBuilder {
fn label(&self) -> Option<&str> {
self.label.as_deref().or(Some("MeasuredScorer"))
}
#[allow(clippy::needless_collect)]
fn build(&self, cmd: &mut Commands, scorer: Entity, actor: Entity) {
let scorers: Vec<_> = self
.scorers
.iter()
.map(|(scorer, weight)| (Scorer(spawn_scorer(&**scorer, cmd, actor)), weight))
.collect();
let scorer_ents: Vec<_> = scorers.map(|(Scorer(ent), _)| ent).collect();
cmd.entity(scorer)
.push_children(&scorer_ents[..])
.insert(MeasuredScorer {
threshold: self.threshold,
scorers,
});
}
}
#[derive(Debug)]
pub struct MeasuredScorerBuilder {
threshold: f32,
measure: Arc<dyn Measure>,
scorers: Vec<(Arc<dyn ScorerBuilder>, f32)>,
label: Option<String>,
}
impl MeasuredScorerBuilder {
pub fn push(mut self, weight: f32, scorer: impl ScorerBuilder + 'static) -> Self {
self.scorers.push((Arc::new(scorer), weight));
self
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment