From 1b4c1c9677a0663ebc0a154afa9601178f90a56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Str=C3=B8hm?= Date: Tue, 7 Nov 2023 02:02:46 +0000 Subject: [PATCH] Renet: Allow application code to be transport agnostic (#119) --- bevy_renet/examples/simple.rs | 4 +- bevy_renet/src/lib.rs | 59 +++++++++++++++++++ bevy_renet/src/steam.rs | 51 ++-------------- bevy_renet/src/transport.rs | 52 ++--------------- demo_bevy/src/bin/client.rs | 6 +- demo_chat/src/client.rs | 2 +- renet/examples/echo.rs | 2 +- renet/src/error.rs | 2 +- renet/src/lib.rs | 2 +- renet/src/remote_connection.rs | 103 ++++++++++++++++++++++++--------- renet/src/server.rs | 10 +--- renet/src/transport/client.rs | 22 +++---- renet_steam/examples/echo.rs | 2 +- renet_steam/src/client.rs | 18 +++--- 14 files changed, 178 insertions(+), 157 deletions(-) diff --git a/bevy_renet/examples/simple.rs b/bevy_renet/examples/simple.rs index 39bca086..0384b768 100644 --- a/bevy_renet/examples/simple.rs +++ b/bevy_renet/examples/simple.rs @@ -5,7 +5,7 @@ use bevy_renet::{ ConnectionConfig, DefaultChannel, RenetClient, RenetServer, ServerEvent, }, transport::{NetcodeClientPlugin, NetcodeServerPlugin}, - RenetClientPlugin, RenetServerPlugin, + RenetClientPlugin, RenetServerPlugin, client_connected, }; use renet::{ transport::{NetcodeClientTransport, NetcodeServerTransport, NetcodeTransportError}, @@ -118,7 +118,7 @@ fn main() { app.add_systems( Update, - (player_input, client_send_input, client_sync_players).run_if(bevy_renet::transport::client_connected()), + (player_input, client_send_input, client_sync_players).run_if(client_connected()), ); } diff --git a/bevy_renet/src/lib.rs b/bevy_renet/src/lib.rs index 3fe2831b..dda6b137 100644 --- a/bevy_renet/src/lib.rs +++ b/bevy_renet/src/lib.rs @@ -10,6 +10,24 @@ pub mod transport; #[cfg(feature = "steam")] pub mod steam; +/// This system set is where all transports receive messages +/// +/// If you want to ensure data has arrived in the [`RenetClient`] or [`RenetServer`], then schedule your +/// system after this set. +/// +/// This system set runs in PreUpdate. +#[derive(Debug, SystemSet, Clone, Copy, PartialEq, Eq, Hash)] +pub struct RenetReceive; + +/// This system set is where all transports send messages +/// +/// If you want to ensure your packets have been registered by the [`RenetClient`] or [`RenetServer`], then +/// schedule your system before this set. +/// +/// This system set runs in PostUpdate. +#[derive(Debug, SystemSet, Clone, Copy, PartialEq, Eq, Hash)] +pub struct RenetSend; + pub struct RenetServerPlugin; pub struct RenetClientPlugin; @@ -42,3 +60,44 @@ impl RenetClientPlugin { client.update(time.delta()); } } + +pub fn client_connected() -> impl FnMut(Option>) -> bool { + |client| match client { + Some(client) => client.is_connected(), + None => false, + } +} + +pub fn client_disconnected() -> impl FnMut(Option>) -> bool { + |client| match client { + Some(client) => client.is_disconnected(), + None => true, + } +} + +pub fn client_connecting() -> impl FnMut(Option>) -> bool { + |client| match client { + Some(client) => client.is_connecting(), + None => false, + } +} + +pub fn client_just_connected() -> impl FnMut(Local, Option>) -> bool { + |mut last_connected: Local, client| { + let connected = client.map(|client| client.is_connected()).unwrap_or(false); + + let just_connected = !*last_connected && connected; + *last_connected = connected; + just_connected + } +} + +pub fn client_just_disconnected() -> impl FnMut(Local, Option>) -> bool { + |mut last_connected: Local, client| { + let disconnected = client.map(|client| client.is_disconnected()).unwrap_or(true); + + let just_disconnected = *last_connected && disconnected; + *last_connected = !disconnected; + just_disconnected + } +} diff --git a/bevy_renet/src/steam.rs b/bevy_renet/src/steam.rs index d02d8c74..b39c0c97 100644 --- a/bevy_renet/src/steam.rs +++ b/bevy_renet/src/steam.rs @@ -2,7 +2,7 @@ use bevy::{app::AppExit, prelude::*}; use renet::{RenetClient, RenetServer}; use renet_steam::steamworks::SteamError; -use crate::{RenetClientPlugin, RenetServerPlugin}; +use crate::{RenetClientPlugin, RenetReceive, RenetSend, RenetServerPlugin}; pub use renet_steam::{AccessPermission, SteamClientTransport, SteamServerConfig, SteamServerTransport}; @@ -24,25 +24,26 @@ impl Plugin for SteamServerPlugin { app.add_systems( PreUpdate, Self::update_system + .in_set(RenetReceive) .run_if(resource_exists::()) .after(RenetServerPlugin::update_system), ); app.add_systems( PostUpdate, - (Self::send_packets, Self::disconnect_on_exit).run_if(resource_exists::()), + (Self::send_packets.in_set(RenetSend), Self::disconnect_on_exit).run_if(resource_exists::()), ); } } impl SteamServerPlugin { - pub fn update_system(mut transport: Option>, mut server: ResMut) { + fn update_system(mut transport: Option>, mut server: ResMut) { if let Some(transport) = transport.as_mut() { transport.update(&mut server); } } - pub fn send_packets(mut transport: Option>, mut server: ResMut) { + fn send_packets(mut transport: Option>, mut server: ResMut) { if let Some(transport) = transport.as_mut() { transport.send_packets(&mut server); } @@ -97,48 +98,8 @@ impl SteamClientPlugin { } fn disconnect_on_exit(exit: EventReader, mut transport: ResMut) { - if !exit.is_empty() && !transport.is_disconnected() { + if !exit.is_empty() { transport.disconnect(); } } } - -pub fn client_connected() -> impl FnMut(Option>) -> bool { - |transport| match transport { - Some(transport) => transport.is_connected(), - None => false, - } -} - -pub fn client_disconnected() -> impl FnMut(Option>) -> bool { - |transport| match transport { - Some(transport) => transport.is_disconnected(), - None => true, - } -} - -pub fn client_connecting() -> impl FnMut(Option>) -> bool { - |transport| match transport { - Some(transport) => transport.is_connecting(), - None => false, - } -} - -pub fn client_just_connected() -> impl FnMut(Local, Option>) -> bool { - |mut last_connected: Local, transport| { - let connected = transport.map(|transport| transport.is_connected()).unwrap_or(false); - let just_connected = !*last_connected && connected; - *last_connected = connected; - just_connected - } -} - -pub fn client_just_disconnected() -> impl FnMut(Local, Option>) -> bool { - |mut last_connected: Local, transport| { - let disconnected = transport.map(|transport| transport.is_disconnected()).unwrap_or(true); - - let just_disconnected = *last_connected && disconnected; - *last_connected = !disconnected; - just_disconnected - } -} diff --git a/bevy_renet/src/transport.rs b/bevy_renet/src/transport.rs index 2b77dfa8..bb6b79a9 100644 --- a/bevy_renet/src/transport.rs +++ b/bevy_renet/src/transport.rs @@ -5,7 +5,7 @@ use renet::{ use bevy::{app::AppExit, prelude::*}; -use crate::{RenetClientPlugin, RenetServerPlugin}; +use crate::{RenetClientPlugin, RenetReceive, RenetSend, RenetServerPlugin}; pub struct NetcodeServerPlugin; @@ -18,6 +18,7 @@ impl Plugin for NetcodeServerPlugin { app.add_systems( PreUpdate, Self::update_system + .in_set(RenetReceive) .run_if(resource_exists::()) .run_if(resource_exists::()) .after(RenetServerPlugin::update_system), @@ -25,7 +26,7 @@ impl Plugin for NetcodeServerPlugin { app.add_systems( PostUpdate, - (Self::send_packets, Self::disconnect_on_exit) + (Self::send_packets.in_set(RenetSend), Self::disconnect_on_exit) .run_if(resource_exists::()) .run_if(resource_exists::()), ); @@ -33,7 +34,7 @@ impl Plugin for NetcodeServerPlugin { } impl NetcodeServerPlugin { - pub fn update_system( + fn update_system( mut transport: ResMut, mut server: ResMut, time: Res