Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
v0.3.0 - renaming types
Browse files Browse the repository at this point in the history
  • Loading branch information
simbleau committed Apr 8, 2024
1 parent a070750 commit 252f57c
Show file tree
Hide file tree
Showing 30 changed files with 220 additions and 158 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe

## Unreleased

## 0.3.0

### added

- A `prelude` module.

### changed

- To fix name conflicts with `AddProtocolExt`, the respective types have changed names.
- The `client` feature trait has changed to `AddClientProtocolExt`
- The `server` feature trait has changed to `AddServerProtocolExt`
- Method names have changed:
- `add_sendonly_protocol` has changed to `add_client_wo_protocol` and `add_server_wo_protocol`
- `add_readonly_bounded_protocol` has changed to `add_client_ro_protocol` and `add_server_ro_protocol`
- `add_readonly_unbounded_protocol` has changed to `add_client_ro_unbounded_protocol` and `add_server_ro_unbounded_protocol`
- `add_bounded_protocol` has changed to `add_client_rw_protocol` and `add_server_rw_protocol`
- `add_unbounded_protocol` has changed to `add_client_rw_unbounded_protocol` and `add_server_rw_unbounded_protocol`
- The `ConnectionRequest` event under the `client` feature has been renamed to `RtcClientRequestEvent`
- The `Payload` derive was renamed to `Protocol`
- Fields on `RtcClientState` and `RtcServerState` are now private, with accessor methods, e.g. `.id()` instead of `.id`

## 0.2.0

### added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ resolver = "2"

[workspace.package]
edition = "2021"
version = "0.2.0"
version = "0.3.0"
license = "MIT OR Apache-2.0"
description = "A client-server library designed over WebRTC for Bevy"
repository = "https://github.com/loopystudios/bevy_rtc"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Run the [demos](#demos) and [instructions](#instructions).

| bevy | bevy_rtc |
|-------|-------------|
| 0.13 | 0.1-0.2, main |
| 0.13 | 0.1-0.3, main |
| < 0.13| unsupported |

## Cargo features
Expand Down
3 changes: 2 additions & 1 deletion bevy_rtc/src/client/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ pub enum RtcClientEvent {
DisconnectedFromHost { reason: Option<String> },
}

// TODO: This should be a command, e.g. Commands.connect_rtc(addr), Commands.disconnect_rtc
#[derive(Debug, Clone, Event)]
pub enum ConnectionRequest {
pub enum RtcClientRequestEvent {
/// A request to connect to the server through the signaling server.
/// The format of the addr should be ws://host:port or wss://host:port
Connect { addr: String },
Expand Down
4 changes: 2 additions & 2 deletions bevy_rtc/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ mod state;
mod system_params;
mod systems;

pub use events::{ConnectionRequest, RtcClientEvent};
pub use events::{RtcClientEvent, RtcClientRequestEvent};
pub use plugin::RtcClientPlugin;
pub use router::AddProtocolExt;
pub use router::AddClientProtocolExt;
pub use state::{RtcClientState, RtcClientStatus};
pub use system_params::RtcClient;
7 changes: 4 additions & 3 deletions bevy_rtc/src/client/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{
systems, AddProtocolExt, ConnectionRequest, RtcClientEvent, RtcClientState, RtcClientStatus,
systems, AddClientProtocolExt, RtcClientEvent, RtcClientRequestEvent, RtcClientState,
RtcClientStatus,
};
use crate::{
events::SocketRecvEvent,
Expand All @@ -16,9 +17,9 @@ impl Plugin for RtcClientPlugin {
fn build(&self, app: &mut App) {
app.add_event::<SocketRecvEvent>()
.insert_resource(RtcClientState::default())
.add_bounded_protocol::<LatencyTracerPayload>(2)
.add_client_rw_protocol::<LatencyTracerPayload>(2)
.init_state::<RtcClientStatus>()
.add_event::<ConnectionRequest>()
.add_event::<RtcClientRequestEvent>()
.add_event::<RtcClientEvent>()
.add_systems(OnEnter(RtcClientStatus::Establishing), systems::init_socket)
.add_systems(
Expand Down
53 changes: 26 additions & 27 deletions bevy_rtc/src/client/router/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod receive;
mod send;

use crate::{
protocol::Payload,
protocol::Protocol,
socket::{common_socket_reader, RtcSocket},
};
use bevy::prelude::*;
Expand All @@ -11,26 +11,25 @@ use std::collections::VecDeque;
pub use receive::IncomingMessages;
pub use send::OutgoingMessages;

pub trait AddProtocolExt {
/// Register a protocol that is only sent, never read. Hence, allocate no
/// buffer and do not run systems for receiving.
fn add_sendonly_protocol<M: Payload>(&mut self) -> &mut Self;
/// Register a protocol that is only read, never sent. Allocate a bounded
/// buffer per peer for receiving, and do not run systems for sending.
fn add_readonly_bounded_protocol<M: Payload>(&mut self, bound: usize) -> &mut Self;
/// Register a protocol that is only read, never sent. Use a growable buffer
/// for receiving, and do not run systems for sending.
fn add_readonly_unbounded_protocol<M: Payload>(&mut self) -> &mut Self;
/// Register a protocol for sending and receiving. Allocate a bounded buffer
/// per peer for receiving.
fn add_bounded_protocol<M: Payload>(&mut self, bound: usize) -> &mut Self;
pub trait AddClientProtocolExt {
/// Register a protocol that is only written, never read.
fn add_client_wo_protocol<M: Protocol>(&mut self) -> &mut Self;
/// Register a protocol that is only read, never written. Allocate a bounded
/// buffer per peer for receiving.
fn add_client_ro_protocol<M: Protocol>(&mut self, bound: usize) -> &mut Self;
/// Register a protocol that is only read, never written. Use a growable buffer
/// for reading.
fn add_client_ro_unbounded_protocol<M: Protocol>(&mut self) -> &mut Self;
/// Register a protocol for reading and writing. Allocate a bounded buffer
/// per peer for reading.
fn add_client_rw_protocol<M: Protocol>(&mut self, bound: usize) -> &mut Self;
/// Register a protocol for sending and receiving. Use a growable buffer
/// for receiving.
fn add_unbounded_protocol<M: Payload>(&mut self) -> &mut Self;
/// for reading.
fn add_client_rw_unbounded_protocol<M: Protocol>(&mut self) -> &mut Self;
}

impl AddProtocolExt for App {
fn add_sendonly_protocol<M: Payload>(&mut self) -> &mut Self {
impl AddClientProtocolExt for App {
fn add_client_wo_protocol<M: Protocol>(&mut self) -> &mut Self {
if self.world.contains_resource::<OutgoingMessages<M>>() {
panic!("client already contains resource: {}", M::reflect_name());
}
Expand All @@ -45,11 +44,7 @@ impl AddProtocolExt for App {
self
}

fn add_readonly_unbounded_protocol<M: Payload>(&mut self) -> &mut Self {
self.add_readonly_bounded_protocol::<M>(usize::MAX)
}

fn add_readonly_bounded_protocol<M: Payload>(&mut self, bound: usize) -> &mut Self {
fn add_client_ro_protocol<M: Protocol>(&mut self, bound: usize) -> &mut Self {
if self.world.contains_resource::<IncomingMessages<M>>() {
panic!("client already contains resource: {}", M::reflect_name());
}
Expand All @@ -66,13 +61,13 @@ impl AddProtocolExt for App {
self
}

fn add_unbounded_protocol<M: Payload>(&mut self) -> &mut Self {
self.add_bounded_protocol::<M>(usize::MAX)
fn add_client_ro_unbounded_protocol<M: Protocol>(&mut self) -> &mut Self {
self.add_client_ro_protocol::<M>(usize::MAX)
}

fn add_bounded_protocol<M>(&mut self, bound: usize) -> &mut Self
fn add_client_rw_protocol<M>(&mut self, bound: usize) -> &mut Self
where
M: Payload,
M: Protocol,
{
if self.world.contains_resource::<IncomingMessages<M>>()
|| self.world.contains_resource::<OutgoingMessages<M>>()
Expand All @@ -99,4 +94,8 @@ impl AddProtocolExt for App {
);
self
}

fn add_client_rw_unbounded_protocol<M: Protocol>(&mut self) -> &mut Self {
self.add_client_rw_protocol::<M>(usize::MAX)
}
}
6 changes: 3 additions & 3 deletions bevy_rtc/src/client/router/receive.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use crate::{events::SocketRecvEvent, protocol::Payload};
use crate::{events::SocketRecvEvent, protocol::Protocol};
use bevy::prelude::*;
use std::collections::VecDeque;

#[derive(Default, Debug, Resource)]
pub struct IncomingMessages<M: Payload> {
pub struct IncomingMessages<M: Protocol> {
pub bound: usize,
pub messages: VecDeque<M>,
}

impl<M: Payload> IncomingMessages<M> {
impl<M: Protocol> IncomingMessages<M> {
pub fn receive_payloads(mut incoming: ResMut<Self>, mut events: EventReader<SocketRecvEvent>) {
let bound = incoming.bound;
let packets: Vec<_> = events
Expand Down
8 changes: 4 additions & 4 deletions bevy_rtc/src/client/router/send.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use crate::{
client::state::RtcClientState,
protocol::Payload,
protocol::Protocol,
socket::{RtcSocket, RELIABLE_CHANNEL_INDEX, UNRELIABLE_CHANNEL_INDEX},
};
use bevy::prelude::*;

#[derive(Default, Debug, Resource)]
pub struct OutgoingMessages<M: Payload> {
pub struct OutgoingMessages<M: Protocol> {
pub reliable_to_host: Vec<M>,
pub unreliable_to_host: Vec<M>,
}

impl<M: Payload> OutgoingMessages<M> {
impl<M: Protocol> OutgoingMessages<M> {
/// Swaps the event buffers and clears the oldest event buffer. In general,
/// this should be called once per frame/update.
pub fn flush(&mut self) {
Expand All @@ -24,7 +24,7 @@ impl<M: Payload> OutgoingMessages<M> {
mut socket: ResMut<RtcSocket>,
state: Res<RtcClientState>,
) {
if let Some(host) = state.host_id {
if let Some(host) = state.host_peer_id {
// Client is sending
for message in queue.reliable_to_host.iter() {
if socket
Expand Down
41 changes: 34 additions & 7 deletions bevy_rtc/src/client/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,40 @@ pub enum RtcClientStatus {
#[derive(Resource, Default)]
pub struct RtcClientState {
/// The socket address, used for connecting/reconnecting
pub addr: Option<String>,
/// The ID of the host
pub host_id: Option<PeerId>,
/// The ID given by the signaling server
pub id: Option<PeerId>,
pub(crate) addr: Option<String>,
/// The Peer ID of the host
pub(crate) host_peer_id: Option<PeerId>,
/// The Peer ID given by the signaling server
pub(crate) peer_id: Option<PeerId>,
/// The latency to the server
pub latency: Option<Duration>,
pub(crate) latency: Option<Duration>,
/// The smooth latency to the server
pub smoothed_latency: Option<Duration>,
pub(crate) smoothed_latency: Option<Duration>,
}

impl RtcClientState {
/// Returns the address bound by the server/host.
pub fn addr(&self) -> Option<&str> {
self.addr.as_deref()
}

/// Returns the peer ID of this client if connected
pub fn peer_id(&self) -> Option<PeerId> {
self.peer_id
}

/// Returns the peer ID of the server if connected
pub fn host_peer_id(&self) -> Option<PeerId> {
self.host_peer_id
}

/// Return the latency to the server if connected
pub fn latency(&self) -> Option<Duration> {
self.latency
}

/// Return the smoothed latency to the server if connected
pub fn smoothed_latency(&self) -> Option<Duration> {
self.smoothed_latency
}
}
6 changes: 3 additions & 3 deletions bevy_rtc/src/client/system_params.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use super::router::{IncomingMessages, OutgoingMessages};
use crate::protocol::Payload;
use crate::protocol::Protocol;
use bevy::{ecs::system::SystemParam, prelude::*};

#[derive(SystemParam, Debug)]
pub struct RtcClient<'w, M: Payload> {
pub struct RtcClient<'w, M: Protocol> {
pub(crate) incoming: ResMut<'w, IncomingMessages<M>>,
pub(crate) outgoing: ResMut<'w, OutgoingMessages<M>>,
}

impl<'w, M: Payload> RtcClient<'w, M> {
impl<'w, M: Protocol> RtcClient<'w, M> {
/// Returns the capacity of incoming messages.
pub fn capacity(&self) -> usize {
self.incoming.bound
Expand Down
30 changes: 15 additions & 15 deletions bevy_rtc/src/client/systems.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{
events::{ConnectionRequest, RtcClientEvent},
events::{RtcClientEvent, RtcClientRequestEvent},
state::{RtcClientState, RtcClientStatus},
RtcClient,
};
Expand Down Expand Up @@ -49,23 +49,23 @@ pub(crate) fn reset_socket(
*state = RtcClientState {
// Keep for reconnecting
addr: state.addr.clone(),
host_id: None,
id: None,
host_peer_id: None,
peer_id: None,
latency: None,
smoothed_latency: None,
};
}

/// Reads and handles connection request events
pub(crate) fn connection_request_handler(
mut cxn_event_reader: EventReader<ConnectionRequest>,
mut request_reader: EventReader<RtcClientRequestEvent>,
mut state: ResMut<RtcClientState>,
mut next_connection_state: ResMut<NextState<RtcClientStatus>>,
current_connection_state: Res<State<RtcClientStatus>>,
mut event_wtr: EventWriter<RtcClientEvent>,
) {
match cxn_event_reader.read().next() {
Some(ConnectionRequest::Connect { addr }) => {
match request_reader.read().next() {
Some(RtcClientRequestEvent::Connect { addr }) => {
if let RtcClientStatus::Disconnected = current_connection_state.get() {
debug!(
previous = format!("{current_connection_state:?}"),
Expand All @@ -75,7 +75,7 @@ pub(crate) fn connection_request_handler(
next_connection_state.set(RtcClientStatus::Establishing);
}
}
Some(ConnectionRequest::Disconnect) => {
Some(RtcClientRequestEvent::Disconnect) => {
debug!(
previous = format!("{current_connection_state:?}"),
"set state: disconnected"
Expand All @@ -100,10 +100,10 @@ pub(crate) fn client_event_writer(
// Create events

// Id changed events
if let Some(id) = socket.id() {
if state.id.is_none() {
state.id.replace(id);
event_wtr.send(RtcClientEvent::IdAssigned(id));
if let Some(peer_id) = socket.id() {
if state.peer_id.is_none() {
state.peer_id.replace(peer_id);
event_wtr.send(RtcClientEvent::IdAssigned(peer_id));
}
}

Expand All @@ -113,7 +113,7 @@ pub(crate) fn client_event_writer(
for (id, peer_state) in updates {
match peer_state {
matchbox_socket::PeerState::Connected => {
state.host_id.replace(id);
state.host_peer_id.replace(id);
commands.spawn(LatencyTracer::new(id));
next_connection_state.set(RtcClientStatus::Connected);
event_wtr.send(RtcClientEvent::ConnectedToHost(id));
Expand Down Expand Up @@ -144,7 +144,7 @@ pub fn send_latency_tracers(
state: Res<RtcClientState>,
mut client: RtcClient<LatencyTracerPayload>,
) {
let peer_id = state.id.expect("expected peer id");
let peer_id = state.peer_id.expect("expected peer id");
client.unreliable_to_host(LatencyTracerPayload::new(peer_id));
}

Expand All @@ -153,8 +153,8 @@ pub fn read_latency_tracers(
mut trace_query: Query<&mut LatencyTracer>,
mut client: RtcClient<LatencyTracerPayload>,
) {
let host_id = state.host_id.expect("expected host id");
let peer_id = state.id.expect("expected peer id");
let host_id = state.host_peer_id.expect("expected host id");
let peer_id = state.peer_id.expect("expected peer id");
let mut tracer = trace_query.single_mut();

for payload in client.read() {
Expand Down
2 changes: 1 addition & 1 deletion bevy_rtc/src/latency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mod bevy_rtc {
}

/// A packet containing information to track a peer's latency
#[derive(proc_macro_payload::Payload, Serialize, Deserialize, Debug, Clone)]
#[derive(proc_macro_protocol::Protocol, Serialize, Deserialize, Debug, Clone)]
pub struct LatencyTracerPayload {
pub from: PeerId,
pub sent: f64,
Expand Down
Loading

0 comments on commit 252f57c

Please sign in to comment.