Skip to main content

subtr_actor/stats/analysis_graph/nodes/
ball_carry.rs

1use super::*;
2use crate::stats::calculators::*;
3use crate::*;
4
5/// Detects ball carries and air dribbles from continuous ball-control sequences.
6pub struct BallCarryNode {
7    calculator: BallCarryCalculator,
8}
9
10impl BallCarryNode {
11    pub fn new() -> Self {
12        Self {
13            calculator: BallCarryCalculator::new(),
14        }
15    }
16
17    fn update_from_control_state(
18        &mut self,
19        ctx: &AnalysisStateContext<'_>,
20    ) -> SubtrActorResult<()> {
21        self.calculator
22            .update(ctx.get::<ContinuousBallControlState>()?)
23    }
24}
25
26impl Default for BallCarryNode {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32impl AnalysisNode for BallCarryNode {
33    type State = BallCarryCalculator;
34
35    fn name(&self) -> &'static str {
36        "ball_carry"
37    }
38
39    fn emitted_events(&self) -> &'static [crate::stats::calculators::EmittedEvent] {
40        crate::stats::calculators::BALL_CARRY_EMITTED_EVENTS
41    }
42
43    fn dependencies(&self) -> Vec<AnalysisDependency> {
44        vec![continuous_ball_control_dependency()]
45    }
46
47    fn evaluate(&mut self, ctx: &AnalysisStateContext<'_>) -> SubtrActorResult<()> {
48        self.update_from_control_state(ctx)
49    }
50
51    fn finish(&mut self, ctx: &AnalysisStateContext<'_>) -> SubtrActorResult<()> {
52        self.update_from_control_state(ctx)
53    }
54
55    fn state(&self) -> &Self::State {
56        &self.calculator
57    }
58}
59
60pub(crate) fn boxed_default() -> Box<dyn AnalysisNodeDyn> {
61    Box::new(BallCarryNode::new())
62}