Skip to content

Commit 291ddaa

Browse files
committed
Rename replicate_into_scene into replicate_into
And move it to `scene` module since it's not directly related to server and isn't used inside it.
1 parent 3793d01 commit 291ddaa

File tree

5 files changed

+107
-103
lines changed

5 files changed

+107
-103
lines changed

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
- Use `EntityHashMap` instead of `HashMap` with entities as keys.
13+
- Rename `replicate_into_scene` into `replicate_into` and move it to `scene` module.
1314

1415
## [0.17.0] - 2023-11-13
1516

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ struct Player;
200200
```
201201
202202
This pairs nicely with server state serialization and keeps saves clean.
203-
You can use [`replicate_into_scene`](server::replicate_into_scene) to
203+
You can use [`replicate_into`](scene::replicate_into) to
204204
fill `DynamicScene` with replicated entities and their components.
205205
206206
The mentioned [`Ignored<T>`] component is an exception.
@@ -388,6 +388,7 @@ pub mod client;
388388
pub mod network_event;
389389
pub mod parent_sync;
390390
pub mod replicon_core;
391+
pub mod scene;
391392
pub mod server;
392393

393394
pub mod prelude {

src/scene.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use bevy::{ecs::archetype::ArchetypeId, prelude::*, scene::DynamicEntity};
2+
3+
use crate::replicon_core::replication_rules::ReplicationRules;
4+
5+
/**
6+
Fills scene with all replicated entities and their components.
7+
8+
Entities won't have the [`Replication`](crate::replicon_core::replication_rules::Replication) component.
9+
So on deserialization you need to insert it back if you want entities to continue to replicate.
10+
11+
# Panics
12+
13+
Panics if any replicated component is not registered using `register_type()`
14+
or `#[reflect(Component)]` is missing.
15+
16+
# Examples
17+
18+
```
19+
use bevy::{prelude::*, scene::serde::SceneDeserializer};
20+
use bevy_replicon::{prelude::*, scene};
21+
use serde::de::DeserializeSeed;
22+
# let mut world = World::new();
23+
# world.init_resource::<AppTypeRegistry>();
24+
# world.init_resource::<ReplicationRules>();
25+
26+
// Serialization
27+
let registry = world.resource::<AppTypeRegistry>();
28+
let mut scene = DynamicScene::default();
29+
scene::replicate_into(&mut scene, &world);
30+
let scene = scene
31+
.serialize_ron(&registry)
32+
.expect("scene should be serialized");
33+
34+
// Deserialization
35+
let scene_deserializer = SceneDeserializer {
36+
type_registry: &registry.read(),
37+
};
38+
let mut deserializer =
39+
ron::Deserializer::from_str(&scene).expect("scene should be serialized as valid ron");
40+
let mut scene = scene_deserializer
41+
.deserialize(&mut deserializer)
42+
.expect("ron should be convertible to scene");
43+
44+
// All saved entities should have `Replication` component.
45+
for entity in &mut scene.entities {
46+
entity.components.push(Replication.clone_value());
47+
}
48+
```
49+
*/
50+
pub fn replicate_into(scene: &mut DynamicScene, world: &World) {
51+
let registry = world.resource::<AppTypeRegistry>();
52+
let replication_rules = world.resource::<ReplicationRules>();
53+
54+
let registry = registry.read();
55+
for archetype in world
56+
.archetypes()
57+
.iter()
58+
.filter(|archetype| archetype.id() != ArchetypeId::EMPTY)
59+
.filter(|archetype| archetype.id() != ArchetypeId::INVALID)
60+
.filter(|archetype| archetype.contains(replication_rules.get_marker_id()))
61+
{
62+
let entities_offset = scene.entities.len();
63+
for archetype_entity in archetype.entities() {
64+
scene.entities.push(DynamicEntity {
65+
entity: archetype_entity.entity(),
66+
components: Vec::new(),
67+
});
68+
}
69+
70+
for component_id in archetype.components() {
71+
let Some((_, replication_info)) = replication_rules.get(component_id) else {
72+
continue;
73+
};
74+
if archetype.contains(replication_info.ignored_id) {
75+
continue;
76+
}
77+
78+
// SAFETY: `component_info` obtained from the world.
79+
let component_info = unsafe { world.components().get_info_unchecked(component_id) };
80+
let type_name = component_info.name();
81+
let type_id = component_info
82+
.type_id()
83+
.unwrap_or_else(|| panic!("{type_name} should have registered TypeId"));
84+
let registration = registry
85+
.get(type_id)
86+
.unwrap_or_else(|| panic!("{type_name} should be registered"));
87+
let reflect_component = registration
88+
.data::<ReflectComponent>()
89+
.unwrap_or_else(|| panic!("{type_name} should have reflect(Component)"));
90+
91+
for (index, archetype_entity) in archetype.entities().iter().enumerate() {
92+
let component = reflect_component
93+
.reflect(world.entity(archetype_entity.entity()))
94+
.unwrap_or_else(|| panic!("entity should have {type_name}"));
95+
96+
scene.entities[entities_offset + index]
97+
.components
98+
.push(component.clone_value());
99+
}
100+
}
101+
}
102+
}

src/server.rs

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use bevy::{
1111
system::SystemChangeTick,
1212
},
1313
prelude::*,
14-
scene::DynamicEntity,
1514
time::common_conditions::on_timer,
1615
utils::HashMap,
1716
};
@@ -475,105 +474,6 @@ impl AckedTicks {
475474
#[derive(Clone, Copy, Debug, Default, Deref, DerefMut, Resource)]
476475
pub(super) struct MinRepliconTick(RepliconTick);
477476

478-
/**
479-
Fills scene with all replicated entities and their components.
480-
481-
Entities won't have the [`Replication`](crate::replicon_core::replication_rules::Replication) component.
482-
So on deserialization you need to insert it back if you want entities to continue to replicate.
483-
484-
# Panics
485-
486-
Panics if any replicated component is not registered using `register_type()`
487-
or `#[reflect(Component)]` is missing.
488-
489-
# Examples
490-
491-
```
492-
use bevy::{prelude::*, scene::serde::SceneDeserializer};
493-
use bevy_replicon::{prelude::*, server};
494-
use serde::de::DeserializeSeed;
495-
# let mut world = World::new();
496-
# world.init_resource::<AppTypeRegistry>();
497-
# world.init_resource::<ReplicationRules>();
498-
499-
// Serialization
500-
let registry = world.resource::<AppTypeRegistry>();
501-
let mut scene = DynamicScene::default();
502-
server::replicate_into_scene(&mut scene, &world);
503-
let scene = scene
504-
.serialize_ron(&registry)
505-
.expect("scene should be serialized");
506-
507-
// Deserialization
508-
let scene_deserializer = SceneDeserializer {
509-
type_registry: &registry.read(),
510-
};
511-
let mut deserializer =
512-
ron::Deserializer::from_str(&scene).expect("scene should be serialized as valid ron");
513-
let mut scene = scene_deserializer
514-
.deserialize(&mut deserializer)
515-
.expect("ron should be convertible to scene");
516-
517-
// All saved entities should have `Replication` component.
518-
for entity in &mut scene.entities {
519-
entity.components.push(Replication.clone_value());
520-
}
521-
```
522-
*/
523-
pub fn replicate_into_scene(scene: &mut DynamicScene, world: &World) {
524-
let registry = world.resource::<AppTypeRegistry>();
525-
let replication_rules = world.resource::<ReplicationRules>();
526-
527-
let registry = registry.read();
528-
for archetype in world
529-
.archetypes()
530-
.iter()
531-
.filter(|archetype| archetype.id() != ArchetypeId::EMPTY)
532-
.filter(|archetype| archetype.id() != ArchetypeId::INVALID)
533-
.filter(|archetype| archetype.contains(replication_rules.get_marker_id()))
534-
{
535-
let entities_offset = scene.entities.len();
536-
for archetype_entity in archetype.entities() {
537-
scene.entities.push(DynamicEntity {
538-
entity: archetype_entity.entity(),
539-
components: Vec::new(),
540-
});
541-
}
542-
543-
for component_id in archetype.components() {
544-
let Some((_, replication_info)) = replication_rules.get(component_id) else {
545-
continue;
546-
};
547-
if archetype.contains(replication_info.ignored_id) {
548-
continue;
549-
}
550-
551-
// SAFETY: `component_info` obtained from the world.
552-
let component_info = unsafe { world.components().get_info_unchecked(component_id) };
553-
let type_name = component_info.name();
554-
let type_id = component_info
555-
.type_id()
556-
.unwrap_or_else(|| panic!("{type_name} should have registered TypeId"));
557-
let registration = registry
558-
.get(type_id)
559-
.unwrap_or_else(|| panic!("{type_name} should be registered"));
560-
let reflect_component = registration
561-
.data::<ReflectComponent>()
562-
.unwrap_or_else(|| panic!("{type_name} should have reflect(Component)"));
563-
564-
for (index, archetype_entity) in archetype.entities().iter().enumerate() {
565-
let component = reflect_component
566-
.reflect(world.entity(archetype_entity.entity()))
567-
.unwrap_or_else(|| panic!("entity should have {type_name}"));
568-
569-
scene.entities[entities_offset + index]
570-
.components
571-
.push(component.clone_value());
572-
}
573-
}
574-
}
575-
}
576-
577477
/**
578478
A resource that exists on the server for mapping server entities to
579479
entities that clients have already spawned. The mappings are sent to clients as part of replication

tests/replication.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
mod common;
22

33
use bevy::prelude::*;
4-
use bevy_replicon::{prelude::*, server};
4+
use bevy_replicon::{prelude::*, scene};
55

66
use bevy_renet::renet::{transport::NetcodeClientTransport, ClientId};
77
use serde::{Deserialize, Serialize};
@@ -305,7 +305,7 @@ fn replication_into_scene() {
305305
.id();
306306

307307
let mut scene = DynamicScene::default();
308-
server::replicate_into_scene(&mut scene, &app.world);
308+
scene::replicate_into(&mut scene, &app.world);
309309

310310
assert!(scene.resources.is_empty());
311311

0 commit comments

Comments
 (0)