Skip to main content

subtr_actor/stats/analysis_graph/nodes/
loose_possession.rs

1use super::*;
2use crate::stats::calculators::*;
3use crate::*;
4
5/// Derives loose team possession (last team to touch owns the ball until the
6/// opponent takes it away) directly from touch and live-play state.
7pub struct LoosePossessionNode {
8    calculator: LoosePossessionCalculator,
9}
10
11impl LoosePossessionNode {
12    pub fn new() -> Self {
13        Self {
14            calculator: LoosePossessionCalculator::new(),
15        }
16    }
17}
18
19impl Default for LoosePossessionNode {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25impl AnalysisNode for LoosePossessionNode {
26    type State = LoosePossessionCalculator;
27
28    fn name(&self) -> &'static str {
29        "loose_possession"
30    }
31
32    fn emitted_events(&self) -> &'static [crate::stats::calculators::EmittedEvent] {
33        crate::stats::calculators::LOOSE_POSSESSION_EMITTED_EVENTS
34    }
35
36    fn dependencies(&self) -> NodeDependencies {
37        vec![
38            frame_info_dependency(),
39            touch_state_dependency(),
40            live_play_dependency(),
41        ]
42    }
43
44    fn evaluate(&mut self, ctx: &AnalysisStateContext<'_>) -> SubtrActorResult<()> {
45        self.calculator.update(
46            ctx.get::<FrameInfo>()?,
47            ctx.get::<TouchState>()?,
48            ctx.get::<LivePlayState>()?,
49        )
50    }
51
52    fn finish(&mut self, _ctx: &AnalysisStateContext<'_>) -> SubtrActorResult<()> {
53        self.calculator.finish();
54        Ok(())
55    }
56
57    fn state(&self) -> &Self::State {
58        &self.calculator
59    }
60}
61
62pub(crate) fn boxed_default() -> Box<dyn AnalysisNodeDyn> {
63    Box::new(LoosePossessionNode::new())
64}