Skip to main content

subtr_actor/stats/export/
touch.rs

1use crate::*;
2
3use super::*;
4
5impl StatFieldProvider for TouchStats {
6    fn visit_stat_fields(&self, visitor: &mut dyn FnMut(ExportedStat)) {
7        visitor(ExportedStat::unsigned(
8            "touch",
9            "touch_count",
10            StatUnit::Count,
11            self.touch_count,
12        ));
13        visitor(ExportedStat::unsigned(
14            "touch",
15            "dribble_touch_count",
16            StatUnit::Count,
17            self.dribble_touch_count,
18        ));
19        visitor(ExportedStat::unsigned(
20            "touch",
21            "control_touch_count",
22            StatUnit::Count,
23            self.control_touch_count,
24        ));
25        visitor(ExportedStat::unsigned(
26            "touch",
27            "medium_hit_count",
28            StatUnit::Count,
29            self.medium_hit_count,
30        ));
31        visitor(ExportedStat::unsigned(
32            "touch",
33            "hard_hit_count",
34            StatUnit::Count,
35            self.hard_hit_count,
36        ));
37        visitor(ExportedStat::unsigned(
38            "touch",
39            "aerial_touch_count",
40            StatUnit::Count,
41            self.aerial_touch_count,
42        ));
43        visitor(ExportedStat::unsigned(
44            "touch",
45            "high_aerial_touch_count",
46            StatUnit::Count,
47            self.high_aerial_touch_count,
48        ));
49        for entry in self.complete_labeled_touch_counts().entries {
50            visitor(ExportedStat::unsigned_labeled(
51                "touch",
52                "touch_count",
53                StatUnit::Count,
54                entry.labels,
55                entry.count,
56            ));
57        }
58        visitor(ExportedStat::unsigned(
59            "touch",
60            "is_last_touch",
61            StatUnit::Count,
62            u32::from(self.is_last_touch),
63        ));
64        if let Some(value) = self.last_touch_time {
65            visitor(ExportedStat::float(
66                "touch",
67                "last_touch_time",
68                StatUnit::Seconds,
69                value,
70            ));
71        }
72        if let Some(value) = self.last_touch_frame {
73            visitor(ExportedStat::unsigned(
74                "touch",
75                "last_touch_frame",
76                StatUnit::Count,
77                u32::try_from(value).unwrap_or(u32::MAX),
78            ));
79        }
80        if let Some(value) = self.time_since_last_touch {
81            visitor(ExportedStat::float(
82                "touch",
83                "time_since_last_touch",
84                StatUnit::Seconds,
85                value,
86            ));
87        }
88        if let Some(value) = self.frames_since_last_touch {
89            visitor(ExportedStat::unsigned(
90                "touch",
91                "frames_since_last_touch",
92                StatUnit::Count,
93                u32::try_from(value).unwrap_or(u32::MAX),
94            ));
95        }
96        if let Some(value) = self.last_ball_speed_change {
97            visitor(ExportedStat::float(
98                "touch",
99                "last_ball_speed_change",
100                StatUnit::UnrealUnitsPerSecond,
101                value,
102            ));
103        }
104        visitor(ExportedStat::float(
105            "touch",
106            "average_ball_speed_change",
107            StatUnit::UnrealUnitsPerSecond,
108            self.average_ball_speed_change(),
109        ));
110        visitor(ExportedStat::float(
111            "touch",
112            "max_ball_speed_change",
113            StatUnit::UnrealUnitsPerSecond,
114            self.max_ball_speed_change,
115        ));
116    }
117}
118
119#[cfg(test)]
120mod tests {
121    use super::*;
122
123    #[test]
124    fn touch_export_includes_labeled_touch_count_stats() {
125        let mut stats = TouchStats {
126            touch_count: 2,
127            ..Default::default()
128        };
129        stats.labeled_touch_counts.increment([
130            StatLabel::new("kind", "hard_hit"),
131            StatLabel::new("height_band", "high_air"),
132        ]);
133        stats.labeled_touch_counts.increment([
134            StatLabel::new("kind", "hard_hit"),
135            StatLabel::new("height_band", "high_air"),
136        ]);
137
138        let labeled_touch_stats: Vec<_> = stats
139            .stat_fields()
140            .into_iter()
141            .filter(|stat| {
142                stat.descriptor.name == "touch_count"
143                    && stat.descriptor.variant == LABELED_STAT_VARIANT
144            })
145            .collect();
146
147        assert_eq!(labeled_touch_stats.len(), 12);
148        assert_eq!(
149            labeled_touch_stats
150                .iter()
151                .find(|stat| {
152                    stat.descriptor.labels
153                        == vec![
154                            StatLabel::new("height_band", "high_air"),
155                            StatLabel::new("kind", "hard_hit"),
156                        ]
157                })
158                .unwrap()
159                .descriptor
160                .labels,
161            vec![
162                StatLabel::new("height_band", "high_air"),
163                StatLabel::new("kind", "hard_hit"),
164            ]
165        );
166        assert_eq!(
167            labeled_touch_stats
168                .iter()
169                .find(|stat| {
170                    stat.descriptor.labels
171                        == vec![
172                            StatLabel::new("height_band", "high_air"),
173                            StatLabel::new("kind", "hard_hit"),
174                        ]
175                })
176                .unwrap()
177                .value,
178            StatValue::Unsigned(2)
179        );
180        assert_eq!(
181            labeled_touch_stats
182                .iter()
183                .find(|stat| {
184                    stat.descriptor.labels
185                        == vec![
186                            StatLabel::new("height_band", "ground"),
187                            StatLabel::new("kind", "dribble"),
188                        ]
189                })
190                .unwrap()
191                .value,
192            StatValue::Unsigned(0)
193        );
194    }
195}