Skip to main content

subtr_actor/processor/
view.rs

1use super::*;
2
3/// Read-only processor surface consumed by collectors and stat calculators.
4///
5/// `ReplayProcessor` still owns replay traversal and actor-state mutation, but
6/// collectors should depend on this trait so the same collection pipeline can
7/// later be driven by non-replay state sources.
8pub trait ProcessorView {
9    fn get_replay_meta(&self) -> SubtrActorResult<ReplayMeta>;
10    fn get_replay_game_type_details(&self) -> ReplayGameTypeDetails {
11        self.get_replay_meta()
12            .map(|meta| meta.game_type)
13            .unwrap_or_default()
14    }
15    fn player_count(&self) -> usize;
16    fn iter_player_ids_in_order(&self) -> Box<dyn Iterator<Item = &PlayerId> + '_>;
17    fn current_in_game_team_player_counts(&self) -> [usize; 2];
18
19    fn get_seconds_remaining(&self) -> SubtrActorResult<i32>;
20    fn get_replicated_state_name(&self) -> SubtrActorResult<i32>;
21    fn get_replicated_game_state_time_remaining(&self) -> SubtrActorResult<i32>;
22    fn get_ball_has_been_hit(&self) -> SubtrActorResult<bool>;
23    fn get_ignore_ball_syncing(&self) -> SubtrActorResult<bool>;
24    fn get_team_scores(&self) -> SubtrActorResult<(i32, i32)>;
25    fn get_ball_hit_team_num(&self) -> SubtrActorResult<u8>;
26    fn get_scored_on_team_num(&self) -> SubtrActorResult<u8>;
27
28    fn get_normalized_ball_rigid_body(&self) -> SubtrActorResult<boxcars::RigidBody>;
29    fn get_velocity_applied_ball_rigid_body(
30        &self,
31        target_time: f32,
32    ) -> SubtrActorResult<boxcars::RigidBody>;
33    fn get_interpolated_ball_rigid_body(
34        &self,
35        target_time: f32,
36        close_enough_to_frame_time: f32,
37    ) -> SubtrActorResult<boxcars::RigidBody>;
38
39    fn get_normalized_player_rigid_body(
40        &self,
41        player_id: &PlayerId,
42    ) -> SubtrActorResult<boxcars::RigidBody>;
43    fn get_velocity_applied_player_rigid_body(
44        &self,
45        player_id: &PlayerId,
46        target_time: f32,
47    ) -> SubtrActorResult<boxcars::RigidBody>;
48    fn get_interpolated_player_rigid_body(
49        &self,
50        player_id: &PlayerId,
51        target_time: f32,
52        close_enough_to_frame_time: f32,
53    ) -> SubtrActorResult<boxcars::RigidBody>;
54
55    fn get_player_name(&self, player_id: &PlayerId) -> SubtrActorResult<String>;
56    fn get_player_car_hitbox(&self, player_id: &PlayerId) -> CarHitbox;
57    fn get_player_team_key(&self, player_id: &PlayerId) -> SubtrActorResult<String>;
58    fn get_player_is_team_0(&self, player_id: &PlayerId) -> SubtrActorResult<bool>;
59    fn get_player_id_from_car_id(&self, actor_id: &boxcars::ActorId) -> SubtrActorResult<PlayerId>;
60    fn get_player_boost_level(&self, player_id: &PlayerId) -> SubtrActorResult<f32>;
61    fn get_player_last_boost_level(&self, player_id: &PlayerId) -> SubtrActorResult<f32>;
62    fn get_player_boost_percentage(&self, player_id: &PlayerId) -> SubtrActorResult<f32>;
63    fn get_boost_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8>;
64    fn get_jump_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8>;
65    fn get_double_jump_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8>;
66    fn get_dodge_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8>;
67    fn get_powerslide_active(&self, player_id: &PlayerId) -> SubtrActorResult<bool>;
68    fn get_player_match_assists(&self, player_id: &PlayerId) -> SubtrActorResult<i32>;
69    fn get_player_match_goals(&self, player_id: &PlayerId) -> SubtrActorResult<i32>;
70    fn get_player_match_saves(&self, player_id: &PlayerId) -> SubtrActorResult<i32>;
71    fn get_player_match_score(&self, player_id: &PlayerId) -> SubtrActorResult<i32>;
72    fn get_player_match_shots(&self, player_id: &PlayerId) -> SubtrActorResult<i32>;
73
74    fn get_active_demos(&self) -> SubtrActorResult<Vec<DemolishAttribute>>;
75    fn demolishes(&self) -> &[DemolishInfo];
76    fn boost_pad_events(&self) -> &[BoostPadEvent];
77    fn touch_events(&self) -> &[TouchEvent];
78    fn dodge_refreshed_events(&self) -> &[DodgeRefreshedEvent];
79    fn player_stat_events(&self) -> &[PlayerStatEvent];
80    fn goal_events(&self) -> &[GoalEvent];
81    fn current_frame_active_demo_events(&self) -> &[DemoEventSample] {
82        &[]
83    }
84    fn current_frame_demolish_events(&self) -> &[DemolishInfo] {
85        &[]
86    }
87    fn current_frame_boost_pad_events(&self) -> &[BoostPadEvent];
88    fn current_frame_touch_events(&self) -> &[TouchEvent];
89    fn current_frame_dodge_refreshed_events(&self) -> &[DodgeRefreshedEvent];
90    fn current_frame_player_stat_events(&self) -> &[PlayerStatEvent];
91    fn current_frame_goal_events(&self) -> &[GoalEvent];
92}
93
94impl ProcessorView for ReplayProcessor<'_> {
95    fn get_replay_meta(&self) -> SubtrActorResult<ReplayMeta> {
96        ReplayProcessor::get_replay_meta(self)
97    }
98
99    fn get_replay_game_type_details(&self) -> ReplayGameTypeDetails {
100        ReplayProcessor::get_replay_game_type_details(self)
101    }
102
103    fn player_count(&self) -> usize {
104        ReplayProcessor::player_count(self)
105    }
106
107    fn iter_player_ids_in_order(&self) -> Box<dyn Iterator<Item = &PlayerId> + '_> {
108        Box::new(ReplayProcessor::iter_player_ids_in_order(self))
109    }
110
111    fn current_in_game_team_player_counts(&self) -> [usize; 2] {
112        ReplayProcessor::current_in_game_team_player_counts(self)
113    }
114
115    fn get_seconds_remaining(&self) -> SubtrActorResult<i32> {
116        ReplayProcessor::get_seconds_remaining(self)
117    }
118
119    fn get_replicated_state_name(&self) -> SubtrActorResult<i32> {
120        ReplayProcessor::get_replicated_state_name(self)
121    }
122
123    fn get_replicated_game_state_time_remaining(&self) -> SubtrActorResult<i32> {
124        ReplayProcessor::get_replicated_game_state_time_remaining(self)
125    }
126
127    fn get_ball_has_been_hit(&self) -> SubtrActorResult<bool> {
128        ReplayProcessor::get_ball_has_been_hit(self)
129    }
130
131    fn get_ignore_ball_syncing(&self) -> SubtrActorResult<bool> {
132        ReplayProcessor::get_ignore_ball_syncing(self)
133    }
134
135    fn get_team_scores(&self) -> SubtrActorResult<(i32, i32)> {
136        ReplayProcessor::get_team_scores(self)
137    }
138
139    fn get_ball_hit_team_num(&self) -> SubtrActorResult<u8> {
140        ReplayProcessor::get_ball_hit_team_num(self)
141    }
142
143    fn get_scored_on_team_num(&self) -> SubtrActorResult<u8> {
144        ReplayProcessor::get_scored_on_team_num(self)
145    }
146
147    fn get_normalized_ball_rigid_body(&self) -> SubtrActorResult<boxcars::RigidBody> {
148        ReplayProcessor::get_normalized_ball_rigid_body(self)
149    }
150
151    fn get_velocity_applied_ball_rigid_body(
152        &self,
153        target_time: f32,
154    ) -> SubtrActorResult<boxcars::RigidBody> {
155        ReplayProcessor::get_velocity_applied_ball_rigid_body(self, target_time)
156    }
157
158    fn get_interpolated_ball_rigid_body(
159        &self,
160        target_time: f32,
161        close_enough_to_frame_time: f32,
162    ) -> SubtrActorResult<boxcars::RigidBody> {
163        ReplayProcessor::get_interpolated_ball_rigid_body(
164            self,
165            target_time,
166            close_enough_to_frame_time,
167        )
168    }
169
170    fn get_normalized_player_rigid_body(
171        &self,
172        player_id: &PlayerId,
173    ) -> SubtrActorResult<boxcars::RigidBody> {
174        ReplayProcessor::get_normalized_player_rigid_body(self, player_id)
175    }
176
177    fn get_velocity_applied_player_rigid_body(
178        &self,
179        player_id: &PlayerId,
180        target_time: f32,
181    ) -> SubtrActorResult<boxcars::RigidBody> {
182        ReplayProcessor::get_velocity_applied_player_rigid_body(self, player_id, target_time)
183    }
184
185    fn get_interpolated_player_rigid_body(
186        &self,
187        player_id: &PlayerId,
188        target_time: f32,
189        close_enough_to_frame_time: f32,
190    ) -> SubtrActorResult<boxcars::RigidBody> {
191        ReplayProcessor::get_interpolated_player_rigid_body(
192            self,
193            player_id,
194            target_time,
195            close_enough_to_frame_time,
196        )
197    }
198
199    fn get_player_name(&self, player_id: &PlayerId) -> SubtrActorResult<String> {
200        ReplayProcessor::get_player_name(self, player_id)
201    }
202
203    fn get_player_car_hitbox(&self, player_id: &PlayerId) -> CarHitbox {
204        ReplayProcessor::get_player_car_hitbox(self, player_id)
205    }
206
207    fn get_player_team_key(&self, player_id: &PlayerId) -> SubtrActorResult<String> {
208        ReplayProcessor::get_player_team_key(self, player_id)
209    }
210
211    fn get_player_is_team_0(&self, player_id: &PlayerId) -> SubtrActorResult<bool> {
212        ReplayProcessor::get_player_is_team_0(self, player_id)
213    }
214
215    fn get_player_id_from_car_id(&self, actor_id: &boxcars::ActorId) -> SubtrActorResult<PlayerId> {
216        ReplayProcessor::get_player_id_from_car_id(self, actor_id)
217    }
218
219    fn get_player_boost_level(&self, player_id: &PlayerId) -> SubtrActorResult<f32> {
220        ReplayProcessor::get_player_boost_level(self, player_id)
221    }
222
223    fn get_player_last_boost_level(&self, player_id: &PlayerId) -> SubtrActorResult<f32> {
224        ReplayProcessor::get_player_last_boost_level(self, player_id)
225    }
226
227    fn get_player_boost_percentage(&self, player_id: &PlayerId) -> SubtrActorResult<f32> {
228        ReplayProcessor::get_player_boost_percentage(self, player_id)
229    }
230
231    fn get_boost_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8> {
232        ReplayProcessor::get_boost_active(self, player_id)
233    }
234
235    fn get_jump_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8> {
236        ReplayProcessor::get_jump_active(self, player_id)
237    }
238
239    fn get_double_jump_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8> {
240        ReplayProcessor::get_double_jump_active(self, player_id)
241    }
242
243    fn get_dodge_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8> {
244        ReplayProcessor::get_dodge_active(self, player_id)
245    }
246
247    fn get_powerslide_active(&self, player_id: &PlayerId) -> SubtrActorResult<bool> {
248        ReplayProcessor::get_powerslide_active(self, player_id)
249    }
250
251    fn get_player_match_assists(&self, player_id: &PlayerId) -> SubtrActorResult<i32> {
252        ReplayProcessor::get_player_match_assists(self, player_id)
253    }
254
255    fn get_player_match_goals(&self, player_id: &PlayerId) -> SubtrActorResult<i32> {
256        ReplayProcessor::get_player_match_goals(self, player_id)
257    }
258
259    fn get_player_match_saves(&self, player_id: &PlayerId) -> SubtrActorResult<i32> {
260        ReplayProcessor::get_player_match_saves(self, player_id)
261    }
262
263    fn get_player_match_score(&self, player_id: &PlayerId) -> SubtrActorResult<i32> {
264        ReplayProcessor::get_player_match_score(self, player_id)
265    }
266
267    fn get_player_match_shots(&self, player_id: &PlayerId) -> SubtrActorResult<i32> {
268        ReplayProcessor::get_player_match_shots(self, player_id)
269    }
270
271    fn get_active_demos(&self) -> SubtrActorResult<Vec<DemolishAttribute>> {
272        ReplayProcessor::get_active_demos(self).map(Iterator::collect)
273    }
274
275    fn demolishes(&self) -> &[DemolishInfo] {
276        &self.demolishes
277    }
278
279    fn boost_pad_events(&self) -> &[BoostPadEvent] {
280        &self.boost_pad_events
281    }
282
283    fn touch_events(&self) -> &[TouchEvent] {
284        &self.touch_events
285    }
286
287    fn dodge_refreshed_events(&self) -> &[DodgeRefreshedEvent] {
288        &self.dodge_refreshed_events
289    }
290
291    fn player_stat_events(&self) -> &[PlayerStatEvent] {
292        &self.player_stat_events
293    }
294
295    fn goal_events(&self) -> &[GoalEvent] {
296        &self.goal_events
297    }
298
299    fn current_frame_boost_pad_events(&self) -> &[BoostPadEvent] {
300        ReplayProcessor::current_frame_boost_pad_events(self)
301    }
302
303    fn current_frame_touch_events(&self) -> &[TouchEvent] {
304        ReplayProcessor::current_frame_touch_events(self)
305    }
306
307    fn current_frame_dodge_refreshed_events(&self) -> &[DodgeRefreshedEvent] {
308        ReplayProcessor::current_frame_dodge_refreshed_events(self)
309    }
310
311    fn current_frame_player_stat_events(&self) -> &[PlayerStatEvent] {
312        ReplayProcessor::current_frame_player_stat_events(self)
313    }
314
315    fn current_frame_goal_events(&self) -> &[GoalEvent] {
316        ReplayProcessor::current_frame_goal_events(self)
317    }
318}