use core::marker::PhantomData;
use bevy::{ecs::component::Immutable, prelude::*};
use crate::shared::replication::registry::{
ReplicationRegistry, component_mask::ComponentMask, receive_fns::MutWrite,
};
pub trait VisibilityFilter: Component<Mutability = Immutable> {
type ClientComponent: Component<Mutability = Immutable>;
type Scope: FilterScope;
fn is_visible(&self, client: Entity, component: Option<&Self::ClientComponent>) -> bool;
}
#[derive(Clone)]
pub enum VisibilityScope {
Entity,
Components(ComponentMask),
}
pub trait FilterScope {
fn visibility_scope(world: &mut World, registry: &mut ReplicationRegistry) -> VisibilityScope;
}
#[deprecated(since = "0.39.0", note = "Renamed into `SingleComponent`")]
pub type ComponentScope<A> = SingleComponent<A>;
pub struct SingleComponent<A: Component>(PhantomData<A>);
impl<C: Component<Mutability: MutWrite<C>>> FilterScope for SingleComponent<C> {
fn visibility_scope(world: &mut World, registry: &mut ReplicationRegistry) -> VisibilityScope {
let mut mask = ComponentMask::default();
let (index, _) = registry.init_component_fns::<C>(world);
mask.insert(index);
VisibilityScope::Components(mask)
}
}
impl FilterScope for Entity {
fn visibility_scope(
_world: &mut World,
_registry: &mut ReplicationRegistry,
) -> VisibilityScope {
VisibilityScope::Entity
}
}
macro_rules! impl_filter_scope {
($($C:ident),*) => {
impl<$($C: Component<Mutability: MutWrite<$C>>),*> FilterScope for ($($C,)*) {
fn visibility_scope(world: &mut World, registry: &mut ReplicationRegistry) -> VisibilityScope {
let mut mask = ComponentMask::default();
$(
let (index, _) = registry.init_component_fns::<$C>(world);
mask.insert(index);
)*
VisibilityScope::Components(mask)
}
}
};
}
variadics_please::all_tuples!(impl_filter_scope, 2, 10, C);