Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,27 @@ jobs:
- name: Test doc
run: cargo test --all-features --doc

feature-combinations:
name: Feature combinations
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v4

- name: Instal stable toolchain
uses: dtolnay/rust-toolchain@stable

- name: Cache crates
uses: Swatinem/rust-cache@v2

- name: Install Cargo Hack
run: cargo install cargo-hack

- name: Check feature combinations
run: cargo hack check --feature-powerset
env:
RUSTFLAGS: -Aunused -Dwarnings

test:
name: Test
runs-on: ubuntu-latest
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- `ServerEventsPlugin` and `ClientEventsPlugin` can be disabled on client-only and server-only apps respectively.
- Put `ClientDiagnosticsPlugin` under `diagnostics` feature (disabled by default) and make it part of the `RepliconPlugins` group.
- Put `ClientDiagnosticsPlugin` under `client_diagnostics` feature (disabled by default) and make it part of the `RepliconPlugins` group.
- Put `scene` module under `scene` feature (enabled by default).
- Put `parent_sync` module under `parent_sync` feature (enabled by default).
- Put `client` module under `client` feature (enabled by default).
- Put `server` module under `server` feature (enabled by default).
- `TestFnsEntityExt::serialize` now accepts `RepliconTick` for server tick instead of using `ServerTick` resource internally.
- Move `replicon_client`, `server_entity_map`, `replicon_server`, `connected_clients` under `core` module. These modules are needed for both client and server.
- Move `VisibilityPolicy` to `connected_clients` module.
- Do not divide values per seconds by the number of messages for `ClientDiagnosticsPlugin`.
- Move `server::events::event_data` module to `core::event_registry::server_event`.
- Move `client::events::event_data` module to `core::event_registry::client_event`.
Expand Down
56 changes: 51 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,16 @@ criterion = { version = "0.5", default-features = false, features = [
] }

[features]
default = ["scene", "parent_sync"]
default = ["scene", "parent_sync", "client", "server"]

# Integration with Bevy diagnostics.
diagnostics = []
# Client-related logic.
client = []

# Server-related logic.
server = []

# Integration with Bevy diagnostics for client.
client_diagnostics = ["client"]

# Replication into a scene.
scene = ["bevy/bevy_scene"]
Expand All @@ -62,13 +68,53 @@ name = "replication"
harness = false

[[test]]
name = "stats"
required-features = ["diagnostics"]
name = "changes"
required-features = ["client", "server"]

[[test]]
name = "client_event"
required-features = ["client", "server"]

[[test]]
name = "connection"
required-features = ["client", "server"]

[[test]]
name = "despawn"
required-features = ["client", "server"]

[[test]]
name = "fns"
required-features = ["client"]

[[test]]
name = "insertion"
required-features = ["client", "server"]

[[test]]
name = "removal"
required-features = ["client", "server"]

[[test]]
name = "scene"
required-features = ["scene"]

[[test]]
name = "server_event"
required-features = ["client", "server"]

[[test]]
name = "spawn"
required-features = ["client", "server"]

[[test]]
name = "stats"
required-features = ["client_diagnostics", "client", "server"]

[[test]]
name = "visibility"
required-features = ["client", "server"]

[lints.clippy]
type_complexity = "allow"
too_many_arguments = "allow"
Expand Down
8 changes: 3 additions & 5 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
pub mod confirm_history;
#[cfg(feature = "diagnostics")]
#[cfg(feature = "client_diagnostics")]
pub mod diagnostics;
pub mod events;
pub mod replicon_client;
pub mod server_entity_map;

use std::{io::Cursor, mem};

Expand All @@ -18,12 +16,12 @@ use crate::core::{
common_conditions::{client_connected, client_just_connected, client_just_disconnected},
ctx::{DespawnCtx, RemoveCtx, WriteCtx},
replication_registry::ReplicationRegistry,
replicon_client::RepliconClient,
replicon_tick::RepliconTick,
server_entity_map::ServerEntityMap,
Replicated,
};
use confirm_history::ConfirmHistory;
use replicon_client::RepliconClient;
use server_entity_map::ServerEntityMap;

/// Client functionality and replication receiving.
///
Expand Down
7 changes: 3 additions & 4 deletions src/client/events.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use super::{
replicon_client::RepliconClient, server_entity_map::ServerEntityMap, ClientPlugin, ClientSet,
ServerInitTick,
};
use super::{ClientPlugin, ClientSet, ServerInitTick};
use crate::core::{
common_conditions::*,
ctx::{ClientReceiveCtx, ClientSendCtx},
event_registry::EventRegistry,
replicon_client::RepliconClient,
server_entity_map::ServerEntityMap,
};
use bevy::prelude::*;

Expand Down
4 changes: 4 additions & 0 deletions src/core.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
pub mod channels;
pub mod command_markers;
pub mod common_conditions;
pub mod connected_clients;
pub mod ctx;
pub mod event_registry;
pub mod replication_registry;
pub mod replication_rules;
pub mod replicon_client;
pub mod replicon_server;
pub mod replicon_tick;
pub mod server_entity_map;

use bevy::prelude::*;
use serde::{Deserialize, Serialize};
Expand Down
2 changes: 1 addition & 1 deletion src/core/common_conditions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bevy::prelude::*;

use crate::{client::replicon_client::RepliconClient, server::replicon_server::RepliconServer};
use super::{replicon_client::RepliconClient, replicon_server::RepliconServer};

/// Returns `true` if the server is running.
pub fn server_running(server: Option<Res<RepliconServer>>) -> bool {
Expand Down
39 changes: 25 additions & 14 deletions src/server/connected_clients.rs → src/core/connected_clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,20 @@ use bevy::{
utils::{Duration, HashMap},
};

use crate::{
core::{replicon_tick::RepliconTick, ClientId},
server::VisibilityPolicy,
};
use crate::core::{replicon_tick::RepliconTick, ClientId};
use client_visibility::ClientVisibility;

/// Stores information about connected clients.
///
/// Inserted as resource by [`ServerPlugin`](crate::server::ServerPlugin).
#[derive(Resource, Default)]
pub struct ConnectedClients {
clients: Vec<ConnectedClient>,
policy: VisibilityPolicy,
}

impl ConnectedClients {
pub(super) fn new(policy: VisibilityPolicy) -> Self {
pub(crate) fn new(policy: VisibilityPolicy) -> Self {
Self {
clients: Default::default(),
policy,
Expand Down Expand Up @@ -106,7 +105,7 @@ impl ConnectedClients {
/// Initializes a new [`ConnectedClient`] for this client.
///
/// Reuses the memory from the buffers if available.
pub(super) fn add(&mut self, client_buffers: &mut ClientBuffers, client_id: ClientId) {
pub(crate) fn add(&mut self, client_buffers: &mut ClientBuffers, client_id: ClientId) {
debug!("adding connected `{client_id:?}`");

let client = if let Some(mut client) = client_buffers.clients.pop() {
Expand All @@ -122,7 +121,7 @@ impl ConnectedClients {
/// Removes a connected client.
///
/// Keeps allocated memory in the buffers for reuse.
pub(super) fn remove(&mut self, client_buffers: &mut ClientBuffers, client_id: ClientId) {
pub(crate) fn remove(&mut self, client_buffers: &mut ClientBuffers, client_id: ClientId) {
debug!("removing disconnected `{client_id:?}`");

let index = self
Expand All @@ -138,7 +137,7 @@ impl ConnectedClients {
/// Clears all clients.
///
/// Keeps allocated memory in the buffers for reuse.
pub(super) fn clear(&mut self, client_buffers: &mut ClientBuffers) {
pub(crate) fn clear(&mut self, client_buffers: &mut ClientBuffers) {
for mut client in self.clients.drain(..) {
client_buffers.entities.extend(client.drain_entities());
client_buffers.clients.push(client);
Expand Down Expand Up @@ -200,7 +199,7 @@ impl ConnectedClient {
}

/// Sets the client's init tick.
pub(super) fn set_init_tick(&mut self, tick: RepliconTick) {
pub(crate) fn set_init_tick(&mut self, tick: RepliconTick) {
self.init_tick = tick;
}

Expand Down Expand Up @@ -234,7 +233,7 @@ impl ConnectedClient {
///
/// Used later to acknowledge updated entities.
#[must_use]
pub(super) fn register_update(
pub(crate) fn register_update(
&mut self,
client_buffers: &mut ClientBuffers,
tick: Tick,
Expand Down Expand Up @@ -263,7 +262,7 @@ impl ConnectedClient {
///
/// The change tick is the reference point for determining if components on an entity have changed and
/// need to be replicated. Component changes older than the change limit are assumed to be acked by the client.
pub(super) fn set_change_tick(&mut self, entity: Entity, tick: Tick) {
pub(crate) fn set_change_tick(&mut self, entity: Entity, tick: Tick) {
self.change_ticks.insert(entity, tick);
}

Expand All @@ -277,7 +276,7 @@ impl ConnectedClient {
/// Change limits for all entities from this update will be set to the update's tick if it's higher.
///
/// Keeps allocated memory in the buffers for reuse.
pub(super) fn acknowledge(
pub(crate) fn acknowledge(
&mut self,
client_buffers: &mut ClientBuffers,
tick: Tick,
Expand Down Expand Up @@ -323,7 +322,7 @@ impl ConnectedClient {
/// Drains all entities for which visibility was lost during this tick.
///
/// Internal cleanup happens lazily during the iteration.
pub(super) fn drain_lost_visibility(&mut self) -> impl Iterator<Item = Entity> + '_ {
pub(crate) fn drain_lost_visibility(&mut self) -> impl Iterator<Item = Entity> + '_ {
self.visibility.drain_lost_visibility().inspect(|entity| {
self.change_ticks.remove(entity);
})
Expand All @@ -332,7 +331,7 @@ impl ConnectedClient {
/// Removes all updates older then `min_timestamp`.
///
/// Keeps allocated memory in the buffers for reuse.
pub(super) fn remove_older_updates(
pub(crate) fn remove_older_updates(
&mut self,
client_buffers: &mut ClientBuffers,
min_timestamp: Duration,
Expand Down Expand Up @@ -369,3 +368,15 @@ struct UpdateInfo {
timestamp: Duration,
entities: Vec<Entity>,
}

/// Controls how visibility will be managed via [`ClientVisibility`].
#[derive(Default, Debug, Clone, Copy)]
pub enum VisibilityPolicy {
/// All entities are visible by default and visibility can't be changed.
#[default]
All,
/// All entities are visible by default and should be explicitly registered to be hidden.
Blacklist,
/// All entities are hidden by default and should be explicitly registered to be visible.
Whitelist,
}
4 changes: 1 addition & 3 deletions src/core/ctx.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use bevy::{prelude::*, reflect::TypeRegistry};

use crate::{
client::server_entity_map::ServerEntityMap, core::replicon_tick::RepliconTick, Replicated,
};
use super::{replicon_tick::RepliconTick, server_entity_map::ServerEntityMap, Replicated};

/// Replication context for serialization function.
#[non_exhaustive]
Expand Down
14 changes: 6 additions & 8 deletions src/core/event_registry/client_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@ use bincode::{DefaultOptions, Options};
use serde::{de::DeserializeOwned, Serialize};

use super::EventRegistry;
use crate::{
client::replicon_client::RepliconClient,
core::{
channels::{RepliconChannel, RepliconChannels},
ctx::{ClientSendCtx, ServerReceiveCtx},
ClientId,
},
server::replicon_server::RepliconServer,
use crate::core::{
channels::{RepliconChannel, RepliconChannels},
ctx::{ClientSendCtx, ServerReceiveCtx},
replicon_client::RepliconClient,
replicon_server::RepliconServer,
ClientId,
};

/// An extension trait for [`App`] for creating client events.
Expand Down
20 changes: 8 additions & 12 deletions src/core/event_registry/server_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,14 @@ use ordered_multimap::ListOrderedMultimap;
use serde::{de::DeserializeOwned, Serialize};

use super::EventRegistry;
use crate::{
client::replicon_client::RepliconClient,
core::{
channels::{RepliconChannel, RepliconChannels},
ctx::{ClientReceiveCtx, ServerSendCtx},
replicon_tick::RepliconTick,
ClientId,
},
server::{
connected_clients::{ConnectedClient, ConnectedClients},
replicon_server::RepliconServer,
},
use crate::core::{
channels::{RepliconChannel, RepliconChannels},
connected_clients::{ConnectedClient, ConnectedClients},
ctx::{ClientReceiveCtx, ServerSendCtx},
replicon_client::RepliconClient,
replicon_server::RepliconServer,
replicon_tick::RepliconTick,
ClientId,
};

/// An extension trait for [`App`] for creating client events.
Expand Down
Loading