subtr_actor/stats/accumulators/
controlled_play.rs1use super::*;
2
3#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, ts_rs::TS)]
5#[ts(export)]
6pub struct ControlledPlayStats {
7 pub count: u32,
8 pub total_time: f32,
9 pub longest_time: f32,
10 pub touch_count: u32,
11 pub total_advance_distance: f32,
12}
13
14impl ControlledPlayStats {
15 pub fn avg_time(&self) -> f32 {
16 if self.count == 0 {
17 0.0
18 } else {
19 self.total_time / self.count as f32
20 }
21 }
22}
23
24#[derive(Debug, Clone, Default, PartialEq)]
26pub struct ControlledPlayStatsAccumulator {
27 player_stats: HashMap<PlayerId, ControlledPlayStats>,
28 team_zero_stats: ControlledPlayStats,
29 team_one_stats: ControlledPlayStats,
30}
31
32impl ControlledPlayStatsAccumulator {
33 pub fn new() -> Self {
34 Self::default()
35 }
36
37 pub fn player_stats(&self) -> &HashMap<PlayerId, ControlledPlayStats> {
38 &self.player_stats
39 }
40
41 pub fn team_zero_stats(&self) -> &ControlledPlayStats {
42 &self.team_zero_stats
43 }
44
45 pub fn team_one_stats(&self) -> &ControlledPlayStats {
46 &self.team_one_stats
47 }
48
49 pub fn apply_event(&mut self, event: &ControlledPlayEvent) {
50 Self::apply_event_to_stats(
51 self.player_stats
52 .entry(event.player_id.clone())
53 .or_default(),
54 event,
55 );
56 let team_stats = if event.is_team_0 {
57 &mut self.team_zero_stats
58 } else {
59 &mut self.team_one_stats
60 };
61 Self::apply_event_to_stats(team_stats, event);
62 }
63
64 fn apply_event_to_stats(stats: &mut ControlledPlayStats, event: &ControlledPlayEvent) {
65 stats.count += 1;
66 stats.total_time += event.duration;
67 stats.longest_time = stats.longest_time.max(event.duration);
68 stats.touch_count += event.touch_count;
69 stats.total_advance_distance += event.total_advance_distance;
70 }
71}