Add trait wrapping the distribution query filters
All checks were successful
CI / Formatting (push) Successful in 39s

This commit is contained in:
Michael Bradley 2025-10-26 18:34:13 -04:00
parent 3dfeae14f7
commit 3921537360
Signed by: MichaelBradley
SSH key fingerprint: SHA256:BKO2eI2LPsCbQS3n3i5SdwZTAIV3F1lHezR07qP+Ob0
5 changed files with 67 additions and 35 deletions

View file

@ -1,3 +1,5 @@
use std::marker::PhantomData;
use bevy::{
ecs::{component::Mutable, query::QueryFilter},
prelude::*,
@ -51,17 +53,27 @@ where
}
/// Components wishing to be networked must implement this type
pub trait Networked: Component<Mutability = Mutable> + NetworkEncodable + NetworkDecodable {
type LocalFilter: QueryFilter;
type RemoteFilter: QueryFilter;
pub trait Networked: Component<Mutability = Mutable> + NetworkEncodable + NetworkDecodable {}
impl<T> Networked for T where
T: Component<Mutability = Mutable> + NetworkEncodable + NetworkDecodable
{
}
impl<T> Networked for T
where
T: Component<Mutability = Mutable> + NetworkEncodable + NetworkDecodable,
{
type LocalFilter = Without<PeerOwned>;
type RemoteFilter = With<PeerOwned>;
pub trait NetworkSettings: 'static + Send + Sync {
type IncomingFilter: QueryFilter;
type LocalChangeFilter: QueryFilter;
type NewPeerFilter: QueryFilter;
type NewLocalEntityFilter: QueryFilter;
}
pub struct DefaultNetworkSettings;
impl NetworkSettings for DefaultNetworkSettings {
type IncomingFilter = With<PeerOwned>;
type LocalChangeFilter = Without<PeerOwned>;
type NewPeerFilter = Without<PeerOwned>;
type NewLocalEntityFilter = Without<PeerOwned>;
}
fn incoming_network_entity<
@ -85,9 +97,21 @@ fn incoming_network_entity<
}
}
fn new_peer<T: NetworkEncodable + Component>(
fn changed_local_entity<T: NetworkEncodable + Component, F: QueryFilter>(
components: Query<(&T, &EntityNetworkID), (Changed<T>, F)>,
peers: Query<&PeerID>,
mut outbound: MessageWriter<OutboundPacket>,
) {
for (component, id) in components {
for peer in peers {
outbound.write(Packet::create(peer.id, id.0, component.encode()));
}
}
}
fn new_peer<T: NetworkEncodable + Component, F: QueryFilter>(
add: On<Add, PeerID>,
components: Query<(&T, &EntityNetworkID), Without<PeerOwned>>,
components: Query<(&T, &EntityNetworkID), F>,
peers: Query<&PeerID>,
mut outbound: MessageWriter<OutboundPacket>,
) -> Result {
@ -98,9 +122,9 @@ fn new_peer<T: NetworkEncodable + Component>(
Ok(())
}
fn new_local_entity<T: NetworkEncodable + Component>(
fn new_local_entity<T: NetworkEncodable + Component, F: QueryFilter>(
add: On<Add, T>,
components: Query<(&T, &EntityNetworkID), Without<PeerOwned>>,
components: Query<(&T, &EntityNetworkID), F>,
peers: Query<&PeerID>,
mut outbound: MessageWriter<OutboundPacket>,
) {
@ -111,26 +135,31 @@ fn new_local_entity<T: NetworkEncodable + Component>(
}
}
fn changed_local_entity<T: NetworkEncodable + Component, F: QueryFilter>(
components: Query<(&T, &EntityNetworkID), (F, Changed<T>)>,
peers: Query<&PeerID>,
mut outbound: MessageWriter<OutboundPacket>,
) {
for (component, id) in components {
for peer in peers {
outbound.write(Packet::create(peer.id, id.0, component.encode()));
#[derive(Debug)]
pub struct DistributionPlugin<T: Networked, Settings: NetworkSettings = DefaultNetworkSettings> {
_phantom1: PhantomData<T>,
_phantom2: PhantomData<Settings>,
}
impl<T: Networked, Settings: NetworkSettings> Default for DistributionPlugin<T, Settings> {
fn default() -> Self {
Self {
_phantom1: Default::default(),
_phantom2: Default::default(),
}
}
}
pub fn distribution_plugin<T: Networked>(app: &mut App) {
app.add_systems(
FixedUpdate,
(
changed_local_entity::<T, T::LocalFilter>,
incoming_network_entity::<T, T::RemoteFilter>,
),
)
.add_observer(new_peer::<T>)
.add_observer(new_local_entity::<T>);
impl<T: Networked, Settings: NetworkSettings> Plugin for DistributionPlugin<T, Settings> {
fn build(&self, app: &mut App) {
app.add_systems(
FixedUpdate,
(
incoming_network_entity::<T, Settings::IncomingFilter>,
changed_local_entity::<T, Settings::LocalChangeFilter>,
),
)
.add_observer(new_peer::<T, Settings::NewPeerFilter>)
.add_observer(new_local_entity::<T, Settings::NewLocalEntityFilter>);
}
}