Skip to content

Commit e4b39ba

Browse files
committed
Migrate to bevy 0.16
1 parent 7a426f6 commit e4b39ba

File tree

3 files changed

+58
-60
lines changed

3 files changed

+58
-60
lines changed

integration_tests/src/how_to_test_apps.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![cfg(test)]
12
//! Demonstrates simple integration testing of Bevy applications.
23
//!
34
//! By substituting [`DefaultPlugins`] with [`MinimalPlugins`], Bevy can run completely headless.

integration_tests/src/how_to_test_systems.rs

+29-20
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ struct Enemy {
77
score_value: u32,
88
}
99

10+
#[derive(Event)]
1011
struct EnemyDied(u32);
1112

1213
#[derive(Resource)]
1314
struct Score(u32);
1415

1516
fn update_score(mut dead_enemies: EventReader<EnemyDied>, mut score: ResMut<Score>) {
16-
for value in dead_enemies.iter() {
17+
for value in dead_enemies.read() {
1718
score.0 += value.0;
1819
}
1920
}
@@ -37,7 +38,7 @@ fn hurt_enemies(mut enemies: Query<&mut Enemy>) {
3738
}
3839
}
3940

40-
fn spawn_enemy(mut commands: Commands, keyboard_input: Res<Input<KeyCode>>) {
41+
fn spawn_enemy(mut commands: Commands, keyboard_input: Res<ButtonInput<KeyCode>>) {
4142
if keyboard_input.just_pressed(KeyCode::Space) {
4243
commands.spawn(Enemy {
4344
hit_points: 5,
@@ -58,11 +59,11 @@ fn did_hurt_enemy() {
5859
app.add_event::<EnemyDied>();
5960

6061
// Add our two systems
61-
app.add_systems((hurt_enemies, despawn_dead_enemies).chain());
62+
app.add_systems(Update, (hurt_enemies, despawn_dead_enemies).chain());
6263

6364
// Setup test entities
6465
let enemy_id = app
65-
.world
66+
.world_mut()
6667
.spawn(Enemy {
6768
hit_points: 5,
6869
score_value: 3,
@@ -73,8 +74,8 @@ fn did_hurt_enemy() {
7374
app.update();
7475

7576
// Check resulting changes
76-
assert!(app.world.get::<Enemy>(enemy_id).is_some());
77-
assert_eq!(app.world.get::<Enemy>(enemy_id).unwrap().hit_points, 4);
77+
assert!(app.world().get::<Enemy>(enemy_id).is_some());
78+
assert_eq!(app.world().get::<Enemy>(enemy_id).unwrap().hit_points, 4);
7879
}
7980

8081
#[test]
@@ -89,11 +90,11 @@ fn did_despawn_enemy() {
8990
app.add_event::<EnemyDied>();
9091

9192
// Add our two systems
92-
app.add_systems((hurt_enemies, despawn_dead_enemies).chain());
93+
app.add_systems(Update, (hurt_enemies, despawn_dead_enemies).chain());
9394

9495
// Setup test entities
9596
let enemy_id = app
96-
.world
97+
.world_mut()
9798
.spawn(Enemy {
9899
hit_points: 1,
99100
score_value: 1,
@@ -104,12 +105,12 @@ fn did_despawn_enemy() {
104105
app.update();
105106

106107
// Check enemy was despawned
107-
assert!(app.world.get::<Enemy>(enemy_id).is_none());
108+
assert!(app.world().get::<Enemy>(enemy_id).is_none());
108109

109110
// Get `EnemyDied` event reader
110-
let enemy_died_events = app.world.resource::<Events<EnemyDied>>();
111-
let mut enemy_died_reader = enemy_died_events.get_reader();
112-
let enemy_died = enemy_died_reader.iter(enemy_died_events).next().unwrap();
111+
let enemy_died_events = app.world().resource::<Events<EnemyDied>>();
112+
let mut enemy_died_cursor = enemy_died_events.get_cursor();
113+
let enemy_died = enemy_died_cursor.read(enemy_died_events).next().unwrap();
113114

114115
// Check the event has been sent
115116
assert_eq!(enemy_died.0, 1);
@@ -121,27 +122,35 @@ fn spawn_enemy_using_input_resource() {
121122
let mut app = App::new();
122123

123124
// Add our systems
124-
app.add_system(spawn_enemy);
125+
app.add_systems(Update, spawn_enemy);
125126

126127
// Setup test resource
127-
let mut input = Input::<KeyCode>::default();
128+
let mut input = ButtonInput::<KeyCode>::default();
128129
input.press(KeyCode::Space);
129130
app.insert_resource(input);
130131

131132
// Run systems
132133
app.update();
133134

134135
// Check resulting changes, one entity has been spawned with `Enemy` component
135-
assert_eq!(app.world.query::<&Enemy>().iter(&app.world).len(), 1);
136+
assert_eq!(
137+
app.world_mut().query::<&Enemy>().iter(&app.world()).len(),
138+
1
139+
);
136140

137141
// Clear the `just_pressed` status for all `KeyCode`s
138-
app.world.resource_mut::<Input<KeyCode>>().clear();
142+
app.world_mut()
143+
.resource_mut::<ButtonInput<KeyCode>>()
144+
.clear();
139145

140146
// Run systems
141147
app.update();
142148

143149
// Check resulting changes, no new entity has been spawned
144-
assert_eq!(app.world.query::<&Enemy>().iter(&app.world).len(), 1);
150+
assert_eq!(
151+
app.world_mut().query::<&Enemy>().iter(&app.world()).len(),
152+
1
153+
);
145154
}
146155

147156
#[test]
@@ -156,16 +165,16 @@ fn update_score_on_event() {
156165
app.add_event::<EnemyDied>();
157166

158167
// Add our systems
159-
app.add_system(update_score);
168+
app.add_systems(Update, update_score);
160169

161170
// Send an `EnemyDied` event
162-
app.world
171+
app.world_mut()
163172
.resource_mut::<Events<EnemyDied>>()
164173
.send(EnemyDied(3));
165174

166175
// Run systems
167176
app.update();
168177

169178
// Check resulting changes
170-
assert_eq!(app.world.resource::<Score>().0, 3);
179+
assert_eq!(app.world().resource::<Score>().0, 3);
171180
}

integration_tests/src/scenes/components.rs

+28-40
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#![cfg(test)]
22
//! Testing of serialization and deserialization of diverse scene components.
33
4-
use bevy::ecs::entity::EntityMap;
4+
use bevy::ecs::entity::EntityHashMap;
55
use bevy::prelude::*;
66
use bevy::reflect::erased_serde::__private::serde::de::DeserializeSeed;
77
use bevy::reflect::erased_serde::__private::serde::Serialize;
8+
use bevy::reflect::TypeRegistry;
89
use bevy::scene::serde::{SceneDeserializer, SceneSerializer};
910
use bevy::scene::ScenePlugin;
1011
use bincode::Options;
@@ -32,43 +33,43 @@ fn messagepack_roundtrip_equality() {
3233

3334
/// Convenience function for testing the roundtrip equality of different serialization methods.
3435
fn assert_round_trip_equality(
35-
serialize: fn(DynamicScene, &AppTypeRegistry) -> Vec<u8>,
36+
serialize: fn(DynamicScene, &TypeRegistry) -> Vec<u8>,
3637
deserialize: fn(SceneDeserializer, &[u8]) -> DynamicScene,
3738
) {
3839
let mut input_app = create_test_app();
3940
spawn_test_entities(&mut input_app);
4041

41-
let type_registry = input_app.world.resource::<AppTypeRegistry>();
42-
let scene = DynamicScene::from_world(&input_app.world, type_registry);
43-
let serialized = serialize(scene, type_registry);
42+
let type_registry = input_app.world().resource::<AppTypeRegistry>().read();
43+
let scene = DynamicScene::from_world(&input_app.world());
44+
let serialized = serialize(scene, &type_registry);
4445

4546
// We use a clean app to deserialize into, so nothing of the input app can interfere.
4647
let mut output_app = create_test_app();
4748
let scene = {
4849
let scene_deserializer = SceneDeserializer {
49-
type_registry: &output_app.world.resource::<AppTypeRegistry>().read(),
50+
type_registry: &output_app.world().resource::<AppTypeRegistry>().read(),
5051
};
5152
deserialize(scene_deserializer, &serialized)
5253
};
5354

54-
let mut entity_map = EntityMap::default();
55+
let mut entity_map = EntityHashMap::default();
5556
scene
56-
.write_to_world(&mut output_app.world, &mut entity_map)
57+
.write_to_world(&mut output_app.world_mut(), &mut entity_map)
5758
.unwrap_or_else(|error| panic!("Could not add deserialized scene to world: {error}"));
5859

5960
// TODO: Ideally we'd check whether the input and output world are exactly equal. But the world does not implement Eq.
6061
// so instead we check the serialized outputs against each other. However, this will miss anything that fails to serialize in the first place.
6162

62-
let type_registry = input_app.world.resource::<AppTypeRegistry>();
63-
let scene = DynamicScene::from_world(&input_app.world, type_registry);
64-
let serialized_again = serialize(scene, type_registry);
63+
let type_registry = input_app.world().resource::<AppTypeRegistry>().read();
64+
let scene = DynamicScene::from_world(&input_app.world());
65+
let serialized_again = serialize(scene, &type_registry);
6566

6667
assert_eq!(serialized, serialized_again);
6768
}
6869

69-
fn serialize_world_ron(scene: DynamicScene, type_registry: &AppTypeRegistry) -> Vec<u8> {
70+
fn serialize_world_ron(scene: DynamicScene, type_registry: &TypeRegistry) -> Vec<u8> {
7071
scene
71-
.serialize_ron(type_registry)
72+
.serialize(type_registry)
7273
.map(|output| output.as_bytes().to_vec())
7374
.unwrap_or_else(|error| panic!("Scene failed to serialize: {error}"))
7475
}
@@ -81,8 +82,8 @@ fn deserialize_world_ron(scene_deserializer: SceneDeserializer, input: &[u8]) ->
8182
.unwrap_or_else(|error| panic!("Scene failed to deserialize: {error}"))
8283
}
8384

84-
fn serialize_world_postcard(scene: DynamicScene, type_registry: &AppTypeRegistry) -> Vec<u8> {
85-
let scene_serializer = SceneSerializer::new(&scene, &type_registry.0);
85+
fn serialize_world_postcard(scene: DynamicScene, type_registry: &TypeRegistry) -> Vec<u8> {
86+
let scene_serializer = SceneSerializer::new(&scene, type_registry);
8687
postcard::to_allocvec(&scene_serializer)
8788
.unwrap_or_else(|error| panic!("Scene failed to serialize: {error}"))
8889
}
@@ -94,8 +95,8 @@ fn deserialize_world_postcard(scene_deserializer: SceneDeserializer, input: &[u8
9495
.unwrap_or_else(|error| panic!("Scene failed to deserialize: {error}"))
9596
}
9697

97-
fn serialize_world_bincode(scene: DynamicScene, type_registry: &AppTypeRegistry) -> Vec<u8> {
98-
let scene_serializer = SceneSerializer::new(&scene, &type_registry.0);
98+
fn serialize_world_bincode(scene: DynamicScene, type_registry: &TypeRegistry) -> Vec<u8> {
99+
let scene_serializer = SceneSerializer::new(&scene, type_registry);
99100
bincode::serialize(&scene_serializer)
100101
.unwrap_or_else(|error| panic!("Scene failed to serialize: {error}"))
101102
}
@@ -107,8 +108,8 @@ fn deserialize_world_bincode(scene_deserializer: SceneDeserializer, input: &[u8]
107108
.unwrap_or_else(|error| panic!("Scene failed to deserialize: {error}"))
108109
}
109110

110-
fn serialize_world_messagepack(scene: DynamicScene, type_registry: &AppTypeRegistry) -> Vec<u8> {
111-
let scene_serializer = SceneSerializer::new(&scene, &type_registry.0);
111+
fn serialize_world_messagepack(scene: DynamicScene, type_registry: &TypeRegistry) -> Vec<u8> {
112+
let scene_serializer = SceneSerializer::new(&scene, type_registry);
112113
let mut buf = Vec::new();
113114
let mut ser = rmp_serde::Serializer::new(&mut buf);
114115
scene_serializer
@@ -130,33 +131,20 @@ fn deserialize_world_messagepack(
130131

131132
fn create_test_app() -> App {
132133
let mut app = App::new();
133-
app.add_plugins(MinimalPlugins)
134-
.add_plugin(AssetPlugin::default())
135-
.add_plugin(ScenePlugin::default())
136-
.add_plugin(TransformPlugin::default())
137-
.register_type::<ReferenceComponent>()
138-
.register_type::<Option<Entity>>()
139-
.register_type::<VectorComponent>()
140-
.register_type::<TupleComponent>()
141-
// TODO: Without the `Vec` registrations, the serialization
142-
// works. But the de-serialization fails. This does not sound correct.
143-
// Either both should fail, or both should work.
144-
.register_type::<Vec<u32>>()
145-
.register_type::<Vec<String>>()
146-
// TODO: Without these tuple registrations, the serialization
147-
// works. But the de-serialization fails. This does not sound correct.
148-
// Either both should fail, or both should work.
149-
.register_type::<(i32, String, f32)>()
150-
.register_type::<(bool, bool, u32)>();
134+
app.add_plugins(MinimalPlugins).add_plugins((
135+
AssetPlugin::default(),
136+
ScenePlugin,
137+
TransformPlugin,
138+
));
151139

152140
app
153141
}
154142

155143
fn spawn_test_entities(app: &mut App) {
156-
let entity_1 = app.world.spawn(TransformBundle::default()).id();
157-
app.world.spawn(ReferenceComponent(Some(entity_1)));
144+
let entity_1 = app.world_mut().spawn(Transform::default()).id();
145+
app.world_mut().spawn(ReferenceComponent(Some(entity_1)));
158146

159-
app.world
147+
app.world_mut()
160148
.spawn(VectorComponent {
161149
integer_vector: vec![1, 2, 3, 4, 5, 123456789],
162150
// Testing different characters in strings

0 commit comments

Comments
 (0)