1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
pub mod decorator;
pub mod ndarray;
pub mod replay_data;

pub use self::ndarray::*;
pub use decorator::*;
pub use replay_data::*;

use crate::*;
use boxcars;

/// Enum used to control the progress of time during replay processing.
pub enum TimeAdvance {
    /// Move forward in time by a specified amount.
    Time(f32),
    /// Advance to the next frame.
    NextFrame,
}

/// Trait for types that collect data from a replay.
///
/// A `Collector` processes frames from a replay, potentially using a
/// [`ReplayProcessor`] for access to additional replay data and context. It
/// determines the pace of replay progression via the [`TimeAdvance`] return
/// value.
pub trait Collector: Sized {
    /// Process a single frame from a replay.
    ///
    /// # Arguments
    ///
    /// * `processor` - The [`ReplayProcessor`] providing context for the replay.
    /// * `frame` - The [`boxcars::Frame`] to process.
    /// * `frame_number` - The number of the current frame.
    /// * `current_time` - The current target time in the replay.
    ///
    /// # Returns
    ///
    /// Returns a [`TimeAdvance`] enum which determines the next step in replay
    /// progression.
    fn process_frame(
        &mut self,
        processor: &ReplayProcessor,
        frame: &boxcars::Frame,
        frame_number: usize,
        current_time: f32,
    ) -> SubtrActorResult<TimeAdvance>;

    /// Process an entire replay.
    ///
    /// # Arguments
    ///
    /// * `replay` - The [`boxcars::Replay`] to process.
    ///
    /// # Returns
    ///
    /// Returns the [`Collector`] itself, potentially modified by the processing
    /// of the replay.
    fn process_replay(mut self, replay: &boxcars::Replay) -> SubtrActorResult<Self> {
        ReplayProcessor::new(replay)?.process(&mut self)?;
        Ok(self)
    }
}

impl<G> Collector for G
where
    G: FnMut(&ReplayProcessor, &boxcars::Frame, usize, f32) -> SubtrActorResult<TimeAdvance>,
{
    fn process_frame(
        &mut self,
        processor: &ReplayProcessor,
        frame: &boxcars::Frame,
        frame_number: usize,
        current_time: f32,
    ) -> SubtrActorResult<TimeAdvance> {
        self(processor, frame, frame_number, current_time)
    }
}