Skip to main content

subtr_actor/stats/analysis_graph/
collector.rs

1use super::graph::AnalysisGraph;
2use crate::stats::calculators::FrameInput;
3use crate::*;
4
5#[allow(dead_code)]
6pub struct AnalysisNodeCollector {
7    graph: AnalysisGraph,
8    last_sample_time: Option<f32>,
9    last_replay_meta_player_count: Option<usize>,
10    last_demolish_count: usize,
11    last_boost_pad_event_count: usize,
12    last_touch_event_count: usize,
13    last_dodge_refreshed_event_count: usize,
14    last_player_stat_event_count: usize,
15    last_goal_event_count: usize,
16}
17
18#[allow(dead_code)]
19impl AnalysisNodeCollector {
20    pub fn new(mut graph: AnalysisGraph) -> Self {
21        graph.register_input_state::<FrameInput>();
22        Self {
23            graph,
24            last_sample_time: None,
25            last_replay_meta_player_count: None,
26            last_demolish_count: 0,
27            last_boost_pad_event_count: 0,
28            last_touch_event_count: 0,
29            last_dodge_refreshed_event_count: 0,
30            last_player_stat_event_count: 0,
31            last_goal_event_count: 0,
32        }
33    }
34
35    pub fn graph(&self) -> &AnalysisGraph {
36        &self.graph
37    }
38
39    pub fn graph_mut(&mut self) -> &mut AnalysisGraph {
40        &mut self.graph
41    }
42
43    pub fn into_graph(self) -> AnalysisGraph {
44        self.graph
45    }
46}
47
48impl Collector for AnalysisNodeCollector {
49    fn process_frame(
50        &mut self,
51        processor: &dyn ProcessorView,
52        _frame: &boxcars::Frame,
53        frame_number: usize,
54        current_time: f32,
55    ) -> SubtrActorResult<TimeAdvance> {
56        let player_count = processor.player_count();
57        if self.last_replay_meta_player_count != Some(player_count) {
58            self.graph.on_replay_meta(&processor.get_replay_meta()?)?;
59            self.last_replay_meta_player_count = Some(player_count);
60        }
61
62        let dt = self
63            .last_sample_time
64            .map(|last_time| (current_time - last_time).max(0.0))
65            .unwrap_or(0.0);
66        let frame_input = FrameInput::aggregate(
67            processor,
68            frame_number,
69            current_time,
70            dt,
71            self.last_demolish_count,
72            self.last_boost_pad_event_count,
73            self.last_touch_event_count,
74            self.last_dodge_refreshed_event_count,
75            self.last_player_stat_event_count,
76            self.last_goal_event_count,
77        );
78        self.graph.evaluate_with_state(&frame_input)?;
79        self.last_sample_time = Some(current_time);
80        self.last_demolish_count = processor.demolishes().len();
81        self.last_boost_pad_event_count = processor.boost_pad_events().len();
82        self.last_touch_event_count = processor.touch_events().len();
83        self.last_dodge_refreshed_event_count = processor.dodge_refreshed_events().len();
84        self.last_player_stat_event_count = processor.player_stat_events().len();
85        self.last_goal_event_count = processor.goal_events().len();
86
87        Ok(TimeAdvance::NextFrame)
88    }
89
90    fn finish_replay(&mut self, _processor: &dyn ProcessorView) -> SubtrActorResult<()> {
91        self.graph.finish()
92    }
93}