Skip to content

Commit 8ea7d21

Browse files
authored
Put ClientDiagnosticsPlugin under diagnostics feature (#295)
1 parent c775e20 commit 8ea7d21

File tree

8 files changed

+165
-132
lines changed

8 files changed

+165
-132
lines changed

.github/workflows/main.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
run: cargo clippy --benches --tests -- -D warnings
5151

5252
- name: Rustdoc
53-
run: cargo rustdoc -- -D warnings
53+
run: cargo rustdoc --all-features -- -D warnings
5454

5555
doctest:
5656
name: Doctest
@@ -66,7 +66,7 @@ jobs:
6666
uses: Swatinem/rust-cache@v2
6767

6868
- name: Test doc
69-
run: cargo test --doc
69+
run: cargo test --all-features --doc
7070

7171
test:
7272
name: Test
@@ -88,7 +88,7 @@ jobs:
8888
run: cargo install cargo-tarpaulin
8989

9090
- name: Test
91-
run: cargo tarpaulin --engine llvm --out lcov --exclude-files benches/* --exclude-files bevy_replicon_renet/*
91+
run: cargo tarpaulin --all-features --engine llvm --out lcov --exclude-files benches/* --exclude-files bevy_replicon_renet/*
9292

9393
- name: Upload code coverage results
9494
if: github.actor != 'dependabot[bot]'

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Changed
1111

1212
- `ServerEventsPlugin` and `ClientEventsPlugin` can be disabled on client-only and server-only apps respectively.
13+
- Put `ClientDiagnosticsPlugin` under `diagnostics` feature and make it part of the `RepliconPlugins` group.
1314
- Do not divide values per seconds by the number of messages for `ClientDiagnosticsPlugin`.
1415
- Move `server::events::event_data` module to `core::event_registry::server_event`.
1516
- Move `client::events::event_data` module to `core::event_registry::client_event`.

Cargo.toml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ categories = ["game-development", "network-programming"]
2020
license = "MIT OR Apache-2.0"
2121
include = ["/benches", "/src", "/tests", "/LICENSE*"]
2222

23+
[package.metadata.docs.rs]
24+
rustdoc-args = ["-Zunstable-options", "--cfg", "docsrs"]
25+
all-features = true
26+
2327
[dependencies]
2428
bevy = { version = "0.14.0-rc.3", default-features = false, features = [
2529
"bevy_scene",
@@ -40,14 +44,24 @@ criterion = { version = "0.5", default-features = false, features = [
4044
"cargo_bench_support",
4145
] }
4246

43-
[lints.clippy]
44-
type_complexity = "allow"
45-
too_many_arguments = "allow"
47+
[features]
48+
default = []
49+
50+
# Plugin for integration with Bevy diagnostics.
51+
diagnostics = []
4652

4753
[[bench]]
4854
name = "replication"
4955
harness = false
5056

57+
[[test]]
58+
name = "stats"
59+
required-features = ["diagnostics"]
60+
61+
[lints.clippy]
62+
type_complexity = "allow"
63+
too_many_arguments = "allow"
64+
5165
# Removed until `bevy_renet` supports 0.14.0-rc.3.
5266
# [workspace]
5367
# members = ["bevy_replicon_renet"]

src/client.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod confirm_history;
2+
#[cfg(feature = "diagnostics")]
23
pub mod diagnostics;
34
pub mod events;
45
pub mod replicon_client;
@@ -21,7 +22,6 @@ use crate::core::{
2122
Replicated,
2223
};
2324
use confirm_history::ConfirmHistory;
24-
use diagnostics::ClientStats;
2525
use replicon_client::RepliconClient;
2626
use server_entity_map::ServerEntityMap;
2727

@@ -640,3 +640,26 @@ pub(super) struct BufferedUpdate {
640640
/// Update data.
641641
message: Bytes,
642642
}
643+
644+
/// Replication stats during message processing.
645+
///
646+
/// Statistic will be collected only if the resource is present.
647+
/// The resource is not added by default.
648+
///
649+
/// See also [`ClientDiagnosticsPlugin`](diagnostics::ClientDiagnosticsPlugin)
650+
/// for automatic integration with Bevy diagnostics.
651+
#[derive(Default, Resource, Debug)]
652+
pub struct ClientStats {
653+
/// Incremented per entity that changes.
654+
pub entities_changed: u32,
655+
/// Incremented for every component that changes.
656+
pub components_changed: u32,
657+
/// Incremented per client mapping added.
658+
pub mappings: u32,
659+
/// Incremented per entity despawn.
660+
pub despawns: u32,
661+
/// Replication messages received.
662+
pub messages: u32,
663+
/// Replication bytes received in message payloads (without internal messaging plugin data).
664+
pub bytes: u64,
665+
}

src/client/diagnostics.rs

Lines changed: 38 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,67 +6,50 @@ use bevy::{
66
};
77
use std::time::Duration;
88

9-
/// Replication stats during message processing.
10-
///
11-
/// Flushed to Diagnostics system periodically.
12-
#[derive(Default, Resource, Debug)]
13-
pub struct ClientStats {
14-
/// Incremented per entity that changes.
15-
pub entities_changed: u32,
16-
/// Incremented for every component that changes.
17-
pub components_changed: u32,
18-
/// Incremented per client mapping added.
19-
pub mappings: u32,
20-
/// Incremented per entity despawn.
21-
pub despawns: u32,
22-
/// Replication messages received.
23-
pub messages: u32,
24-
/// Replication bytes received in message payloads (without internal messaging plugin data).
25-
pub bytes: u64,
26-
}
9+
use super::ClientStats;
2710

28-
/// Plugin to write Diagnostics every second.
11+
/// Plugin to write [`Diagnostics`] based on [`ClientStats`] every second.
2912
///
30-
/// Not added by default.
13+
/// Adds [`ClientStats`] resource and automatically resets it to get diagnostics per second.
3114
pub struct ClientDiagnosticsPlugin;
3215

3316
impl Plugin for ClientDiagnosticsPlugin {
3417
fn build(&self, app: &mut App) {
35-
app.add_systems(
36-
Update,
37-
Self::add_measurements.run_if(on_timer(Duration::from_secs(1))),
38-
)
39-
.init_resource::<ClientStats>()
40-
.register_diagnostic(
41-
Diagnostic::new(Self::ENTITY_CHANGES)
42-
.with_suffix("entities changed per second")
43-
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
44-
)
45-
.register_diagnostic(
46-
Diagnostic::new(Self::COMPONENT_CHANGES)
47-
.with_suffix("components changed per second")
48-
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
49-
)
50-
.register_diagnostic(
51-
Diagnostic::new(Self::MAPPINGS)
52-
.with_suffix("mappings added per second")
53-
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
54-
)
55-
.register_diagnostic(
56-
Diagnostic::new(Self::DESPAWNS)
57-
.with_suffix("despawns per second")
58-
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
59-
)
60-
.register_diagnostic(
61-
Diagnostic::new(Self::MESSAGES)
62-
.with_suffix("messages per second")
63-
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
64-
)
65-
.register_diagnostic(
66-
Diagnostic::new(Self::BYTES)
67-
.with_suffix("bytes per second")
68-
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
69-
);
18+
app.init_resource::<ClientStats>()
19+
.add_systems(
20+
Update,
21+
Self::add_measurements.run_if(on_timer(Duration::from_secs(1))),
22+
)
23+
.register_diagnostic(
24+
Diagnostic::new(Self::ENTITY_CHANGES)
25+
.with_suffix("entities changed per second")
26+
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
27+
)
28+
.register_diagnostic(
29+
Diagnostic::new(Self::COMPONENT_CHANGES)
30+
.with_suffix("components changed per second")
31+
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
32+
)
33+
.register_diagnostic(
34+
Diagnostic::new(Self::MAPPINGS)
35+
.with_suffix("mappings added per second")
36+
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
37+
)
38+
.register_diagnostic(
39+
Diagnostic::new(Self::DESPAWNS)
40+
.with_suffix("despawns per second")
41+
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
42+
)
43+
.register_diagnostic(
44+
Diagnostic::new(Self::MESSAGES)
45+
.with_suffix("messages per second")
46+
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
47+
)
48+
.register_diagnostic(
49+
Diagnostic::new(Self::BYTES)
50+
.with_suffix("bytes per second")
51+
.with_max_history_length(Self::DIAGNOSTIC_HISTORY_LEN),
52+
);
7053
}
7154
}
7255

src/lib.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ To reduce packet size there are the following limits per replication update:
439439
- Up to [`u16::MAX`] entities that have removed components with up to [`u16::MAX`] bytes of component data.
440440
- Up to [`u16::MAX`] entities that were despawned.
441441
*/
442+
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
442443

443444
pub mod client;
444445
pub mod core;
@@ -453,10 +454,9 @@ pub mod prelude {
453454

454455
pub use super::{
455456
client::{
456-
diagnostics::{ClientDiagnosticsPlugin, ClientStats},
457457
events::ClientEventsPlugin,
458458
replicon_client::{RepliconClient, RepliconClientStatus},
459-
ClientPlugin, ClientSet,
459+
ClientPlugin, ClientSet, ClientStats,
460460
},
461461
core::{
462462
channels::{ChannelKind, RepliconChannel, RepliconChannels},
@@ -481,6 +481,9 @@ pub mod prelude {
481481
},
482482
RepliconPlugins,
483483
};
484+
485+
#[cfg(feature = "diagnostics")]
486+
pub use super::client::diagnostics::ClientDiagnosticsPlugin;
484487
}
485488

486489
pub use bincode;
@@ -493,12 +496,20 @@ pub struct RepliconPlugins;
493496

494497
impl PluginGroup for RepliconPlugins {
495498
fn build(self) -> PluginGroupBuilder {
496-
PluginGroupBuilder::start::<Self>()
499+
let mut group = PluginGroupBuilder::start::<Self>();
500+
group = group
497501
.add(RepliconCorePlugin)
498502
.add(ParentSyncPlugin)
499503
.add(ClientPlugin)
500504
.add(ServerPlugin::default())
501505
.add(ClientEventsPlugin)
502-
.add(ServerEventsPlugin)
506+
.add(ServerEventsPlugin);
507+
508+
#[cfg(feature = "diagnostics")]
509+
{
510+
group = group.add(ClientDiagnosticsPlugin);
511+
}
512+
513+
group
503514
}
504515
}

tests/other.rs renamed to tests/connection.rs

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use bevy_replicon::{
33
core::channels::ReplicationChannel, prelude::*, server::server_tick::ServerTick,
44
test_app::ServerTestAppExt,
55
};
6-
use serde::{Deserialize, Serialize};
76

87
#[test]
98
fn client_to_server() {
@@ -203,68 +202,3 @@ fn server_inactive() {
203202

204203
assert_eq!(app.world().resource::<ServerTick>().get(), 0);
205204
}
206-
207-
#[test]
208-
fn diagnostics() {
209-
let mut server_app = App::new();
210-
let mut client_app = App::new();
211-
for app in [&mut server_app, &mut client_app] {
212-
app.add_plugins((
213-
MinimalPlugins,
214-
RepliconPlugins.set(ServerPlugin {
215-
tick_policy: TickPolicy::EveryFrame,
216-
..Default::default()
217-
}),
218-
))
219-
.replicate::<DummyComponent>();
220-
}
221-
client_app.add_plugins(ClientDiagnosticsPlugin);
222-
223-
server_app.connect_client(&mut client_app);
224-
225-
let client_entity = client_app.world_mut().spawn_empty().id();
226-
let server_entity = server_app
227-
.world_mut()
228-
.spawn((Replicated, DummyComponent))
229-
.id();
230-
231-
let client = client_app.world().resource::<RepliconClient>();
232-
let client_id = client.id().unwrap();
233-
234-
let mut entity_map = server_app.world_mut().resource_mut::<ClientEntityMap>();
235-
entity_map.insert(
236-
client_id,
237-
ClientMapping {
238-
server_entity,
239-
client_entity,
240-
},
241-
);
242-
243-
server_app.world_mut().spawn(Replicated).despawn();
244-
245-
server_app.update();
246-
server_app.exchange_with_client(&mut client_app);
247-
client_app.update();
248-
server_app.exchange_with_client(&mut client_app);
249-
250-
server_app
251-
.world_mut()
252-
.get_mut::<DummyComponent>(server_entity)
253-
.unwrap()
254-
.set_changed();
255-
256-
server_app.update();
257-
server_app.exchange_with_client(&mut client_app);
258-
client_app.update();
259-
260-
let stats = client_app.world().resource::<ClientStats>();
261-
assert_eq!(stats.entities_changed, 2);
262-
assert_eq!(stats.components_changed, 2);
263-
assert_eq!(stats.mappings, 1);
264-
assert_eq!(stats.despawns, 1);
265-
assert_eq!(stats.messages, 2);
266-
assert_eq!(stats.bytes, 33);
267-
}
268-
269-
#[derive(Component, Deserialize, Serialize)]
270-
struct DummyComponent;

0 commit comments

Comments
 (0)