Skip to content

Commit

Permalink
Merge pull request #106 from bushrat011899/Bevy0.13Update
Browse files Browse the repository at this point in the history
Update to Bevy 0.13
  • Loading branch information
johanhelsing authored Feb 25, 2024
2 parents 87b5866 + 277ef1f commit 9b1d286
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 124 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ categories = ["network-programming", "game-development"]
wasm-bindgen = ["instant/wasm-bindgen", "ggrs/wasm-bindgen"]

[dependencies]
bevy = { version = "0.12", default-features = false }
bevy = { version = "0.13", default-features = false }
bytemuck = { version = "1.7", features = ["derive"] }
instant = { version = "0.1", optional = true }
log = "0.4"
Expand All @@ -25,11 +25,11 @@ ggrs = { git = "https://github.com/gschup/ggrs", features = ["sync-send"] }
seahash = "4.1"

[dev-dependencies]
bevy = { version = "0.12", default-features = true }
bevy = { version = "0.13", default-features = true }
clap = { version = "4.4", features = ["derive"] }
rand = "0.8.4"
rand_xoshiro = "0.6"
serde = "1.0.130"
serde = "1.0.196"
serde_json = "1.0"
serial_test = "2.0"

Expand Down
24 changes: 12 additions & 12 deletions examples/box_game/box_game.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy::{prelude::*, utils::HashMap};
use bevy::{prelude::*, render::mesh::PlaneMeshBuilder, utils::HashMap};
use bevy_ggrs::{
AddRollbackCommandExtension, GgrsConfig, LocalInputs, LocalPlayers, PlayerInputs, Rollback,
Session,
Expand Down Expand Up @@ -54,24 +54,24 @@ pub struct FrameCount {
/// Collects player inputs during [`ReadInputs`](`bevy_ggrs::ReadInputs`) and creates a [`LocalInputs`] resource.
pub fn read_local_inputs(
mut commands: Commands,
keyboard_input: Res<Input<KeyCode>>,
keyboard_input: Res<ButtonInput<KeyCode>>,
local_players: Res<LocalPlayers>,
) {
let mut local_inputs = HashMap::new();

for handle in &local_players.0 {
let mut input: u8 = 0;

if keyboard_input.pressed(KeyCode::W) {
if keyboard_input.pressed(KeyCode::KeyW) {
input |= INPUT_UP;
}
if keyboard_input.pressed(KeyCode::A) {
if keyboard_input.pressed(KeyCode::KeyA) {
input |= INPUT_LEFT;
}
if keyboard_input.pressed(KeyCode::S) {
if keyboard_input.pressed(KeyCode::KeyS) {
input |= INPUT_DOWN;
}
if keyboard_input.pressed(KeyCode::D) {
if keyboard_input.pressed(KeyCode::KeyD) {
input |= INPUT_RIGHT;
}

Expand All @@ -95,16 +95,16 @@ pub fn setup_system(

// A ground plane
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane {
size: PLANE_SIZE,
..default()
mesh: meshes.add(Mesh::from(PlaneMeshBuilder {
plane: Plane3d::new(Vec3::Y),
half_size: Vec2::splat(PLANE_SIZE / 2.0),
})),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
material: materials.add(StandardMaterial::from(Color::rgb(0.3, 0.5, 0.3))),
..default()
});

let r = PLANE_SIZE / 4.;
let mesh = meshes.add(Mesh::from(shape::Cube { size: CUBE_SIZE }));
let mesh = meshes.add(Mesh::from(Cuboid::from_size(Vec3::splat(CUBE_SIZE))));

for handle in 0..num_players {
let rot = handle as f32 / num_players as f32 * 2. * std::f32::consts::PI;
Expand All @@ -123,7 +123,7 @@ pub fn setup_system(
// ...add visual information...
PbrBundle {
mesh: mesh.clone(),
material: materials.add(color.into()),
material: materials.add(StandardMaterial::from(color)),
transform,
..default()
},
Expand Down
4 changes: 2 additions & 2 deletions examples/stress_tests/particles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const INPUT_NOOP: u8 = 1 << 5;

fn read_local_inputs(
mut commands: Commands,
keyboard_input: Res<Input<KeyCode>>,
keyboard_input: Res<ButtonInput<KeyCode>>,
local_players: Res<LocalPlayers>,
) {
let mut local_inputs = HashMap::new();
Expand All @@ -88,7 +88,7 @@ fn read_local_inputs(
}

// n is a no-op key, press to simply trigger a rollback
if keyboard_input.pressed(KeyCode::N) {
if keyboard_input.pressed(KeyCode::KeyN) {
input |= INPUT_NOOP;
}

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//!
//! See [`GgrsPlugin`] for getting started.
#![forbid(unsafe_code)] // let us try
#![allow(clippy::type_complexity)] // Suppress warnings around Query

use bevy::{
ecs::{
Expand Down
4 changes: 2 additions & 2 deletions src/rollback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ pub trait AddRollbackCommandExtension: private::AddRollbackCommandExtensionSeal
fn add_rollback(&mut self) -> &mut Self;
}

impl<'w, 's, 'a> private::AddRollbackCommandExtensionSeal for EntityCommands<'w, 's, 'a> {}
impl<'a> private::AddRollbackCommandExtensionSeal for EntityCommands<'a> {}

impl<'w, 's, 'a> AddRollbackCommandExtension for EntityCommands<'w, 's, 'a> {
impl<'a> AddRollbackCommandExtension for EntityCommands<'a> {
fn add_rollback(&mut self) -> &mut Self {
self.add(AddRollbackCommand);
self
Expand Down
58 changes: 8 additions & 50 deletions src/snapshot/component_map.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use std::marker::PhantomData;

use bevy::{
ecs::entity::{EntityMapper, MapEntities},
prelude::*,
};
use bevy::{ecs::entity::MapEntities, prelude::*};

use crate::{LoadWorld, LoadWorldSet, RollbackEntityMap};

Expand All @@ -26,8 +23,8 @@ use crate::{LoadWorld, LoadWorldSet, RollbackEntityMap};
/// struct BestFriend(Entity);
///
/// impl MapEntities for BestFriend {
/// fn map_entities(&mut self, entity_mapper: &mut EntityMapper) {
/// self.0 = entity_mapper.get_or_reserve(self.0);
/// fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
/// self.0 = entity_mapper.map_entity(self.0);
/// }
/// }
///
Expand Down Expand Up @@ -72,55 +69,16 @@ fn apply_rollback_map_to_component_inner<C>(world: &mut World, map: Mut<Rollback
where
C: Component + MapEntities,
{
let mut applied_entity_map = map.generate_map();

EntityMapper::world_scope(&mut applied_entity_map, world, apply_map::<C>);
for (original, _new) in map.iter() {
if let Some(mut component) = world.get_mut::<C>(original) {
component.map_entities(&mut map.as_ref());
}
}

trace!(
"Mapped {}",
bevy::utils::get_short_name(std::any::type_name::<C>())
);

// If the entity map is now larger than the set of rollback entities, then dead entities were created.
// TODO: This workaround is required because the current behavior of `map_all_entities` is to change all entities,
// creating dead entities instead of leaving them with their original value. If `EntityMapper` behavior changes,
// then this workaround may no longer be required.
if applied_entity_map.len() > map.len() {
// Reverse dead-mappings, no-op correct mappings
for original in applied_entity_map.keys().copied().collect::<Vec<_>>() {
let mapped = applied_entity_map.remove(&original).unwrap();

if map.get(original).is_some() {
// Rollback entity was correctly mapped; no-op
applied_entity_map.insert(mapped, mapped);
} else {
// An untracked bystander was mapped to a dead end; reverse
applied_entity_map.insert(mapped, original);
}
}

// Map entities a second time, fixing dead entities
EntityMapper::world_scope(&mut applied_entity_map, world, apply_map::<C>);

trace!(
"Re-Mapped {}",
bevy::utils::get_short_name(std::any::type_name::<C>())
);
}
}

fn apply_map<C: Component + MapEntities>(world: &mut World, entity_mapper: &mut EntityMapper) {
let entities = entity_mapper
.get_map()
.values()
.copied()
.collect::<Vec<Entity>>();

for entity in &entities {
if let Some(mut component) = world.get_mut::<C>(*entity) {
component.map_entities(entity_mapper);
}
}
}

impl<C> Plugin for ComponentMapEntitiesPlugin<C>
Expand Down
48 changes: 6 additions & 42 deletions src/snapshot/resource_map.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use std::marker::PhantomData;

use bevy::{
ecs::entity::{EntityMapper, MapEntities},
prelude::*,
};
use bevy::{ecs::entity::MapEntities, prelude::*};

use crate::{LoadWorld, LoadWorldSet, RollbackEntityMap};

Expand All @@ -26,8 +23,8 @@ use crate::{LoadWorld, LoadWorldSet, RollbackEntityMap};
/// struct Player(Entity);
///
/// impl MapEntities for Player {
/// fn map_entities(&mut self, entity_mapper: &mut EntityMapper) {
/// self.0 = entity_mapper.get_or_reserve(self.0);
/// fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
/// self.0 = entity_mapper.map_entity(self.0);
/// }
/// }
///
Expand Down Expand Up @@ -72,47 +69,14 @@ fn apply_rollback_map_to_resource_inner<R>(world: &mut World, map: Mut<RollbackE
where
R: Resource + MapEntities,
{
let mut applied_entity_map = map.generate_map();

EntityMapper::world_scope(&mut applied_entity_map, world, apply_map::<R>);
if let Some(mut resource) = world.get_resource_mut::<R>() {
resource.map_entities(&mut map.as_ref());
}

trace!(
"Mapped {}",
bevy::utils::get_short_name(std::any::type_name::<R>())
);

// If the entity map is now larger than the set of rollback entities, then dead entities were created.
// TODO: This workaround is required because the current behavior of `map_all_entities` is to change all entities,
// creating dead entities instead of leaving them with their original value. If `EntityMapper` behavior changes,
// then this workaround may no longer be required.
if applied_entity_map.len() > map.len() {
// Reverse dead-mappings, no-op correct mappings
for original in applied_entity_map.keys().copied().collect::<Vec<_>>() {
let mapped = applied_entity_map.remove(&original).unwrap();

if map.get(original).is_some() {
// Rollback entity was correctly mapped; no-op
applied_entity_map.insert(mapped, mapped);
} else {
// An untracked bystander was mapped to a dead end; reverse
applied_entity_map.insert(mapped, original);
}
}

// Map entities a second time, fixing dead entities
EntityMapper::world_scope(&mut applied_entity_map, world, apply_map::<R>);

trace!(
"Re-Mapped {}",
bevy::utils::get_short_name(std::any::type_name::<R>())
);
}
}

fn apply_map<R: Resource + MapEntities>(world: &mut World, entity_mapper: &mut EntityMapper) {
if let Some(mut resource) = world.get_resource_mut::<R>() {
resource.map_entities(entity_mapper);
}
}

impl<R> Plugin for ResourceMapEntitiesPlugin<R>
Expand Down
25 changes: 22 additions & 3 deletions src/snapshot/rollback_entity_map.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
use bevy::{prelude::*, utils::HashMap};
use bevy::{ecs::entity::EntityHashMap, prelude::*, utils::HashMap};

/// A [`Resource`] which provides an [`EntityMap`], describing how [`Entities`](`Entity`)
/// changed during a rollback.
#[derive(Resource, Default)]
pub struct RollbackEntityMap(HashMap<Entity, Entity>);
pub struct RollbackEntityMap(EntityHashMap<Entity>);

impl From<EntityHashMap<Entity>> for RollbackEntityMap {
fn from(value: EntityHashMap<Entity>) -> Self {
Self(value)
}
}

impl From<HashMap<Entity, Entity>> for RollbackEntityMap {
fn from(value: HashMap<Entity, Entity>) -> Self {
Self(value.into_iter().collect())
}
}

impl RollbackEntityMap {
/// Create a new [`RollbackEntityMap`], which can generate [`EntityMaps`](`EntityMap`) as required.
pub fn new(map: HashMap<Entity, Entity>) -> Self {
Self(map)
map.into()
}

/// Generate an owned [`EntityMap`], which can be used concurrently with other systems.
Expand Down Expand Up @@ -46,3 +58,10 @@ impl RollbackEntityMap {
map.is_empty()
}
}

impl<'a> EntityMapper for &'a RollbackEntityMap {
/// Map the provided [`Entity`], or return it unmodified if it does not need to be mapped.
fn map_entity(&mut self, entity: Entity) -> Entity {
self.get(entity).unwrap_or(entity)
}
}
2 changes: 1 addition & 1 deletion src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl GgrsTimePlugin {

impl Plugin for GgrsTimePlugin {
fn build(&self, app: &mut App) {
app.insert_resource(Time::new_with(GgrsTime::default()))
app.insert_resource(Time::new_with(GgrsTime))
.add_plugins(ResourceSnapshotPlugin::<CloneStrategy<Time<GgrsTime>>>::default())
.add_systems(
AdvanceWorld,
Expand Down
Loading

0 comments on commit 9b1d286

Please sign in to comment.