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

@ -62,7 +62,7 @@ impl Plugin for GamePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugins(( app.add_plugins((
NetIOPlugin::maybe_peer(self.port, self.source.try_to_address()), NetIOPlugin::maybe_peer(self.port, self.source.try_to_address()),
distribution_plugin::<Seed>, DistributionPlugin::<Seed>::default(),
PhysicsPlugins::default().with_length_unit(50.0), PhysicsPlugins::default().with_length_unit(50.0),
)) ))
.init_state::<AppState>() .init_state::<AppState>()

View file

@ -7,6 +7,8 @@ use bevy::{
prelude::*, prelude::*,
}; };
use crate::net::prelude::PeerOwned;
use super::{ use super::{
objects::{Player, Radius}, objects::{Player, Radius},
seed::Seed, seed::Seed,
@ -85,6 +87,6 @@ pub fn zoom_camera(
Ok(()) Ok(())
} }
pub fn reset_seed(mut seed: Single<&mut Seed>) { pub fn reset_seed(mut seed: Single<&mut Seed, Without<PeerOwned>>) {
**seed = Seed::random() **seed = Seed::random()
} }

View file

@ -6,7 +6,7 @@ use std::{
use bevy::prelude::*; use bevy::prelude::*;
use rand::random; use rand::random;
use crate::net::prelude::{EntityNetworkID, Networked}; use crate::net::prelude::EntityNetworkID;
/// Value with which to initialize the PRNG /// Value with which to initialize the PRNG
#[derive(Clone, Component, Copy, Debug)] #[derive(Clone, Component, Copy, Debug)]

View file

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

View file

@ -11,7 +11,8 @@ mod thread;
#[allow(unused_imports)] #[allow(unused_imports)]
pub mod prelude { pub mod prelude {
pub use super::distribution::{ pub use super::distribution::{
EntityNetworkID, NetworkDecodable, NetworkEncodable, Networked, distribution_plugin, DefaultNetworkSettings, DistributionPlugin, EntityNetworkID, NetworkDecodable,
NetworkEncodable, NetworkSettings, Networked, PeerOwned,
}; };
pub use super::packet::{InboundPacket, OutboundPacket, Packet}; pub use super::packet::{InboundPacket, OutboundPacket, Packet};
pub use super::peer::{Peer, PeerID, PeerReceiveTiming, PeerSendTiming, PotentialPeers}; pub use super::peer::{Peer, PeerID, PeerReceiveTiming, PeerSendTiming, PotentialPeers};