Skip to main content

subtr_actor/stats/analysis_graph/nodes/
rotation.rs

1use super::*;
2use crate::stats::calculators::*;
3use crate::*;
4
5/// Tracks rotational roles (first/second/third man) from positions and events during live play.
6pub struct RotationNode {
7    calculator: RotationCalculator,
8}
9
10impl RotationNode {
11    pub fn new() -> Self {
12        Self::with_config(RotationCalculatorConfig::default())
13    }
14
15    pub fn with_config(config: RotationCalculatorConfig) -> Self {
16        Self {
17            calculator: RotationCalculator::with_config(config),
18        }
19    }
20}
21
22impl Default for RotationNode {
23    fn default() -> Self {
24        Self::new()
25    }
26}
27
28impl AnalysisNode for RotationNode {
29    type State = RotationCalculator;
30
31    fn name(&self) -> &'static str {
32        "rotation"
33    }
34
35    fn emitted_events(&self) -> &'static [crate::stats::calculators::EmittedEvent] {
36        crate::stats::calculators::ROTATION_EMITTED_EVENTS
37    }
38
39    fn dependencies(&self) -> NodeDependencies {
40        vec![
41            frame_info_dependency(),
42            gameplay_state_dependency(),
43            ball_frame_state_dependency(),
44            player_frame_state_dependency(),
45            frame_events_state_dependency(),
46            live_play_dependency(),
47        ]
48    }
49
50    fn evaluate(&mut self, ctx: &AnalysisStateContext<'_>) -> SubtrActorResult<()> {
51        self.calculator.update(
52            ctx.get::<FrameInfo>()?,
53            ctx.get::<GameplayState>()?,
54            ctx.get::<BallFrameState>()?,
55            ctx.get::<PlayerFrameState>()?,
56            ctx.get::<FrameEventsState>()?,
57            ctx.get::<LivePlayState>()?,
58        )
59    }
60
61    fn finish(&mut self, _ctx: &AnalysisStateContext<'_>) -> SubtrActorResult<()> {
62        self.calculator.flush_pending_events();
63        Ok(())
64    }
65
66    fn state(&self) -> &Self::State {
67        &self.calculator
68    }
69}
70
71pub(crate) fn boxed_default() -> Box<dyn AnalysisNodeDyn> {
72    Box::new(RotationNode::new())
73}