Skip to content

Commit

Permalink
Renet: Allow application code to be transport agnostic (#119)
Browse files Browse the repository at this point in the history
  • Loading branch information
OleStrohm authored Nov 7, 2023
1 parent fb71a40 commit 1b4c1c9
Show file tree
Hide file tree
Showing 14 changed files with 178 additions and 157 deletions.
4 changes: 2 additions & 2 deletions bevy_renet/examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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()),
);
}

Expand Down
59 changes: 59 additions & 0 deletions bevy_renet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -42,3 +60,44 @@ impl RenetClientPlugin {
client.update(time.delta());
}
}

pub fn client_connected() -> impl FnMut(Option<Res<RenetClient>>) -> bool {
|client| match client {
Some(client) => client.is_connected(),
None => false,
}
}

pub fn client_disconnected() -> impl FnMut(Option<Res<RenetClient>>) -> bool {
|client| match client {
Some(client) => client.is_disconnected(),
None => true,
}
}

pub fn client_connecting() -> impl FnMut(Option<Res<RenetClient>>) -> bool {
|client| match client {
Some(client) => client.is_connecting(),
None => false,
}
}

pub fn client_just_connected() -> impl FnMut(Local<bool>, Option<Res<RenetClient>>) -> bool {
|mut last_connected: Local<bool>, 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<bool>, Option<Res<RenetClient>>) -> bool {
|mut last_connected: Local<bool>, client| {
let disconnected = client.map(|client| client.is_disconnected()).unwrap_or(true);

let just_disconnected = *last_connected && disconnected;
*last_connected = !disconnected;
just_disconnected
}
}
51 changes: 6 additions & 45 deletions bevy_renet/src/steam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand All @@ -24,25 +24,26 @@ impl Plugin for SteamServerPlugin {
app.add_systems(
PreUpdate,
Self::update_system
.in_set(RenetReceive)
.run_if(resource_exists::<RenetServer>())
.after(RenetServerPlugin::update_system),
);

app.add_systems(
PostUpdate,
(Self::send_packets, Self::disconnect_on_exit).run_if(resource_exists::<RenetServer>()),
(Self::send_packets.in_set(RenetSend), Self::disconnect_on_exit).run_if(resource_exists::<RenetServer>()),
);
}
}

impl SteamServerPlugin {
pub fn update_system(mut transport: Option<NonSendMut<SteamServerTransport>>, mut server: ResMut<RenetServer>) {
fn update_system(mut transport: Option<NonSendMut<SteamServerTransport>>, mut server: ResMut<RenetServer>) {
if let Some(transport) = transport.as_mut() {
transport.update(&mut server);
}
}

pub fn send_packets(mut transport: Option<NonSendMut<SteamServerTransport>>, mut server: ResMut<RenetServer>) {
fn send_packets(mut transport: Option<NonSendMut<SteamServerTransport>>, mut server: ResMut<RenetServer>) {
if let Some(transport) = transport.as_mut() {
transport.send_packets(&mut server);
}
Expand Down Expand Up @@ -97,48 +98,8 @@ impl SteamClientPlugin {
}

fn disconnect_on_exit(exit: EventReader<AppExit>, mut transport: ResMut<SteamClientTransport>) {
if !exit.is_empty() && !transport.is_disconnected() {
if !exit.is_empty() {
transport.disconnect();
}
}
}

pub fn client_connected() -> impl FnMut(Option<Res<SteamClientTransport>>) -> bool {
|transport| match transport {
Some(transport) => transport.is_connected(),
None => false,
}
}

pub fn client_disconnected() -> impl FnMut(Option<Res<SteamClientTransport>>) -> bool {
|transport| match transport {
Some(transport) => transport.is_disconnected(),
None => true,
}
}

pub fn client_connecting() -> impl FnMut(Option<Res<SteamClientTransport>>) -> bool {
|transport| match transport {
Some(transport) => transport.is_connecting(),
None => false,
}
}

pub fn client_just_connected() -> impl FnMut(Local<bool>, Option<Res<SteamClientTransport>>) -> bool {
|mut last_connected: Local<bool>, 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<bool>, Option<Res<SteamClientTransport>>) -> bool {
|mut last_connected: Local<bool>, transport| {
let disconnected = transport.map(|transport| transport.is_disconnected()).unwrap_or(true);

let just_disconnected = *last_connected && disconnected;
*last_connected = !disconnected;
just_disconnected
}
}
52 changes: 6 additions & 46 deletions bevy_renet/src/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use renet::{

use bevy::{app::AppExit, prelude::*};

use crate::{RenetClientPlugin, RenetServerPlugin};
use crate::{RenetClientPlugin, RenetReceive, RenetSend, RenetServerPlugin};

pub struct NetcodeServerPlugin;

Expand All @@ -18,22 +18,23 @@ impl Plugin for NetcodeServerPlugin {
app.add_systems(
PreUpdate,
Self::update_system
.in_set(RenetReceive)
.run_if(resource_exists::<NetcodeServerTransport>())
.run_if(resource_exists::<RenetServer>())
.after(RenetServerPlugin::update_system),
);

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::<NetcodeServerTransport>())
.run_if(resource_exists::<RenetServer>()),
);
}
}

impl NetcodeServerPlugin {
pub fn update_system(
fn update_system(
mut transport: ResMut<NetcodeServerTransport>,
mut server: ResMut<RenetServer>,
time: Res<Time>,
Expand All @@ -44,7 +45,7 @@ impl NetcodeServerPlugin {
}
}

pub fn send_packets(mut transport: ResMut<NetcodeServerTransport>, mut server: ResMut<RenetServer>) {
fn send_packets(mut transport: ResMut<NetcodeServerTransport>, mut server: ResMut<RenetServer>) {
transport.send_packets(&mut server);
}

Expand Down Expand Up @@ -98,49 +99,8 @@ impl NetcodeClientPlugin {
}

fn disconnect_on_exit(exit: EventReader<AppExit>, mut transport: ResMut<NetcodeClientTransport>) {
if !exit.is_empty() && !transport.is_disconnected() {
if !exit.is_empty() {
transport.disconnect();
}
}
}

pub fn client_connected() -> impl FnMut(Option<Res<NetcodeClientTransport>>) -> bool {
|transport| match transport {
Some(transport) => transport.is_connected(),
None => false,
}
}

pub fn client_disconnected() -> impl FnMut(Option<Res<NetcodeClientTransport>>) -> bool {
|transport| match transport {
Some(transport) => transport.is_disconnected(),
None => true,
}
}

pub fn client_connecting() -> impl FnMut(Option<Res<NetcodeClientTransport>>) -> bool {
|transport| match transport {
Some(transport) => transport.is_connecting(),
None => false,
}
}

pub fn client_just_connected() -> impl FnMut(Local<bool>, Option<Res<NetcodeClientTransport>>) -> bool {
|mut last_connected: Local<bool>, 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<bool>, Option<Res<NetcodeClientTransport>>) -> bool {
|mut last_connected: Local<bool>, transport| {
let disconnected = transport.map(|transport| transport.is_disconnected()).unwrap_or(true);

let just_disconnected = *last_connected && disconnected;
*last_connected = !disconnected;
just_disconnected
}
}
6 changes: 4 additions & 2 deletions demo_bevy/src/bin/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use bevy::{
};
use bevy_egui::{EguiContexts, EguiPlugin};
use bevy_renet::{
client_connected,
renet::{ClientId, RenetClient},
RenetClientPlugin,
};
Expand Down Expand Up @@ -46,7 +47,8 @@ fn add_netcode_network(app: &mut App) {
use std::{net::UdpSocket, time::SystemTime};

app.add_plugins(bevy_renet::transport::NetcodeClientPlugin);
app.configure_sets(Update, Connected.run_if(bevy_renet::transport::client_connected()));

app.configure_sets(Update, Connected.run_if(client_connected()));

let client = RenetClient::new(connection_config());

Expand Down Expand Up @@ -98,7 +100,7 @@ fn add_steam_network(app: &mut App) {
app.insert_resource(transport);
app.insert_resource(CurrentClientId(steam_client.user().steam_id().raw()));

app.configure_sets(Update, Connected.run_if(bevy_renet::steam::client_connected()));
app.configure_sets(Update, Connected.run_if(client_connected()));

app.insert_non_send_resource(single);
fn steam_callbacks(client: NonSend<SingleClient>) {
Expand Down
2 changes: 1 addition & 1 deletion demo_chat/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl ChatApp {
AppState::MainScreen => {
draw_main_screen(&mut self.ui_state, &mut self.state, ctx);
}
AppState::ClientChat { transport, .. } if transport.is_connecting() => draw_loader(ctx),
AppState::ClientChat { client, .. } if client.is_connecting() => draw_loader(ctx),
AppState::ClientChat { usernames, .. } => {
let usernames = usernames.clone();
draw_chat(&mut self.ui_state, &mut self.state, usernames, ctx);
Expand Down
2 changes: 1 addition & 1 deletion renet/examples/echo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ fn client(server_addr: SocketAddr, username: Username) {
client.update(duration);
transport.update(duration, &mut client).unwrap();

if transport.is_connected() {
if client.is_connected() {
match stdin_channel.try_recv() {
Ok(text) => client.send_message(DefaultChannel::ReliableOrdered, text.as_bytes().to_vec()),
Err(TryRecvError::Empty) => {}
Expand Down
2 changes: 1 addition & 1 deletion renet/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt;

use crate::packet::SerializationError;

/// Possibles reasons for a disconnection.
/// Possible reasons for a disconnection.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DisconnectReason {
/// Connection was terminated by the transport layer
Expand Down
2 changes: 1 addition & 1 deletion renet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub mod transport;

pub use channel::{ChannelConfig, DefaultChannel, SendType};
pub use error::{ChannelError, ClientNotFound, DisconnectReason};
pub use remote_connection::{ConnectionConfig, NetworkInfo, RenetClient};
pub use remote_connection::{ConnectionConfig, RenetConnectionStatus, NetworkInfo, RenetClient};
pub use server::{RenetServer, ServerEvent};

pub use bytes::Bytes;
Expand Down
Loading

0 comments on commit 1b4c1c9

Please sign in to comment.