Skip to content
Snippets Groups Projects
thinker.rs 10.81 KiB
use std::{
    sync::Arc,
    time::{Duration, Instant},
};

use bevy::prelude::*;

use crate::{
    actions::{self, ActionBuilder, ActionBuilderWrapper, ActionState},
    choices::{Choice, ChoiceBuilder},
    pickers::Picker,
    scorers::{Score, ScorerBuilder},
};

#[derive(Debug, Clone, Copy)]
pub struct Actor(pub Entity);

#[derive(Debug, Clone, Copy)]
pub struct ActionEnt(pub Entity);

#[derive(Debug, Clone, Copy)]
pub struct ScorerEnt(pub Entity);

#[derive(Debug)]
pub struct Thinker {
    picker: Arc<dyn Picker>,
    otherwise: Option<ActionBuilderWrapper>,
    choices: Vec<Choice>,
    current_action: Option<(ActionEnt, ActionBuilderWrapper)>,
}

impl Thinker {
    pub fn build() -> ThinkerBuilder {
        ThinkerBuilder::new()
    }
}

#[derive(Debug, Default)]
pub struct ThinkerBuilder {
    pub picker: Option<Arc<dyn Picker>>,
    pub otherwise: Option<ActionBuilderWrapper>, // Arc<dyn ActionBuilder>?
    pub choices: Vec<ChoiceBuilder>,
}

impl ThinkerBuilder {
    pub(crate) fn new() -> Self {
        Self {
            picker: None,
            otherwise: None,
            choices: Vec::new(),
        }
    }

    pub fn picker(&mut self, picker: impl Picker + 'static) -> &mut Self {
        self.picker = Some(Arc::new(picker));
        self
    }

    pub fn when(
        &mut self,
        scorer: impl ScorerBuilder + 'static,
        action: impl ActionBuilder + 'static,
    ) -> &mut Self {
        self.choices.push(ChoiceBuilder::new(Arc::new(scorer), Arc::new(action)));
        self
    }

    pub fn otherwise(&mut self, otherwise: impl ActionBuilder + 'static) -> &mut Self {
        self.otherwise = Some(ActionBuilderWrapper::new(Arc::new(otherwise)));
        self