AppMarkerExt

Trait 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<Mutability: MutWrite<C>>>(
        &mut self,
        write: WriteFn<C>,
        remove: RemoveFn,
    ) -> &mut Self;
    fn set_command_fns<C: Component<Mutability: MutWrite<C>>>(
        &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<Mutability: MutWrite<C>>>( &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 / default_insert_write and default_remove. See also Self::set_command_fns.

§Examples

In this example we write all received updates for Health component into user’s History<Health> if Predicted marker is present on the client entity. In this scenario, you’d insert Predicted the first time the entity is replicated. Then Health updates after that will be inserted to the history.

use bevy::{ecs::system::EntityCommands, ecs::component::Mutable, prelude::*, platform::collections::HashMap};
use bevy_replicon::{
    bytes::Bytes,
    shared::{
        replication::{
            command_markers::MarkerConfig,
            deferred_entity::DeferredEntity,
            registry::{
                ctx::{RemoveCtx, WriteCtx},
                rule_fns::RuleFns,
            },
        },
        replicon_tick::RepliconTick,
    },
    prelude::*,
};
use serde::{Serialize, Deserialize};

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

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

    Ok(())
}

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

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

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

#[derive(Component, Deref, DerefMut, Serialize, Deserialize)]
struct Health(u32);
Source

fn set_command_fns<C: Component<Mutability: MutWrite<C>>>( &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 / default_insert_write and default_remove. See also Self::set_marker_fns.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so 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<Mutability: MutWrite<C>>>( &mut self, write: WriteFn<C>, remove: RemoveFn, ) -> &mut Self

Source§

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

Implementors§