Skip to main content

subtr_actor/stats/analysis_graph/
collector.rs

1use super::graph::AnalysisGraph;
2use crate::stats::calculators::{FrameInput, ReplayFrameInputBuilder};
3use crate::*;
4
5pub struct AnalysisNodeCollector {
6    graph: AnalysisGraph,
7    frame_input_builder: ReplayFrameInputBuilder,
8    last_sample_time: Option<f32>,
9    last_replay_meta_player_count: Option<usize>,
10}
11
12impl AnalysisNodeCollector {
13    pub fn new(mut graph: AnalysisGraph) -> Self {
14        graph.register_input_state::<FrameInput>();
15        Self {
16            graph,
17            frame_input_builder: ReplayFrameInputBuilder::default(),
18            last_sample_time: None,
19            last_replay_meta_player_count: None,
20        }
21    }
22
23    pub fn graph(&self) -> &AnalysisGraph {
24        &self.graph
25    }
26
27    pub fn graph_mut(&mut self) -> &mut AnalysisGraph {
28        &mut self.graph
29    }
30
31    pub fn into_graph(self) -> AnalysisGraph {
32        self.graph
33    }
34}
35
36impl Collector for AnalysisNodeCollector {
37    fn process_frame(
38        &mut self,
39        processor: &dyn ProcessorView,
40        _frame: &boxcars::Frame,
41        frame_number: usize,
42        current_time: f32,
43    ) -> SubtrActorResult<TimeAdvance> {
44        let player_count = processor.player_count();
45        if self.last_replay_meta_player_count != Some(player_count) {
46            self.graph.on_replay_meta(&processor.get_replay_meta()?)?;
47            self.last_replay_meta_player_count = Some(player_count);
48        }
49
50        let dt = self
51            .last_sample_time
52            .map(|last_time| (current_time - last_time).max(0.0))
53            .unwrap_or(0.0);
54        let frame_input =
55            self.frame_input_builder
56                .aggregate(processor, frame_number, current_time, dt);
57        self.graph.evaluate_with_state(&frame_input)?;
58        self.last_sample_time = Some(current_time);
59
60        Ok(TimeAdvance::NextFrame)
61    }
62
63    fn finish_replay(&mut self, _processor: &dyn ProcessorView) -> SubtrActorResult<()> {
64        self.graph.finish()
65    }
66}