Replace specific networking trait bounds with general Networked trait

This commit is contained in:
Michael Bradley 2025-10-25 21:50:02 -04:00
parent 0f2248a2cb
commit fee5fb3c95
Signed by: MichaelBradley
SSH key fingerprint: SHA256:BKO2eI2LPsCbQS3n3i5SdwZTAIV3F1lHezR07qP+Ob0
2 changed files with 44 additions and 10 deletions

View file

@ -8,44 +8,76 @@ use super::{
#[derive(Component)] #[derive(Component)]
pub struct PeerOwned; pub struct PeerOwned;
fn spawner<T: TryFrom<Vec<u8>> + Component>( pub trait Networked: Component + NetworkEncodable + NetworkDecodable {}
impl<T> Networked for T where T: Component + NetworkEncodable + NetworkDecodable {}
pub trait NetworkEncodable {
fn encode(&self) -> Vec<u8>;
}
impl<T> NetworkEncodable for T
where
T: Clone + Into<Vec<u8>>,
{
fn encode(&self) -> Vec<u8> {
self.clone().into()
}
}
pub trait NetworkDecodable: Sized {
type DecodeError;
fn decode(buffer: Vec<u8>) -> std::result::Result<Self, Self::DecodeError>;
}
impl<T> NetworkDecodable for T
where
T: TryFrom<Vec<u8>>,
{
type DecodeError = T::Error;
fn decode(buffer: Vec<u8>) -> std::result::Result<Self, Self::DecodeError> {
T::try_from(buffer)
}
}
fn spawner<T: NetworkDecodable + Component>(
mut inbound: MessageReader<InboundPacket>, mut inbound: MessageReader<InboundPacket>,
mut commands: Commands, mut commands: Commands,
) { ) {
for InboundPacket(packet) in inbound.read() { for InboundPacket(packet) in inbound.read() {
if let Ok(component) = T::try_from(packet.message.clone()) { if let Ok(component) = T::decode(packet.message.clone()) {
commands.spawn((component, PeerOwned)); commands.spawn((component, PeerOwned));
} }
} }
} }
fn new_peer<T: Into<Vec<u8>> + Component + Clone>( fn new_peer<T: NetworkEncodable + Component>(
add: On<Add, PeerID>, add: On<Add, PeerID>,
peers: Query<&PeerID>,
components: Query<&T, Without<PeerOwned>>, components: Query<&T, Without<PeerOwned>>,
peers: Query<&PeerID>,
mut outbound: MessageWriter<OutboundPacket>, mut outbound: MessageWriter<OutboundPacket>,
) -> Result { ) -> Result {
let peer = peers.get(add.entity)?; let peer = peers.get(add.entity)?;
for component in components { for component in components {
outbound.write(Packet::create(component.clone().into(), peer.id)); outbound.write(Packet::create(component.encode(), peer.id));
} }
Ok(()) Ok(())
} }
fn new_entity<T: Into<Vec<u8>> + Component + Clone>( fn new_entity<T: NetworkEncodable + Component>(
add: On<Add, T>, add: On<Add, T>,
peers: Query<&PeerID>,
components: Query<&T, Without<PeerOwned>>, components: Query<&T, Without<PeerOwned>>,
peers: Query<&PeerID>,
mut outbound: MessageWriter<OutboundPacket>, mut outbound: MessageWriter<OutboundPacket>,
) { ) {
if let Ok(component) = components.get(add.entity) { if let Ok(component) = components.get(add.entity) {
for peer in peers { for peer in peers {
outbound.write(Packet::create(component.clone().into(), peer.id)); outbound.write(Packet::create(component.encode(), peer.id));
} }
} }
} }
pub fn distribution_plugin<T: Into<Vec<u8>> + TryFrom<Vec<u8>> + Component + Clone>(app: &mut App) { pub fn distribution_plugin<T: Networked>(app: &mut App) {
app.add_systems(FixedUpdate, spawner::<T>) app.add_systems(FixedUpdate, spawner::<T>)
.add_observer(new_peer::<T>) .add_observer(new_peer::<T>)
.add_observer(new_entity::<T>); .add_observer(new_entity::<T>);

View file

@ -10,7 +10,9 @@ mod thread;
#[allow(unused_imports)] #[allow(unused_imports)]
pub mod prelude { pub mod prelude {
pub use super::distribution::distribution_plugin; pub use super::distribution::{
NetworkDecodable, NetworkEncodable, Networked, distribution_plugin,
};
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};
pub use super::plugin::NetIOPlugin; pub use super::plugin::NetIOPlugin;