Skip to main content

subtr_actor/stats/analysis_graph/nodes/
continuous_ball_control.rs

1use super::*;
2use crate::stats::calculators::*;
3use crate::*;
4
5pub struct ContinuousBallControlNode {
6    tracker: ContinuousBallControlTracker<BallCarryKind>,
7    state: ContinuousBallControlState,
8}
9
10impl ContinuousBallControlNode {
11    pub fn new() -> Self {
12        Self {
13            tracker: ContinuousBallControlTracker::default(),
14            state: ContinuousBallControlState::default(),
15        }
16    }
17}
18
19impl Default for ContinuousBallControlNode {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25impl AnalysisNode for ContinuousBallControlNode {
26    type State = ContinuousBallControlState;
27
28    fn name(&self) -> &'static str {
29        "continuous_ball_control"
30    }
31
32    fn dependencies(&self) -> Vec<AnalysisDependency> {
33        vec![
34            frame_info_dependency(),
35            ball_frame_state_dependency(),
36            player_frame_state_dependency(),
37            touch_state_dependency(),
38            live_play_dependency(),
39        ]
40    }
41
42    fn evaluate(&mut self, ctx: &AnalysisStateContext<'_>) -> SubtrActorResult<()> {
43        let frame = ctx.get::<FrameInfo>()?;
44        let touch_state = ctx.get::<TouchState>()?;
45        let candidate = if frame.dt > 0.0 {
46            BallCarryCalculator::control_candidate(
47                ctx.get::<BallFrameState>()?,
48                ctx.get::<PlayerFrameState>()?,
49                ctx.get::<LivePlayState>()?.is_live_play,
50                touch_state,
51            )
52        } else {
53            None
54        };
55        self.state.completed_sequences.extend(self.tracker.update(
56            frame,
57            candidate,
58            BallCarryCalculator::min_duration_for_kind,
59        ));
60        Ok(())
61    }
62
63    fn finish(&mut self, _ctx: &AnalysisStateContext<'_>) -> SubtrActorResult<()> {
64        if let Some(sequence) = self
65            .tracker
66            .finish(BallCarryCalculator::min_duration_for_kind)
67        {
68            self.state.completed_sequences.push(sequence);
69        }
70        Ok(())
71    }
72
73    fn state(&self) -> &Self::State {
74        &self.state
75    }
76}
77
78pub(crate) fn boxed_default() -> Box<dyn AnalysisNodeDyn> {
79    Box::new(ContinuousBallControlNode::new())
80}