big_brain/
choices.rs

1use std::sync::Arc;
2
3use bevy::prelude::*;
4
5use crate::{
6    actions::{ActionBuilder, ActionBuilderWrapper},
7    scorers::{self, Score, ScorerBuilder},
8    thinker::Scorer,
9};
10
11/// Contains different types of Considerations and Actions
12#[derive(Debug, Clone, Reflect)]
13#[reflect(from_reflect = false)]
14pub struct Choice {
15    pub(crate) scorer: Scorer,
16    #[reflect(ignore)]
17    pub(crate) action: ActionBuilderWrapper,
18    pub(crate) action_label: Option<String>,
19}
20
21impl Choice {
22    pub fn calculate(&self, scores: &Query<&Score>) -> f32 {
23        scores
24            .get(self.scorer.0)
25            .expect("Where did the score go?")
26            .0
27    }
28}
29
30/// Builds a new [`Choice`].
31#[derive(Clone, Debug, Reflect)]
32#[reflect(from_reflect = false)]
33pub struct ChoiceBuilder {
34    when_label: Option<String>,
35    #[reflect(ignore)]
36    pub when: Arc<dyn ScorerBuilder>,
37    then_label: Option<String>,
38    #[reflect(ignore)]
39    pub then: Arc<dyn ActionBuilder>,
40}
41impl ChoiceBuilder {
42    pub fn new(scorer: Arc<dyn ScorerBuilder>, action: Arc<dyn ActionBuilder>) -> Self {
43        Self {
44            when_label: scorer.label().map(|s| s.into()),
45            when: scorer,
46            then_label: action.label().map(|s| s.into()),
47            then: action,
48        }
49    }
50
51    pub fn build(&self, cmd: &mut Commands, actor: Entity, parent: Entity) -> Choice {
52        let scorer_ent = scorers::spawn_scorer(&*self.when, cmd, actor);
53        cmd.entity(parent).add_children(&[scorer_ent]);
54        Choice {
55            scorer: Scorer(scorer_ent),
56            action_label: self.then.label().map(|s| s.into()),
57            action: ActionBuilderWrapper::new(self.then.clone()),
58        }
59    }
60}