wde_renderer/sync/
sync_worlds.rs1use bevy::prelude::*;
2
3use crate::sync::{MainEntity, RenderEntity};
4
5#[derive(Component, Copy, Clone, Debug, Default, Reflect)]
10#[reflect(Component, Default, Clone)]
11#[component(storage = "SparseSet")]
12pub struct SyncToRenderWorld;
13
14pub(crate) struct SyncWorldPlugin;
15impl Plugin for SyncWorldPlugin {
16 fn build(&self, app: &mut App) {
17 app.init_resource::<PendingSyncEntity>()
18 .add_observer(
19 |add: On<Add, SyncToRenderWorld>, mut pending: ResMut<PendingSyncEntity>| {
20 pending.push(EntityRecord::Added(add.entity)); },
22 )
23 .add_observer(
24 |remove: On<Remove, SyncToRenderWorld>,
25 mut pending: ResMut<PendingSyncEntity>,
26 query: Query<&RenderEntity>| {
27 if let Ok(e) = query.get(remove.entity) {
28 pending.push(EntityRecord::Removed(*e)); };
30 },
31 );
32 }
33}
34
35#[derive(Debug)]
37pub(crate) enum EntityRecord {
38 Added(Entity),
40 Removed(RenderEntity),
42 ComponentRemoved(Entity, fn(EntityWorldMut<'_>)),
44}
45
46#[derive(Resource, Default, Deref, DerefMut)]
48pub(crate) struct PendingSyncEntity {
49 records: Vec<EntityRecord>,
50}
51
52pub(crate) fn sync_worlds(main_world: &mut World, render_world: &mut World) {
53 main_world.resource_scope(|world, mut pending: Mut<PendingSyncEntity>| {
54 for record in pending.drain(..) {
55 match record {
56 EntityRecord::Added(e) => {
57 if let Ok(mut main_entity) = world.get_entity_mut(e) {
58 match main_entity.entry::<RenderEntity>() {
59 bevy::ecs::world::ComponentEntry::Occupied(_) => {
60 panic!("Attempting to synchronize an entity that has already been synchronized!");
61 }
62 bevy::ecs::world::ComponentEntry::Vacant(entry) => {
63 let id = render_world.spawn(MainEntity(e)).id();
64
65 entry.insert(RenderEntity(id));
66 }
67 };
68 }
69 }
70 EntityRecord::Removed(render_entity) => {
71 if let Ok(ec) = render_world.get_entity_mut(render_entity.id()) {
72 ec.despawn();
73 };
74 }
75 EntityRecord::ComponentRemoved(main_entity, removal_function) => {
76 let Some(render_entity) = world.get::<RenderEntity>(main_entity) else {
77 continue;
78 };
79 if let Ok(render_world_entity) = render_world.get_entity_mut(render_entity.id()) {
80 removal_function(render_world_entity);
81 }
82 },
83 }
84 }
85 });
86}