Skip to main content

Observer

Trait Observer 

Source
pub trait Observer {
    // Provided methods
    fn interests(&self) -> Interests { ... }
    fn on_demo_command(
        &mut self,
        ctx: &Context,
        msg_type: EDemoCommands,
        msg: &[u8],
    ) -> ObserverResult { ... }
    fn on_net_message(
        &mut self,
        ctx: &Context,
        msg_type: NetMessages,
        msg: &[u8],
    ) -> ObserverResult { ... }
    fn on_svc_message(
        &mut self,
        ctx: &Context,
        msg_type: SvcMessages,
        msg: &[u8],
    ) -> ObserverResult { ... }
    fn on_base_user_message(
        &mut self,
        ctx: &Context,
        msg_type: EBaseUserMessages,
        msg: &[u8],
    ) -> ObserverResult { ... }
    fn on_base_game_event(
        &mut self,
        ctx: &Context,
        msg_type: EBaseGameEvents,
        msg: &[u8],
    ) -> ObserverResult { ... }
    fn on_tick_start(&mut self, ctx: &Context) -> ObserverResult { ... }
    fn on_tick_end(&mut self, ctx: &Context) -> ObserverResult { ... }
    fn on_entity(
        &mut self,
        ctx: &Context,
        event: EntityEvents,
        entity: &Entity,
    ) -> ObserverResult { ... }
    fn on_game_event(
        &mut self,
        ctx: &Context,
        ge: &GameEvent<'_>,
    ) -> ObserverResult { ... }
    fn on_string_table(
        &mut self,
        ctx: &Context,
        st: &StringTable,
        modified: &[i32],
    ) -> ObserverResult { ... }
    fn on_stop(&mut self, ctx: &Context) -> ObserverResult { ... }
}
Expand description

Observer trait for handling demo file events.

Implement this trait to receive callbacks as the parser processes the demo file. You can either implement it manually or use the #[observer] attribute macro for a more convenient approach.

§Interest-based Filtering

The interests method allows you to declare which events your observer wants to receive. This is crucial for performance as it allows the parser to skip processing events that no observer cares about.

§Examples

use source2_demo::prelude::*;
use source2_demo_protobufs::CDotaUserMsgChatMessage;

#[derive(Default)]
struct GameStats {
    combat_logs: u32,
    messages: u32,
}

#[observer]
impl GameStats {
    #[on_message]
    fn on_chat_msg(&mut self, ctx: &Context, msg: CDotaUserMsgChatMessage) -> ObserverResult {
        self.messages += 1;
        Ok(())
    }

    #[on_combat_log]
    fn on_combat_log(&mut self, ctx: &Context, entry: &CombatLogEntry) -> ObserverResult {
        self.combat_logs += 1;
        Ok(())
    }
}

§Manual implementation

use source2_demo::prelude::*;

#[derive(Default)]
struct EntityCounter {
    count: usize,
}

impl Observer for EntityCounter {
    fn interests(&self) -> Interests {
        Interests::ENTITY_STATE | Interests::ENTITY_EVENTS
    }

    fn on_entity(
        &mut self,
        ctx: &Context,
        event: EntityEvents,
        entity: &Entity,
    ) -> ObserverResult {
        if event == EntityEvents::Created {
            self.count += 1;
        }
        Ok(())
    }
}

§Combining multiple interests

use source2_demo::prelude::*;

#[derive(Default)]
struct MultiObserver;

impl Observer for MultiObserver {
    fn interests(&self) -> Interests {
        Interests::TICK_START
            | Interests::TICK_END
            | Interests::ENTITY_STATE
            | Interests::ENTITY_EVENTS
    }

    fn on_tick_start(&mut self, ctx: &Context) -> ObserverResult {
        println!("Tick {}", ctx.tick());
        Ok(())
    }

    fn on_entity(
        &mut self,
        ctx: &Context,
        event: EntityEvents,
        entity: &Entity,
    ) -> ObserverResult {
        // Process entities
        Ok(())
    }
}

Provided Methods§

Source

fn interests(&self) -> Interests

Declares which events this observer is interested in.

Return an empty Interests to receive no events, or combine flags using the | operator. This method is called once when the observer is registered.

§Default

Returns Interests::empty() by default (no events).

Source

fn on_demo_command( &mut self, ctx: &Context, msg_type: EDemoCommands, msg: &[u8], ) -> ObserverResult

Called when a demo command is received.

Requires Interests::DEMO_MESSAGE to be set.

Source

fn on_net_message( &mut self, ctx: &Context, msg_type: NetMessages, msg: &[u8], ) -> ObserverResult

Called when a net message is received.

Requires Interests::NET_MESSAGE to be set.

Source

fn on_svc_message( &mut self, ctx: &Context, msg_type: SvcMessages, msg: &[u8], ) -> ObserverResult

Called when an SVC (server-to-client) message is received.

Requires Interests::SVC_MESSAGE to be set.

Source

fn on_base_user_message( &mut self, ctx: &Context, msg_type: EBaseUserMessages, msg: &[u8], ) -> ObserverResult

Called when a base user message is received.

Requires Interests::BASE_USER_MESSAGE to be set.

Source

fn on_base_game_event( &mut self, ctx: &Context, msg_type: EBaseGameEvents, msg: &[u8], ) -> ObserverResult

Called when a base game event is received.

Requires Interests::BASE_GAME_EVENT to be set.

Source

fn on_tick_start(&mut self, ctx: &Context) -> ObserverResult

Called at the start of each tick.

Requires Interests::TICK_START to be set.

Source

fn on_tick_end(&mut self, ctx: &Context) -> ObserverResult

Called at the end of each tick.

Requires Interests::TICK_END to be set.

Source

fn on_entity( &mut self, ctx: &Context, event: EntityEvents, entity: &Entity, ) -> ObserverResult

Called when an entity is created, updated, or deleted.

Requires Interests::ENTITY_EVENTS and Interests::ENTITY_STATE to be set.

Source

fn on_game_event(&mut self, ctx: &Context, ge: &GameEvent<'_>) -> ObserverResult

Called when a game event occurs.

Requires Interests::BASE_GAME_EVENT to be set.

Source

fn on_string_table( &mut self, ctx: &Context, st: &StringTable, modified: &[i32], ) -> ObserverResult

Called when a string table is updated.

Requires Interests::STRING_TABLE_ENTRIES and Interests::STRING_TABLE_STATE to be set.

Source

fn on_stop(&mut self, ctx: &Context) -> ObserverResult

Called when the replay ends.

Requires Interests::REPLAY_END to be set. This is the last callback before parsing completes.

§Arguments
  • ctx - Current replay context

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl<T> Observer for Rc<RefCell<T>>
where T: Observer,