Trait bevy_replicon::core::command_markers::AppMarkerExt

source ·
pub trait AppMarkerExt {
    // Required methods
    fn register_marker<M: Component>(&mut self) -> &mut Self;
    fn register_marker_with<M: Component>(
        &mut self,
        config: MarkerConfig,
    ) -> &mut Self;
    fn set_marker_fns<M: Component, C: Component>(
        &mut self,
        write: WriteFn<C>,
        remove: RemoveFn,
    ) -> &mut Self;
    fn set_command_fns<C: Component>(
        &mut self,
        write: WriteFn<C>,
        remove: RemoveFn,
    ) -> &mut Self;
}
Expand description

Marker-based functions for App.

Allows customizing behavior on clients when receiving updates from the server.

We check markers on receive instead of archetypes because on client we don’t know an incoming entity’s archetype in advance.

This is mostly needed for third-party crates, most end-users should not need to use it directly.

Required Methods§

source

fn register_marker<M: Component>(&mut self) -> &mut Self

Registers a component as a marker.

Can be used to override how this component or other components will be written or removed based on marker-component presence. For details see Self::set_marker_fns.

This function registers markers with default MarkerConfig. See also Self::register_marker_with.

source

fn register_marker_with<M: Component>( &mut self, config: MarkerConfig, ) -> &mut Self

Same as Self::register_marker, but also accepts marker configuration.

source

fn set_marker_fns<M: Component, C: Component>( &mut self, write: WriteFn<C>, remove: RemoveFn, ) -> &mut Self

Associates command functions with a marker for a component.

If this marker is present on an entity and its priority is the highest, then these functions will be called for this component during replication instead of default_write and default_remove. See also Self::set_command_fns.

§Examples

In this example we write all received updates for Transform into user’s History<Transform> if History marker is present on the client entity. In this scenario, you’d insert History the first time the entity is replicated (e.g. by detecting a Player marker component using the blueprint pattern). Then Transform updates after that will be inserted to the history.

use std::io::Cursor;

use bevy::{ecs::system::EntityCommands, prelude::*, utils::HashMap};
use bevy_replicon::{
    core::{
        command_markers::MarkerConfig,
        ctx::{RemoveCtx, WriteCtx},
        replication_registry::rule_fns::RuleFns,
        replicon_tick::RepliconTick,
    },
    prelude::*,
};

app.register_marker_with::<ComponentsHistory>(MarkerConfig {
    need_history: true, // Enable writing for values that are older than the last received value.
    ..Default::default()
})
.set_marker_fns::<ComponentsHistory, Transform>(write_history, remove_history::<Transform>);

/// Instead of writing into a component directly, it writes data into [`History<C>`].
fn write_history<C: Component>(
    ctx: &mut WriteCtx,
    rule_fns: &RuleFns<C>,
    entity: &mut EntityMut,
    cursor: &mut Cursor<&[u8]>,
) -> bincode::Result<()> {
    let component: C = rule_fns.deserialize(ctx, cursor)?;
    if let Some(mut history) = entity.get_mut::<History<C>>() {
        history.insert(ctx.message_tick, component);
    } else {
        ctx.commands
            .entity(entity.id())
            .insert(History([(ctx.message_tick, component)].into()));
    }

    Ok(())
}

/// Removes component `C` and its history.
fn remove_history<C: Component>(ctx: &mut RemoveCtx, entity: &mut EntityMut) {
    ctx.commands.entity(entity.id()).remove::<History<C>>().remove::<C>();
}

/// If this marker is present on an entity, registered components will be stored in [`History<T>`].
///
///Present only on client.
#[derive(Component)]
struct ComponentsHistory;

/// Stores history of values of `C` received from server. Present only on client.
///
/// Present only on client.
#[derive(Component, Deref, DerefMut)]
struct History<C>(HashMap<RepliconTick, C>);
source

fn set_command_fns<C: Component>( &mut self, write: WriteFn<C>, remove: RemoveFn, ) -> &mut Self

Sets default functions for a component when there are no markers.

If there are no markers present on an entity, then these functions will be called for this component during replication instead of default_write and default_remove. See also Self::set_marker_fns.

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl AppMarkerExt for App

source§

fn register_marker<M: Component>(&mut self) -> &mut Self

source§

fn register_marker_with<M: Component>( &mut self, config: MarkerConfig, ) -> &mut Self

source§

fn set_marker_fns<M: Component, C: Component>( &mut self, write: WriteFn<C>, remove: RemoveFn, ) -> &mut Self

source§

fn set_command_fns<C: Component>( &mut self, write: WriteFn<C>, remove: RemoveFn, ) -> &mut Self

Implementors§