pub struct ReplayProcessor<'a> {
Show 15 fields pub replay: &'a Replay, pub actor_state: ActorStateModeler, pub object_id_to_name: HashMap<ObjectId, String>, pub name_to_object_id: HashMap<String, ObjectId>, pub ball_actor_id: Option<ActorId>, pub team_zero: Vec<PlayerId>, pub team_one: Vec<PlayerId>, pub player_to_actor_id: HashMap<PlayerId, ActorId>, pub player_to_car: HashMap<ActorId, ActorId>, pub player_to_team: HashMap<ActorId, ActorId>, pub car_to_boost: HashMap<ActorId, ActorId>, pub car_to_jump: HashMap<ActorId, ActorId>, pub car_to_double_jump: HashMap<ActorId, ActorId>, pub car_to_dodge: HashMap<ActorId, ActorId>, pub demolishes: Vec<DemolishInfo>, /* private fields */
}
Expand description

The ReplayProcessor struct is a pivotal component in subtr-actor’s replay parsing pipeline. It is designed to process and traverse an actor graph of a Rocket League replay, and expose methods for collectors to gather specific data points as it progresses through the replay.

The processor pushes frames from a replay through an ActorStateModeler, which models the state all actors in the replay at a given point in time. The ReplayProcessor also maintains various mappings to allow efficient lookup and traversal of the actor graph, thus assisting Collector instances in their data accumulation tasks.

The primary method of this struct is process, which takes a collector and processes the replay. As it traverses the replay, it calls the Collector::process_frame method of the passed collector, passing the current frame along with its contextual data. This allows the collector to extract specific data from each frame as needed.

The ReplayProcessor also provides a number of helper methods for navigating the actor graph and extracting information, such as get_ball_rigid_body, get_player_name, get_player_team_key, get_player_is_team_0, and get_player_rigid_body.

See Also

  • ActorStateModeler: A struct used to model the states of multiple actors at a given point in time.
  • Collector: A trait implemented by objects that wish to collect data as the ReplayProcessor processes a replay.

Fields§

§replay: &'a Replay§actor_state: ActorStateModeler§object_id_to_name: HashMap<ObjectId, String>§name_to_object_id: HashMap<String, ObjectId>§ball_actor_id: Option<ActorId>§team_zero: Vec<PlayerId>§team_one: Vec<PlayerId>§player_to_actor_id: HashMap<PlayerId, ActorId>§player_to_car: HashMap<ActorId, ActorId>§player_to_team: HashMap<ActorId, ActorId>§car_to_boost: HashMap<ActorId, ActorId>§car_to_jump: HashMap<ActorId, ActorId>§car_to_double_jump: HashMap<ActorId, ActorId>§car_to_dodge: HashMap<ActorId, ActorId>§demolishes: Vec<DemolishInfo>

Implementations§

source§

impl<'a> ReplayProcessor<'a>

source

pub fn new(replay: &'a Replay) -> SubtrActorResult<Self>

Constructs a new ReplayProcessor instance with the provided replay.

Arguments
Returns

Returns a SubtrActorResult of ReplayProcessor. In the process of initialization, the ReplayProcessor: - Maps each object id in the replay to its corresponding name. - Initializes empty state and attribute maps. - Sets the player order from either replay headers or frames, if available.

source

pub fn process<H: Collector>(&mut self, handler: &mut H) -> SubtrActorResult<()>

Self::process takes a Collector as an argument and iterates over each frame in the replay, updating the internal state of the processor and other relevant mappings based on the current frame.

After each a frame is processed, Collector::process_frame of the collector is called. The TimeAdvance return value of this call into Collector::process_frame is used to determine what happens next: in the case of TimeAdvance::Time, the notion of current time is advanced by the provided amount, and only the timestamp of the frame is exceeded, do we process the next frame. This mechanism allows fine grained control of frame processing, and the frequency of invocations of the Collector. If time is advanced by less than the delay between frames, the collector will be called more than once per frame, and can use functions like Self::get_interpolated_player_rigid_body to get values that are interpolated between frames. Its also possible to skip over frames by providing time advance values that are sufficiently large.

At the end of processing, it checks to make sure that no unknown players were encountered during the replay. If any unknown players are found, an error is returned.

source

pub fn reset(&mut self)

Reset the state of the ReplayProcessor.

source

pub fn process_long_enough_to_get_actor_ids(&mut self) -> SubtrActorResult<()>

Processes the replay until it has gathered enough information to map players to their actor IDs.

This function is designed to ensure that each player that participated in the game is associated with a corresponding actor ID. It runs the processing operation for approximately the first 10 seconds of the replay (10 * 30 frames), as this time span is generally sufficient to identify all players.

Note that this function is particularly necessary because the headers of replays sometimes omit some players.

Errors

If any error other than FinishProcessingEarly occurs during the processing operation, it is propagated up by this function.

source

pub fn check_player_id_set(&self) -> SubtrActorResult<()>

source

pub fn process_and_get_replay_meta(&mut self) -> SubtrActorResult<ReplayMeta>

Processes the replay enough to get the actor IDs and then retrieves the replay metadata.

This method is a convenience function that combines the functionalities of process_long_enough_to_get_actor_ids and get_replay_meta into a single operation. It’s meant to be used when you don’t necessarily want to process the whole replay and need only the replay’s metadata.

source

pub fn get_replay_meta(&self) -> SubtrActorResult<ReplayMeta>

Retrieves the replay metadata.

This function collects information about each player in the replay and groups them by team. For each player, it gets the player’s name and statistics. All this information is then wrapped into a ReplayMeta object along with the properties from the replay.

source

pub fn find_update_in_direction( &self, current_index: usize, actor_id: &ActorId, object_id: &ObjectId, direction: SearchDirection ) -> SubtrActorResult<(Attribute, usize)>

Searches for the next or previous update for a specified actor and object in the replay’s network frames.

This method uses the find_in_direction function to search through the network frames of the replay to find the next (or previous, depending on the direction provided) attribute update for a specified actor and object.

Arguments
  • current_index - The index of the network frame from where the search should start.
  • actor_id - The ID of the actor for which the update is being searched.
  • object_id - The ID of the object associated with the actor for which the update is being searched.
  • direction - The direction of search, specified as either SearchDirection::Backward or SearchDirection::Forward.
Returns

If a matching update is found, this function returns a SubtrActorResult tuple containing the found attribute and its index in the replay’s network frames.

Errors

If no matching update is found, or if the replay has no network frames, this function returns a SubtrActorError. Specifically, it returns NoUpdateAfterFrame error variant if no update is found after the specified frame, or NoNetworkFrames if the replay lacks network frames.

source

pub fn get_active_demolish_fx( &self ) -> SubtrActorResult<impl Iterator<Item = &Box<DemolishFx>>>

Provides an iterator over the active demolition effects, boxcars::DemolishFx, in the current frame.

source

pub fn get_interpolated_actor_rigid_body( &self, actor_id: &ActorId, time: f32, close_enough: f32 ) -> SubtrActorResult<RigidBody>

This function first retrieves the actor’s RigidBody at the current frame. If the time difference between the current frame and the provided time is within the close_enough threshold, the function returns the current frame’s RigidBody.

If the RigidBody at the exact time is not available, the function searches in the appropriate direction (either forwards or backwards in time) to find another RigidBody to interpolate from. If the found RigidBody’s time is within the close_enough threshold, it is returned.

Otherwise, it interpolates between the two RigidBodys (from the current frame and the found frame) to produce a RigidBody for the specified time. This is done using the get_interpolated_rigid_body function from the util module.

Arguments
  • actor_id - The ID of the actor whose RigidBody is to be retrieved.
  • time - The time at which the actor’s RigidBody is to be retrieved.
  • close_enough - The acceptable threshold for time difference when determining if a RigidBody is close enough to the desired time to not require interpolation.
Returns

A RigidBody for the actor at the specified time.

source

pub fn get_ball_actor_id(&self) -> SubtrActorResult<ActorId>

source

pub fn get_metadata_actor_id(&self) -> SubtrActorResult<&ActorId>

source

pub fn get_player_actor_id( &self, player_id: &PlayerId ) -> SubtrActorResult<ActorId>

source

pub fn get_car_actor_id( &self, player_id: &PlayerId ) -> SubtrActorResult<ActorId>

source

pub fn get_car_connected_actor_id( &self, player_id: &PlayerId, map: &HashMap<ActorId, ActorId>, name: &'static str ) -> SubtrActorResult<ActorId>

source

pub fn get_boost_actor_id( &self, player_id: &PlayerId ) -> SubtrActorResult<ActorId>

source

pub fn get_jump_actor_id( &self, player_id: &PlayerId ) -> SubtrActorResult<ActorId>

source

pub fn get_double_jump_actor_id( &self, player_id: &PlayerId ) -> SubtrActorResult<ActorId>

source

pub fn get_dodge_actor_id( &self, player_id: &PlayerId ) -> SubtrActorResult<ActorId>

source

pub fn get_actor_rigid_body( &self, actor_id: &ActorId ) -> SubtrActorResult<(&RigidBody, &usize)>

source

pub fn iter_player_ids_in_order(&self) -> impl Iterator<Item = &PlayerId>

source

pub fn player_count(&self) -> usize

source

pub fn iter_actors_by_type( &self, name: &'static str ) -> Option<impl Iterator<Item = (&ActorId, &ActorState)>>

source

pub fn iter_actors_by_object_id<'b>( &'b self, object_id: &'b ObjectId ) -> impl Iterator<Item = (&'b ActorId, &'b ActorState)> + 'b

source

pub fn get_seconds_remaining(&self) -> SubtrActorResult<i32>

Returns the remaining time in seconds in the game as an i32.

source

pub fn get_ignore_ball_syncing(&self) -> SubtrActorResult<bool>

Returns a boolean indicating whether ball syncing is ignored.

source

pub fn get_ball_rigid_body(&self) -> SubtrActorResult<&RigidBody>

Returns a reference to the RigidBody of the ball.

source

pub fn ball_rigid_body_exists(&self) -> SubtrActorResult<bool>

Returns a boolean indicating whether the ball’s RigidBody exists and is not sleeping.

source

pub fn get_ball_rigid_body_and_updated( &self ) -> SubtrActorResult<(&RigidBody, &usize)>

Returns a reference to the ball’s RigidBody and its last updated frame.

source

pub fn get_velocity_applied_ball_rigid_body( &self, target_time: f32 ) -> SubtrActorResult<RigidBody>

Returns a RigidBody of the ball with applied velocity at the target time.

source

pub fn get_interpolated_ball_rigid_body( &self, time: f32, close_enough: f32 ) -> SubtrActorResult<RigidBody>

Returns an interpolated RigidBody of the ball at a specified time.

source

pub fn get_player_name(&self, player_id: &PlayerId) -> SubtrActorResult<String>

Returns the name of the specified player.

source

pub fn get_player_team_key( &self, player_id: &PlayerId ) -> SubtrActorResult<String>

Returns the team key for the specified player.

source

pub fn get_player_is_team_0( &self, player_id: &PlayerId ) -> SubtrActorResult<bool>

Determines if the player is on team 0.

source

pub fn get_player_rigid_body( &self, player_id: &PlayerId ) -> SubtrActorResult<&RigidBody>

Returns a reference to the RigidBody of the player’s car.

source

pub fn get_player_rigid_body_and_updated( &self, player_id: &PlayerId ) -> SubtrActorResult<(&RigidBody, &usize)>

Returns the most recent update to the RigidBody of the player’s car along with the index of the frame in which it was updated.

source

pub fn get_velocity_applied_player_rigid_body( &self, player_id: &PlayerId, target_time: f32 ) -> SubtrActorResult<RigidBody>

source

pub fn get_interpolated_player_rigid_body( &self, player_id: &PlayerId, time: f32, close_enough: f32 ) -> SubtrActorResult<RigidBody>

source

pub fn get_player_boost_level( &self, player_id: &PlayerId ) -> SubtrActorResult<f32>

source

pub fn get_component_active(&self, actor_id: &ActorId) -> SubtrActorResult<u8>

source

pub fn get_boost_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8>

source

pub fn get_jump_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8>

source

pub fn get_double_jump_active( &self, player_id: &PlayerId ) -> SubtrActorResult<u8>

source

pub fn get_dodge_active(&self, player_id: &PlayerId) -> SubtrActorResult<u8>

source

pub fn map_attribute_keys( &self, hash_map: &HashMap<ObjectId, (Attribute, usize)> ) -> HashMap<String, Attribute>

source

pub fn all_mappings_string(&self) -> String

source

pub fn actor_state_string(&self, actor_id: &ActorId) -> String

source

pub fn print_actors_by_id<'b>( &self, actor_ids: impl Iterator<Item = &'b ActorId> )

source

pub fn print_actors_of_type(&self, actor_type: &'static str)

source

pub fn print_actor_types(&self)

source

pub fn print_all_actors(&self)

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for ReplayProcessor<'a>

§

impl<'a> Send for ReplayProcessor<'a>

§

impl<'a> Sync for ReplayProcessor<'a>

§

impl<'a> Unpin for ReplayProcessor<'a>

§

impl<'a> UnwindSafe for ReplayProcessor<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.