Skip to content

Update to Bevy 0.13 #198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Feb 21, 2024
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Removed `Mapper` and `MapNetworkEntities` in favor of `EntityMapper` and `MapEntities` introduced in Bevy 0.13.0
- Changed conditional systems to follow the new pattern, avoid returning a closure.

## [0.22.0] - 2024-02-17

### Changed
Expand Down
8 changes: 3 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ license = "MIT OR Apache-2.0"
include = ["/benches", "/src", "/tests", "/LICENSE*"]

[dependencies]
bevy_renet = "0.0.10"
bevy = { version = "0.12.1", default-features = false, features = [
"bevy_scene",
] }
bevy_renet = "0.0.11"
bevy = { version = "0.13", default-features = false, features = ["bevy_scene"] }
bincode = "1.3"
serde = "1.0"
varint-rs = "2.2"
Expand All @@ -36,7 +34,7 @@ spin_sleep = "1.1"
anyhow = "1.0"
clap = { version = "4.1", features = ["derive"] }
ron = "0.8"
bevy = { version = "0.12", default-features = false, features = [
bevy = { version = "0.13", default-features = false, features = [
"bevy_asset",
"bevy_core_pipeline",
"bevy_render",
Expand Down
35 changes: 13 additions & 22 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,27 @@ allow-osi-fsf-free = "either"
multiple-versions = "deny"
wildcards = "allow"
skip = [
{ name = "async-channel", version = "1.9" },
{ name = "async-lock", version = "2.8" },
{ name = "bitflags", version = "2.0" },
{ name = "event-listener", version = "<5.0" },
{ name = "event-listener-strategy", version = "0.5" },
{ name = "fastrand", version = "1.9" },
{ name = "foreign-types", version = "0.3" },
{ name = "foreign-types-shared", version = "0.1" },
{ name = "futures-lite", version = "1.13" },
{ name = "hashbrown", version = "0.12" },
{ name = "indexmap", version = "1.0" },
{ name = "libloading", version = "0.7" },
{ name = "num_enum", version = "0.6" },
{ name = "num_enum_derive", version = "0.5" },
{ name = "objc-sys", version = "0.2.0-beta.2" },
{ name = "objc2", version = "0.3.0-beta.3.patch-leaks.3" },
{ name = "objc2-encode", version = "2.0.0-pre.2" },
{ name = "redox_syscall", version = "0.3" },
{ name = "regex-automata", version = "0.1" },
{ name = "regex-syntax", version = "0.6" },
{ name = "regex-syntax", version = "0.7" },
{ name = "syn", version = "1.0" },
{ name = "toml_edit", version = "0.19" },
{ name = "tracing-log", version = "0.1" },
{ name = "windows-sys", version = "0.45" },
{ name = "windows-targets", version = "0.42" },
{ name = "windows_aarch64_gnullvm", version = "0.42" },
{ name = "windows_aarch64_msvc", version = "0.42" },
{ name = "windows_i686_gnu", version = "0.42" },
{ name = "windows_i686_msvc", version = "0.42" },
{ name = "windows_x86_64_gnu", version = "0.42" },
{ name = "windows_x86_64_gnullvm", version = "0.42" },
{ name = "windows_x86_64_msvc", version = "0.42" },
{ name = "windows" },
{ name = "windows-sys" },
{ name = "windows-targets" },
{ name = "windows_aarch64_gnullvm" },
{ name = "windows_aarch64_msvc" },
{ name = "windows_i686_gnu" },
{ name = "windows_i686_msvc" },
{ name = "windows_x86_64_gnu" },
{ name = "windows_x86_64_gnullvm" },
{ name = "windows_x86_64_msvc" },
]

[sources]
Expand Down
14 changes: 7 additions & 7 deletions examples/simple_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ impl Plugin for SimpleBoxPlugin {
.add_systems(
Update,
(
Self::movement_system.run_if(has_authority()), // Runs only on the server or a single player.
Self::server_event_system.run_if(resource_exists::<RenetServer>()), // Runs only on the server.
Self::movement_system.run_if(has_authority), // Runs only on the server or a single player.
Self::server_event_system.run_if(resource_exists::<RenetServer>), // Runs only on the server.
(Self::draw_boxes_system, Self::input_system),
),
);
Expand Down Expand Up @@ -174,18 +174,18 @@ impl SimpleBoxPlugin {
}

/// Reads player inputs and sends [`MoveCommandEvents`]
fn input_system(mut move_events: EventWriter<MoveDirection>, input: Res<Input<KeyCode>>) {
fn input_system(mut move_events: EventWriter<MoveDirection>, input: Res<ButtonInput<KeyCode>>) {
let mut direction = Vec2::ZERO;
if input.pressed(KeyCode::Right) {
if input.pressed(KeyCode::ArrowRight) {
direction.x += 1.0;
}
if input.pressed(KeyCode::Left) {
if input.pressed(KeyCode::ArrowLeft) {
direction.x -= 1.0;
}
if input.pressed(KeyCode::Up) {
if input.pressed(KeyCode::ArrowUp) {
direction.y += 1.0;
}
if input.pressed(KeyCode::Down) {
if input.pressed(KeyCode::ArrowDown) {
direction.y -= 1.0;
}
if direction != Vec2::ZERO {
Expand Down
46 changes: 23 additions & 23 deletions examples/tic_tac_toe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct TicTacToePlugin;

impl Plugin for TicTacToePlugin {
fn build(&self, app: &mut App) {
app.add_state::<GameState>()
app.init_state::<GameState>()
.init_resource::<SymbolFont>()
.init_resource::<CurrentTurn>()
.replicate::<Symbol>()
Expand All @@ -70,18 +70,18 @@ impl Plugin for TicTacToePlugin {
.add_systems(
Update,
(
Self::connecting_text_system.run_if(resource_added::<RenetClient>()),
Self::server_waiting_text_system.run_if(resource_added::<RenetServer>()),
Self::server_event_system.run_if(resource_exists::<RenetServer>()),
Self::connecting_text_system.run_if(resource_added::<RenetClient>),
Self::server_waiting_text_system.run_if(resource_added::<RenetServer>),
Self::server_event_system.run_if(resource_exists::<RenetServer>),
Self::start_game_system
.run_if(client_connected())
.run_if(any_component_added::<Player>()), // Wait until client replicates players before starting the game.
.run_if(client_connected)
.run_if(any_component_added::<Player>), // Wait until client replicates players before starting the game.
(
Self::cell_interatction_system.run_if(local_player_turn()),
Self::picking_system.run_if(has_authority()),
Self::cell_interatction_system.run_if(local_player_turn),
Self::picking_system.run_if(has_authority),
Self::symbol_init_system,
Self::turn_advance_system.run_if(any_component_added::<CellIndex>()),
Self::symbol_turn_text_system.run_if(resource_changed::<CurrentTurn>()),
Self::turn_advance_system.run_if(any_component_added::<CellIndex>),
Self::symbol_turn_text_system.run_if(resource_changed::<CurrentTurn>),
)
.run_if(in_state(GameState::InGame)),
),
Expand Down Expand Up @@ -514,22 +514,22 @@ impl TicTacToePlugin {

/// Returns `true` if the local player can select cells.
fn local_player_turn(
) -> impl FnMut(Res<CurrentTurn>, Option<Res<NetcodeClientTransport>>, Query<(&Player, &Symbol)>) -> bool
{
|current_turn, client_transport, players| {
let client_id = client_transport
.map(|client| ClientId::from_raw(client.client_id()))
.unwrap_or(SERVER_ID);

players
.iter()
.any(|(player, &symbol)| player.0 == client_id && symbol == current_turn.0)
}
current_turn: Res<CurrentTurn>,
client_transport: Option<Res<NetcodeClientTransport>>,
players: Query<(&Player, &Symbol)>,
) -> bool {
let client_id = client_transport
.map(|client| client.client_id())
.unwrap_or(SERVER_ID);

players
.iter()
.any(|(player, &symbol)| player.0 == client_id && symbol == current_turn.0)
}

/// A condition for systems to check if any component of type `T` was added to the world.
fn any_component_added<T: Component>() -> impl FnMut(Query<(), Added<T>>) -> bool {
|components| !components.is_empty()
fn any_component_added<T: Component>(components: Query<(), Added<T>>) -> bool {
!components.is_empty()
}

const PORT: u16 = 5000;
Expand Down
33 changes: 14 additions & 19 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ pub mod diagnostics;

use std::io::Cursor;

use bevy::{prelude::*, utils::EntityHashMap};
use bevy::{ecs::entity::EntityHashMap, prelude::*};
use bevy_renet::{
client_connected, client_just_connected, client_just_disconnected,
renet::{Bytes, RenetClient},
transport::NetcodeClientPlugin,
RenetClientPlugin,
RenetClientPlugin, RenetReceive, RenetSend,
};
use bincode::{DefaultOptions, Options};
use varint_rs::VarintReader;
Expand All @@ -32,30 +32,24 @@ impl Plugin for ClientPlugin {
.configure_sets(
PreUpdate,
ClientSet::ResetEvents
.after(NetcodeClientPlugin::update_system)
.after(RenetReceive)
.before(ClientSet::Receive)
.run_if(client_just_connected()),
)
.configure_sets(
PreUpdate,
ClientSet::Receive.after(NetcodeClientPlugin::update_system),
.run_if(client_just_connected),
)
.configure_sets(PreUpdate, ClientSet::Receive.after(RenetReceive))
.configure_sets(
PreUpdate,
ClientSet::Reset
.after(NetcodeClientPlugin::update_system)
.run_if(client_just_disconnected()),
)
.configure_sets(
PostUpdate,
ClientSet::Send.before(NetcodeClientPlugin::send_packets),
.after(RenetReceive)
.run_if(client_just_disconnected),
)
.configure_sets(PostUpdate, ClientSet::Send.before(RenetSend))
.add_systems(
PreUpdate,
Self::replication_receiving_system
.map(Result::unwrap)
.in_set(ClientSet::Receive)
.run_if(client_connected()),
.run_if(client_connected),
)
.add_systems(PreUpdate, Self::reset_system.in_set(ClientSet::Reset));
}
Expand Down Expand Up @@ -453,14 +447,15 @@ fn apply_update_components(

/// Deserializes `entity` from compressed index and generation.
///
/// For details see [`ReplicationBuffer::write_entity`](crate::server::replication_message::replication_buffer::write_entity).
/// For details see
/// [`ReplicationBuffer::write_entity`](crate::server::replication_message::replication_buffer::write_entity).
fn deserialize_entity(cursor: &mut Cursor<&[u8]>) -> bincode::Result<Entity> {
let flagged_index: u64 = cursor.read_u64_varint()?;
let has_generation = (flagged_index & 1) > 0;
let generation = if has_generation {
cursor.read_u32_varint()?
cursor.read_u32_varint()? + 1
} else {
0u32
1u32
};

let bits = (generation as u64) << 32 | (flagged_index >> 1);
Expand Down Expand Up @@ -514,7 +509,7 @@ pub enum ClientSet {
///
/// If [`ClientSet::Reset`] is disabled, then this needs to be cleaned up manually.
#[derive(Default, Deref, DerefMut, Resource)]
pub struct ServerEntityTicks(EntityHashMap<Entity, RepliconTick>);
pub struct ServerEntityTicks(EntityHashMap<RepliconTick>);

/// All cached buffered updates, used by the replicon client to align replication updates with initialization
/// messages.
Expand Down
23 changes: 10 additions & 13 deletions src/client/client_mapper.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
use bevy::{
prelude::*,
utils::{hashbrown::hash_map::Entry, EntityHashMap},
};
use bevy::{ecs::entity::EntityHashMap, prelude::*, utils::hashbrown::hash_map::Entry};

use crate::replicon_core::replication_rules::{Mapper, Replication};
use crate::replicon_core::replication_rules::Replication;

/// Maps server entities into client entities inside components.
///
/// Spawns new client entity if a mapping doesn't exists.
pub struct ClientMapper<'a> {
world: &'a mut World,
server_to_client: &'a mut EntityHashMap<Entity, Entity>,
client_to_server: &'a mut EntityHashMap<Entity, Entity>,
server_to_client: &'a mut EntityHashMap<Entity>,
client_to_server: &'a mut EntityHashMap<Entity>,
}

impl<'a> ClientMapper<'a> {
Expand All @@ -25,8 +22,8 @@ impl<'a> ClientMapper<'a> {
}
}

impl Mapper for ClientMapper<'_> {
fn map(&mut self, entity: Entity) -> Entity {
impl EntityMapper for ClientMapper<'_> {
fn map_entity(&mut self, entity: Entity) -> Entity {
*self.server_to_client.entry(entity).or_insert_with(|| {
let client_entity = self.world.spawn(Replication).id();
self.client_to_server.insert(client_entity, entity);
Expand All @@ -41,8 +38,8 @@ impl Mapper for ClientMapper<'_> {
/// via [`Self::remove_by_client`] or [`Self::clear`].
#[derive(Default, Resource)]
pub struct ServerEntityMap {
server_to_client: EntityHashMap<Entity, Entity>,
client_to_server: EntityHashMap<Entity, Entity>,
server_to_client: EntityHashMap<Entity>,
client_to_server: EntityHashMap<Entity>,
}

impl ServerEntityMap {
Expand Down Expand Up @@ -110,12 +107,12 @@ impl ServerEntityMap {
}

#[inline]
pub fn to_client(&self) -> &EntityHashMap<Entity, Entity> {
pub fn to_client(&self) -> &EntityHashMap<Entity> {
&self.server_to_client
}

#[inline]
pub fn to_server(&self) -> &EntityHashMap<Entity, Entity> {
pub fn to_server(&self) -> &EntityHashMap<Entity> {
&self.client_to_server
}

Expand Down
Loading