Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_scene/src/serde.rs
6598 views
1
//! `serde` serialization and deserialization implementation for Bevy scenes.
2
3
use crate::{DynamicEntity, DynamicScene};
4
use bevy_ecs::entity::Entity;
5
use bevy_platform::collections::HashSet;
6
use bevy_reflect::{
7
serde::{
8
ReflectDeserializer, TypeRegistrationDeserializer, TypedReflectDeserializer,
9
TypedReflectSerializer,
10
},
11
PartialReflect, ReflectFromReflect, TypeRegistry,
12
};
13
use core::fmt::Formatter;
14
use serde::{
15
de::{DeserializeSeed, Error, MapAccess, SeqAccess, Visitor},
16
ser::{SerializeMap, SerializeStruct},
17
Deserialize, Deserializer, Serialize, Serializer,
18
};
19
20
/// Name of the serialized scene struct type.
21
pub const SCENE_STRUCT: &str = "Scene";
22
/// Name of the serialized resources field in a scene struct.
23
pub const SCENE_RESOURCES: &str = "resources";
24
/// Name of the serialized entities field in a scene struct.
25
pub const SCENE_ENTITIES: &str = "entities";
26
27
/// Name of the serialized entity struct type.
28
pub const ENTITY_STRUCT: &str = "Entity";
29
/// Name of the serialized component field in an entity struct.
30
pub const ENTITY_FIELD_COMPONENTS: &str = "components";
31
32
/// Serializer for a [`DynamicScene`].
33
///
34
/// Helper object defining Bevy's serialize format for a [`DynamicScene`] and implementing
35
/// the [`Serialize`] trait for use with Serde.
36
///
37
/// # Example
38
///
39
/// ```
40
/// # use bevy_ecs::prelude::*;
41
/// # use bevy_scene::{DynamicScene, serde::SceneSerializer};
42
/// # let mut world = World::default();
43
/// # world.insert_resource(AppTypeRegistry::default());
44
/// // Get the type registry
45
/// let registry = world.resource::<AppTypeRegistry>();
46
/// let registry = registry.read();
47
///
48
/// // Get a DynamicScene to serialize, for example from the World itself
49
/// let scene = DynamicScene::from_world(&world);
50
///
51
/// // Create a serializer for that DynamicScene, using the associated TypeRegistry
52
/// let scene_serializer = SceneSerializer::new(&scene, &registry);
53
///
54
/// // Serialize through any serde-compatible Serializer
55
/// let ron_string = bevy_scene::ron::ser::to_string(&scene_serializer);
56
/// ```
57
pub struct SceneSerializer<'a> {
58
/// The scene to serialize.
59
pub scene: &'a DynamicScene,
60
/// The type registry containing the types present in the scene.
61
pub registry: &'a TypeRegistry,
62
}
63
64
impl<'a> SceneSerializer<'a> {
65
/// Create a new serializer from a [`DynamicScene`] and an associated [`TypeRegistry`].
66
///
67
/// The type registry must contain all types present in the scene. This is generally the case
68
/// if you obtain both the scene and the registry from the same [`World`].
69
///
70
/// [`World`]: bevy_ecs::world::World
71
pub fn new(scene: &'a DynamicScene, registry: &'a TypeRegistry) -> Self {
72
SceneSerializer { scene, registry }
73
}
74
}
75
76
impl<'a> Serialize for SceneSerializer<'a> {
77
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78
where
79
S: Serializer,
80
{
81
let mut state = serializer.serialize_struct(SCENE_STRUCT, 2)?;
82
state.serialize_field(
83
SCENE_RESOURCES,
84
&SceneMapSerializer {
85
entries: &self.scene.resources,
86
registry: self.registry,
87
},
88
)?;
89
state.serialize_field(
90
SCENE_ENTITIES,
91
&EntitiesSerializer {
92
entities: &self.scene.entities,
93
registry: self.registry,
94
},
95
)?;
96
state.end()
97
}
98
}
99
100
/// Handles serialization of multiple entities as a map of entity id to serialized entity.
101
pub struct EntitiesSerializer<'a> {
102
/// The entities to serialize.
103
pub entities: &'a [DynamicEntity],
104
/// Type registry in which the component types used by the entities are registered.
105
pub registry: &'a TypeRegistry,
106
}
107
108
impl<'a> Serialize for EntitiesSerializer<'a> {
109
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
110
where
111
S: Serializer,
112
{
113
let mut state = serializer.serialize_map(Some(self.entities.len()))?;
114
for entity in self.entities {
115
state.serialize_entry(
116
&entity.entity,
117
&EntitySerializer {
118
entity,
119
registry: self.registry,
120
},
121
)?;
122
}
123
state.end()
124
}
125
}
126
127
/// Handles entity serialization as a map of component type to component value.
128
pub struct EntitySerializer<'a> {
129
/// The entity to serialize.
130
pub entity: &'a DynamicEntity,
131
/// Type registry in which the component types used by the entity are registered.
132
pub registry: &'a TypeRegistry,
133
}
134
135
impl<'a> Serialize for EntitySerializer<'a> {
136
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
137
where
138
S: Serializer,
139
{
140
let mut state = serializer.serialize_struct(ENTITY_STRUCT, 1)?;
141
state.serialize_field(
142
ENTITY_FIELD_COMPONENTS,
143
&SceneMapSerializer {
144
entries: &self.entity.components,
145
registry: self.registry,
146
},
147
)?;
148
state.end()
149
}
150
}
151
152
/// Handles serializing a list of values with a unique type as a map of type to value.
153
///
154
/// Used to serialize scene resources in [`SceneSerializer`] and entity components in [`EntitySerializer`].
155
/// Note that having several entries of the same type in `entries` will lead to an error when using the RON format and
156
/// deserializing through [`SceneMapDeserializer`].
157
///
158
/// Note: The entries are sorted by type path before they're serialized.
159
pub struct SceneMapSerializer<'a> {
160
/// List of boxed values of unique type to serialize.
161
pub entries: &'a [Box<dyn PartialReflect>],
162
/// Type registry in which the types used in `entries` are registered.
163
pub registry: &'a TypeRegistry,
164
}
165
166
impl<'a> Serialize for SceneMapSerializer<'a> {
167
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
168
where
169
S: Serializer,
170
{
171
let mut state = serializer.serialize_map(Some(self.entries.len()))?;
172
let sorted_entries = {
173
let mut entries = self
174
.entries
175
.iter()
176
.map(|entry| {
177
(
178
entry.get_represented_type_info().unwrap().type_path(),
179
entry.as_partial_reflect(),
180
)
181
})
182
.collect::<Vec<_>>();
183
entries.sort_by_key(|(type_path, _)| *type_path);
184
entries
185
};
186
187
for (type_path, partial_reflect) in sorted_entries {
188
state.serialize_entry(
189
type_path,
190
&TypedReflectSerializer::new(partial_reflect, self.registry),
191
)?;
192
}
193
state.end()
194
}
195
}
196
197
#[derive(Deserialize)]
198
#[serde(field_identifier, rename_all = "lowercase")]
199
enum SceneField {
200
Resources,
201
Entities,
202
}
203
204
#[derive(Deserialize)]
205
#[serde(field_identifier, rename_all = "lowercase")]
206
enum EntityField {
207
Components,
208
}
209
210
/// Handles scene deserialization.
211
pub struct SceneDeserializer<'a> {
212
/// Type registry in which the components and resources types used in the scene to deserialize are registered.
213
pub type_registry: &'a TypeRegistry,
214
}
215
216
impl<'a, 'de> DeserializeSeed<'de> for SceneDeserializer<'a> {
217
type Value = DynamicScene;
218
219
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
220
where
221
D: Deserializer<'de>,
222
{
223
deserializer.deserialize_struct(
224
SCENE_STRUCT,
225
&[SCENE_RESOURCES, SCENE_ENTITIES],
226
SceneVisitor {
227
type_registry: self.type_registry,
228
},
229
)
230
}
231
}
232
233
struct SceneVisitor<'a> {
234
pub type_registry: &'a TypeRegistry,
235
}
236
237
impl<'a, 'de> Visitor<'de> for SceneVisitor<'a> {
238
type Value = DynamicScene;
239
240
fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
241
formatter.write_str("scene struct")
242
}
243
244
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
245
where
246
A: SeqAccess<'de>,
247
{
248
let resources = seq
249
.next_element_seed(SceneMapDeserializer {
250
registry: self.type_registry,
251
})?
252
.ok_or_else(|| Error::missing_field(SCENE_RESOURCES))?;
253
254
let entities = seq
255
.next_element_seed(SceneEntitiesDeserializer {
256
type_registry: self.type_registry,
257
})?
258
.ok_or_else(|| Error::missing_field(SCENE_ENTITIES))?;
259
260
Ok(DynamicScene {
261
resources,
262
entities,
263
})
264
}
265
266
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
267
where
268
A: MapAccess<'de>,
269
{
270
let mut resources = None;
271
let mut entities = None;
272
while let Some(key) = map.next_key()? {
273
match key {
274
SceneField::Resources => {
275
if resources.is_some() {
276
return Err(Error::duplicate_field(SCENE_RESOURCES));
277
}
278
resources = Some(map.next_value_seed(SceneMapDeserializer {
279
registry: self.type_registry,
280
})?);
281
}
282
SceneField::Entities => {
283
if entities.is_some() {
284
return Err(Error::duplicate_field(SCENE_ENTITIES));
285
}
286
entities = Some(map.next_value_seed(SceneEntitiesDeserializer {
287
type_registry: self.type_registry,
288
})?);
289
}
290
}
291
}
292
293
let resources = resources.ok_or_else(|| Error::missing_field(SCENE_RESOURCES))?;
294
let entities = entities.ok_or_else(|| Error::missing_field(SCENE_ENTITIES))?;
295
296
Ok(DynamicScene {
297
resources,
298
entities,
299
})
300
}
301
}
302
303
/// Handles deserialization for a collection of entities.
304
pub struct SceneEntitiesDeserializer<'a> {
305
/// Type registry in which the component types used by the entities to deserialize are registered.
306
pub type_registry: &'a TypeRegistry,
307
}
308
309
impl<'a, 'de> DeserializeSeed<'de> for SceneEntitiesDeserializer<'a> {
310
type Value = Vec<DynamicEntity>;
311
312
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
313
where
314
D: Deserializer<'de>,
315
{
316
deserializer.deserialize_map(SceneEntitiesVisitor {
317
type_registry: self.type_registry,
318
})
319
}
320
}
321
322
struct SceneEntitiesVisitor<'a> {
323
pub type_registry: &'a TypeRegistry,
324
}
325
326
impl<'a, 'de> Visitor<'de> for SceneEntitiesVisitor<'a> {
327
type Value = Vec<DynamicEntity>;
328
329
fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
330
formatter.write_str("map of entities")
331
}
332
333
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
334
where
335
A: MapAccess<'de>,
336
{
337
let mut entities = Vec::new();
338
while let Some(entity) = map.next_key::<Entity>()? {
339
let entity = map.next_value_seed(SceneEntityDeserializer {
340
entity,
341
type_registry: self.type_registry,
342
})?;
343
entities.push(entity);
344
}
345
346
Ok(entities)
347
}
348
}
349
350
/// Handle deserialization of an entity and its components.
351
pub struct SceneEntityDeserializer<'a> {
352
/// Id of the deserialized entity.
353
pub entity: Entity,
354
/// Type registry in which the component types used by the entity to deserialize are registered.
355
pub type_registry: &'a TypeRegistry,
356
}
357
358
impl<'a, 'de> DeserializeSeed<'de> for SceneEntityDeserializer<'a> {
359
type Value = DynamicEntity;
360
361
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
362
where
363
D: Deserializer<'de>,
364
{
365
deserializer.deserialize_struct(
366
ENTITY_STRUCT,
367
&[ENTITY_FIELD_COMPONENTS],
368
SceneEntityVisitor {
369
entity: self.entity,
370
registry: self.type_registry,
371
},
372
)
373
}
374
}
375
376
struct SceneEntityVisitor<'a> {
377
pub entity: Entity,
378
pub registry: &'a TypeRegistry,
379
}
380
381
impl<'a, 'de> Visitor<'de> for SceneEntityVisitor<'a> {
382
type Value = DynamicEntity;
383
384
fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
385
formatter.write_str("entities")
386
}
387
388
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
389
where
390
A: SeqAccess<'de>,
391
{
392
let components = seq
393
.next_element_seed(SceneMapDeserializer {
394
registry: self.registry,
395
})?
396
.ok_or_else(|| Error::missing_field(ENTITY_FIELD_COMPONENTS))?;
397
398
Ok(DynamicEntity {
399
entity: self.entity,
400
components,
401
})
402
}
403
404
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
405
where
406
A: MapAccess<'de>,
407
{
408
let mut components = None;
409
while let Some(key) = map.next_key()? {
410
match key {
411
EntityField::Components => {
412
if components.is_some() {
413
return Err(Error::duplicate_field(ENTITY_FIELD_COMPONENTS));
414
}
415
416
components = Some(map.next_value_seed(SceneMapDeserializer {
417
registry: self.registry,
418
})?);
419
}
420
}
421
}
422
423
let components = components
424
.take()
425
.ok_or_else(|| Error::missing_field(ENTITY_FIELD_COMPONENTS))?;
426
Ok(DynamicEntity {
427
entity: self.entity,
428
components,
429
})
430
}
431
}
432
433
/// Handles deserialization of a sequence of values with unique types.
434
pub struct SceneMapDeserializer<'a> {
435
/// Type registry in which the types of the values to deserialize are registered.
436
pub registry: &'a TypeRegistry,
437
}
438
439
impl<'a, 'de> DeserializeSeed<'de> for SceneMapDeserializer<'a> {
440
type Value = Vec<Box<dyn PartialReflect>>;
441
442
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
443
where
444
D: Deserializer<'de>,
445
{
446
deserializer.deserialize_map(SceneMapVisitor {
447
registry: self.registry,
448
})
449
}
450
}
451
452
struct SceneMapVisitor<'a> {
453
pub registry: &'a TypeRegistry,
454
}
455
456
impl<'a, 'de> Visitor<'de> for SceneMapVisitor<'a> {
457
type Value = Vec<Box<dyn PartialReflect>>;
458
459
fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
460
formatter.write_str("map of reflect types")
461
}
462
463
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
464
where
465
A: SeqAccess<'de>,
466
{
467
let mut dynamic_properties = Vec::new();
468
while let Some(entity) = seq.next_element_seed(ReflectDeserializer::new(self.registry))? {
469
dynamic_properties.push(entity);
470
}
471
472
Ok(dynamic_properties)
473
}
474
475
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
476
where
477
A: MapAccess<'de>,
478
{
479
let mut added = <HashSet<_>>::default();
480
let mut entries = Vec::new();
481
while let Some(registration) =
482
map.next_key_seed(TypeRegistrationDeserializer::new(self.registry))?
483
{
484
if !added.insert(registration.type_id()) {
485
return Err(Error::custom(format_args!(
486
"duplicate reflect type: `{}`",
487
registration.type_info().type_path(),
488
)));
489
}
490
491
let value =
492
map.next_value_seed(TypedReflectDeserializer::new(registration, self.registry))?;
493
494
// Attempt to convert using FromReflect.
495
let value = self
496
.registry
497
.get(registration.type_id())
498
.and_then(|tr| tr.data::<ReflectFromReflect>())
499
.and_then(|fr| fr.from_reflect(value.as_partial_reflect()))
500
.map(PartialReflect::into_partial_reflect)
501
.unwrap_or(value);
502
503
entries.push(value);
504
}
505
506
Ok(entries)
507
}
508
}
509
510
#[cfg(test)]
511
mod tests {
512
use crate::{
513
ron,
514
serde::{SceneDeserializer, SceneSerializer},
515
DynamicScene, DynamicSceneBuilder,
516
};
517
use bevy_ecs::{
518
entity::{Entity, EntityHashMap},
519
prelude::{Component, ReflectComponent, ReflectResource, Resource, World},
520
query::{With, Without},
521
reflect::AppTypeRegistry,
522
world::FromWorld,
523
};
524
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
525
use serde::{de::DeserializeSeed, Deserialize, Serialize};
526
use std::io::BufReader;
527
528
#[derive(Component, Reflect, Default)]
529
#[reflect(Component)]
530
struct Foo(i32);
531
#[derive(Component, Reflect, Default)]
532
#[reflect(Component)]
533
struct Bar(i32);
534
#[derive(Component, Reflect, Default)]
535
#[reflect(Component)]
536
struct Baz(i32);
537
538
// De/serialize as hex.
539
mod qux {
540
use serde::{de::Error, Deserialize, Deserializer, Serializer};
541
542
pub fn serialize<S>(value: &u32, serializer: S) -> Result<S::Ok, S::Error>
543
where
544
S: Serializer,
545
{
546
serializer.serialize_str(&format!("{value:X}"))
547
}
548
549
pub fn deserialize<'de, D>(deserializer: D) -> Result<u32, D::Error>
550
where
551
D: Deserializer<'de>,
552
{
553
u32::from_str_radix(<&str as Deserialize>::deserialize(deserializer)?, 16)
554
.map_err(Error::custom)
555
}
556
}
557
558
#[derive(Component, Copy, Clone, Reflect, Debug, PartialEq, Serialize, Deserialize)]
559
#[reflect(Component, Serialize, Deserialize)]
560
struct Qux(#[serde(with = "qux")] u32);
561
562
#[derive(Component, Reflect, Default)]
563
#[reflect(Component)]
564
struct MyComponent {
565
foo: [usize; 3],
566
bar: (f32, f32),
567
baz: MyEnum,
568
}
569
570
#[derive(Reflect, Default)]
571
enum MyEnum {
572
#[default]
573
Unit,
574
Tuple(String),
575
Struct {
576
value: u32,
577
},
578
}
579
580
#[derive(Resource, Reflect, Default)]
581
#[reflect(Resource)]
582
struct MyResource {
583
foo: i32,
584
}
585
586
#[derive(Clone, Component, Reflect, PartialEq)]
587
#[reflect(Component, PartialEq)]
588
struct MyEntityRef(#[entities] Entity);
589
590
impl FromWorld for MyEntityRef {
591
fn from_world(_world: &mut World) -> Self {
592
Self(Entity::PLACEHOLDER)
593
}
594
}
595
596
fn create_world() -> World {
597
let mut world = World::new();
598
let registry = AppTypeRegistry::default();
599
{
600
let mut registry = registry.write();
601
registry.register::<Foo>();
602
registry.register::<Bar>();
603
registry.register::<Baz>();
604
registry.register::<Qux>();
605
registry.register::<MyComponent>();
606
registry.register::<MyEnum>();
607
registry.register::<String>();
608
registry.register_type_data::<String, ReflectSerialize>();
609
registry.register::<[usize; 3]>();
610
registry.register::<(f32, f32)>();
611
registry.register::<MyEntityRef>();
612
registry.register::<Entity>();
613
registry.register::<MyResource>();
614
}
615
world.insert_resource(registry);
616
world
617
}
618
619
#[test]
620
fn should_serialize() {
621
let mut world = create_world();
622
623
let a = world.spawn(Foo(123)).id();
624
let b = world.spawn((Foo(123), Bar(345))).id();
625
let c = world.spawn((Foo(123), Bar(345), Baz(789))).id();
626
627
world.insert_resource(MyResource { foo: 123 });
628
629
let scene = DynamicSceneBuilder::from_world(&world)
630
.extract_entities([a, b, c].into_iter())
631
.extract_resources()
632
.build();
633
634
let expected = r#"(
635
resources: {
636
"bevy_scene::serde::tests::MyResource": (
637
foo: 123,
638
),
639
},
640
entities: {
641
4294967293: (
642
components: {
643
"bevy_scene::serde::tests::Bar": (345),
644
"bevy_scene::serde::tests::Baz": (789),
645
"bevy_scene::serde::tests::Foo": (123),
646
},
647
),
648
4294967294: (
649
components: {
650
"bevy_scene::serde::tests::Bar": (345),
651
"bevy_scene::serde::tests::Foo": (123),
652
},
653
),
654
4294967295: (
655
components: {
656
"bevy_scene::serde::tests::Foo": (123),
657
},
658
),
659
},
660
)"#;
661
let output = scene
662
.serialize(&world.resource::<AppTypeRegistry>().read())
663
.unwrap();
664
assert_eq!(expected, output);
665
}
666
667
#[test]
668
fn should_deserialize() {
669
let world = create_world();
670
671
let input = r#"(
672
resources: {
673
"bevy_scene::serde::tests::MyResource": (
674
foo: 123,
675
),
676
},
677
entities: {
678
8589934591: (
679
components: {
680
"bevy_scene::serde::tests::Foo": (123),
681
},
682
),
683
8589934590: (
684
components: {
685
"bevy_scene::serde::tests::Foo": (123),
686
"bevy_scene::serde::tests::Bar": (345),
687
},
688
),
689
8589934589: (
690
components: {
691
"bevy_scene::serde::tests::Foo": (123),
692
"bevy_scene::serde::tests::Bar": (345),
693
"bevy_scene::serde::tests::Baz": (789),
694
},
695
),
696
},
697
)"#;
698
let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
699
let scene_deserializer = SceneDeserializer {
700
type_registry: &world.resource::<AppTypeRegistry>().read(),
701
};
702
let scene = scene_deserializer.deserialize(&mut deserializer).unwrap();
703
704
assert_eq!(
705
1,
706
scene.resources.len(),
707
"expected `resources` to contain 1 resource"
708
);
709
assert_eq!(
710
3,
711
scene.entities.len(),
712
"expected `entities` to contain 3 entities"
713
);
714
715
let mut map = EntityHashMap::default();
716
let mut dst_world = create_world();
717
scene.write_to_world(&mut dst_world, &mut map).unwrap();
718
719
let my_resource = dst_world.get_resource::<MyResource>();
720
assert!(my_resource.is_some());
721
let my_resource = my_resource.unwrap();
722
assert_eq!(my_resource.foo, 123);
723
724
assert_eq!(3, dst_world.query::<&Foo>().iter(&dst_world).count());
725
assert_eq!(2, dst_world.query::<&Bar>().iter(&dst_world).count());
726
assert_eq!(1, dst_world.query::<&Baz>().iter(&dst_world).count());
727
}
728
729
fn roundtrip_ron(world: &World) -> (DynamicScene, DynamicScene) {
730
let scene = DynamicScene::from_world(world);
731
let registry = world.resource::<AppTypeRegistry>().read();
732
let serialized = scene.serialize(&registry).unwrap();
733
let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap();
734
let scene_deserializer = SceneDeserializer {
735
type_registry: &registry,
736
};
737
let deserialized_scene = scene_deserializer.deserialize(&mut deserializer).unwrap();
738
(scene, deserialized_scene)
739
}
740
741
#[test]
742
fn should_roundtrip_with_later_generations_and_obsolete_references() {
743
let mut world = create_world();
744
745
world.spawn_empty().despawn();
746
747
let a = world.spawn_empty().id();
748
let foo = world.spawn(MyEntityRef(a)).insert(Foo(123)).id();
749
world.despawn(a);
750
world.spawn(MyEntityRef(foo)).insert(Bar(123));
751
752
let (scene, deserialized_scene) = roundtrip_ron(&world);
753
754
let mut map = EntityHashMap::default();
755
let mut dst_world = create_world();
756
deserialized_scene
757
.write_to_world(&mut dst_world, &mut map)
758
.unwrap();
759
760
assert_eq!(2, deserialized_scene.entities.len());
761
assert_scene_eq(&scene, &deserialized_scene);
762
763
let bar_to_foo = dst_world
764
.query_filtered::<&MyEntityRef, Without<Foo>>()
765
.single(&dst_world)
766
.cloned()
767
.unwrap();
768
let foo = dst_world
769
.query_filtered::<Entity, With<Foo>>()
770
.single(&dst_world)
771
.unwrap();
772
773
assert_eq!(foo, bar_to_foo.0);
774
assert!(dst_world
775
.query_filtered::<&MyEntityRef, With<Foo>>()
776
.iter(&dst_world)
777
.all(|r| world.get_entity(r.0).is_err()));
778
}
779
780
#[test]
781
fn should_roundtrip_with_custom_serialization() {
782
let mut world = create_world();
783
let qux = Qux(42);
784
world.spawn(qux);
785
786
let (scene, deserialized_scene) = roundtrip_ron(&world);
787
788
assert_eq!(1, deserialized_scene.entities.len());
789
assert_scene_eq(&scene, &deserialized_scene);
790
791
let mut world = create_world();
792
deserialized_scene
793
.write_to_world(&mut world, &mut EntityHashMap::default())
794
.unwrap();
795
assert_eq!(&qux, world.query::<&Qux>().single(&world).unwrap());
796
}
797
798
#[test]
799
fn should_roundtrip_postcard() {
800
let mut world = create_world();
801
802
world.spawn(MyComponent {
803
foo: [1, 2, 3],
804
bar: (1.3, 3.7),
805
baz: MyEnum::Tuple("Hello World!".to_string()),
806
});
807
808
let registry = world.resource::<AppTypeRegistry>();
809
let registry = &registry.read();
810
811
let scene = DynamicScene::from_world(&world);
812
813
let scene_serializer = SceneSerializer::new(&scene, registry);
814
let serialized_scene = postcard::to_allocvec(&scene_serializer).unwrap();
815
816
assert_eq!(
817
vec![
818
0, 1, 255, 255, 255, 255, 15, 1, 37, 98, 101, 118, 121, 95, 115, 99, 101, 110, 101,
819
58, 58, 115, 101, 114, 100, 101, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77, 121,
820
67, 111, 109, 112, 111, 110, 101, 110, 116, 1, 2, 3, 102, 102, 166, 63, 205, 204,
821
108, 64, 1, 12, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33
822
],
823
serialized_scene
824
);
825
826
let scene_deserializer = SceneDeserializer {
827
type_registry: registry,
828
};
829
let deserialized_scene = scene_deserializer
830
.deserialize(&mut postcard::Deserializer::from_bytes(&serialized_scene))
831
.unwrap();
832
833
assert_eq!(1, deserialized_scene.entities.len());
834
assert_scene_eq(&scene, &deserialized_scene);
835
}
836
837
#[test]
838
fn should_roundtrip_messagepack() {
839
let mut world = create_world();
840
841
world.spawn(MyComponent {
842
foo: [1, 2, 3],
843
bar: (1.3, 3.7),
844
baz: MyEnum::Tuple("Hello World!".to_string()),
845
});
846
847
let registry = world.resource::<AppTypeRegistry>();
848
let registry = &registry.read();
849
850
let scene = DynamicScene::from_world(&world);
851
852
let scene_serializer = SceneSerializer::new(&scene, registry);
853
let mut buf = Vec::new();
854
let mut ser = rmp_serde::Serializer::new(&mut buf);
855
scene_serializer.serialize(&mut ser).unwrap();
856
857
assert_eq!(
858
vec![
859
146, 128, 129, 206, 255, 255, 255, 255, 145, 129, 217, 37, 98, 101, 118, 121, 95,
860
115, 99, 101, 110, 101, 58, 58, 115, 101, 114, 100, 101, 58, 58, 116, 101, 115,
861
116, 115, 58, 58, 77, 121, 67, 111, 109, 112, 111, 110, 101, 110, 116, 147, 147, 1,
862
2, 3, 146, 202, 63, 166, 102, 102, 202, 64, 108, 204, 205, 129, 165, 84, 117, 112,
863
108, 101, 172, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33
864
],
865
buf
866
);
867
868
let scene_deserializer = SceneDeserializer {
869
type_registry: registry,
870
};
871
let mut reader = BufReader::new(buf.as_slice());
872
873
let deserialized_scene = scene_deserializer
874
.deserialize(&mut rmp_serde::Deserializer::new(&mut reader))
875
.unwrap();
876
877
assert_eq!(1, deserialized_scene.entities.len());
878
assert_scene_eq(&scene, &deserialized_scene);
879
}
880
881
#[test]
882
fn should_roundtrip_bincode() {
883
let mut world = create_world();
884
885
world.spawn(MyComponent {
886
foo: [1, 2, 3],
887
bar: (1.3, 3.7),
888
baz: MyEnum::Tuple("Hello World!".to_string()),
889
});
890
891
let registry = world.resource::<AppTypeRegistry>();
892
let registry = &registry.read();
893
894
let scene = DynamicScene::from_world(&world);
895
896
let config = bincode::config::standard().with_fixed_int_encoding();
897
let scene_serializer = SceneSerializer::new(&scene, registry);
898
let serialized_scene = bincode::serde::encode_to_vec(&scene_serializer, config).unwrap();
899
900
assert_eq!(
901
vec![
902
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1,
903
0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 98, 101, 118, 121, 95, 115, 99, 101,
904
110, 101, 58, 58, 115, 101, 114, 100, 101, 58, 58, 116, 101, 115, 116, 115, 58, 58,
905
77, 121, 67, 111, 109, 112, 111, 110, 101, 110, 116, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0,
906
0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 102, 102, 166, 63, 205, 204, 108, 64, 1,
907
0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108,
908
100, 33
909
],
910
serialized_scene
911
);
912
913
let scene_deserializer = SceneDeserializer {
914
type_registry: registry,
915
};
916
917
let (deserialized_scene, _read_bytes) =
918
bincode::serde::seed_decode_from_slice(scene_deserializer, &serialized_scene, config)
919
.unwrap();
920
921
assert_eq!(1, deserialized_scene.entities.len());
922
assert_scene_eq(&scene, &deserialized_scene);
923
}
924
925
/// A crude equality checker for [`DynamicScene`], used solely for testing purposes.
926
fn assert_scene_eq(expected: &DynamicScene, received: &DynamicScene) {
927
assert_eq!(
928
expected.entities.len(),
929
received.entities.len(),
930
"entity count did not match",
931
);
932
933
for expected in &expected.entities {
934
let received = received
935
.entities
936
.iter()
937
.find(|dynamic_entity| dynamic_entity.entity == expected.entity)
938
.unwrap_or_else(|| panic!("missing entity (expected: `{}`)", expected.entity));
939
940
assert_eq!(expected.entity, received.entity, "entities did not match");
941
942
for expected in &expected.components {
943
let received = received
944
.components
945
.iter()
946
.find(|component| {
947
component.get_represented_type_info().unwrap().type_path()
948
== expected.get_represented_type_info().unwrap().type_path()
949
})
950
.unwrap_or_else(|| {
951
panic!(
952
"missing component (expected: `{}`)",
953
expected.get_represented_type_info().unwrap().type_path()
954
)
955
});
956
957
assert!(
958
expected
959
.reflect_partial_eq(received.as_ref())
960
.unwrap_or_default(),
961
"components did not match: (expected: `{expected:?}`, received: `{received:?}`)",
962
);
963
}
964
}
965
}
966
967
/// These tests just verify that the [`assert_scene_eq`] function is working properly for our tests.
968
mod assert_scene_eq_tests {
969
use super::*;
970
971
#[test]
972
#[should_panic(expected = "entity count did not match")]
973
fn should_panic_when_entity_count_not_eq() {
974
let mut world = create_world();
975
let scene_a = DynamicScene::from_world(&world);
976
977
world.spawn(MyComponent {
978
foo: [1, 2, 3],
979
bar: (1.3, 3.7),
980
baz: MyEnum::Unit,
981
});
982
983
let scene_b = DynamicScene::from_world(&world);
984
985
assert_scene_eq(&scene_a, &scene_b);
986
}
987
988
#[test]
989
#[should_panic(expected = "components did not match")]
990
fn should_panic_when_components_not_eq() {
991
let mut world = create_world();
992
993
let entity = world
994
.spawn(MyComponent {
995
foo: [1, 2, 3],
996
bar: (1.3, 3.7),
997
baz: MyEnum::Unit,
998
})
999
.id();
1000
1001
let scene_a = DynamicScene::from_world(&world);
1002
1003
world.entity_mut(entity).insert(MyComponent {
1004
foo: [3, 2, 1],
1005
bar: (1.3, 3.7),
1006
baz: MyEnum::Unit,
1007
});
1008
1009
let scene_b = DynamicScene::from_world(&world);
1010
1011
assert_scene_eq(&scene_a, &scene_b);
1012
}
1013
1014
#[test]
1015
#[should_panic(expected = "missing component")]
1016
fn should_panic_when_missing_component() {
1017
let mut world = create_world();
1018
1019
let entity = world
1020
.spawn(MyComponent {
1021
foo: [1, 2, 3],
1022
bar: (1.3, 3.7),
1023
baz: MyEnum::Unit,
1024
})
1025
.id();
1026
1027
let scene_a = DynamicScene::from_world(&world);
1028
1029
world.entity_mut(entity).remove::<MyComponent>();
1030
1031
let scene_b = DynamicScene::from_world(&world);
1032
1033
assert_scene_eq(&scene_a, &scene_b);
1034
}
1035
}
1036
}
1037
1038