naia_bevy_shared/
change_detection.rs1use std::any::TypeId;
2
3use bevy_ecs::{
4 component::Component,
5 entity::Entity,
6 event::EventWriter,
7 prelude::Event,
8 query::{Added, Changed},
9 removal_detection::RemovedComponents,
10 system::{Query, ResMut},
11};
12
13use naia_shared::{ComponentKind, Replicate};
14
15use crate::{HostOwned, HostOwnedMap};
16
17#[derive(Event)]
18pub enum HostSyncEvent {
19 Insert(TypeId, Entity, ComponentKind),
20 Remove(TypeId, Entity, ComponentKind),
21 Despawn(TypeId, Entity),
22}
23
24impl HostSyncEvent {
25 pub fn host_id(&self) -> TypeId {
26 match self {
27 HostSyncEvent::Insert(type_id, _, _) => *type_id,
28 HostSyncEvent::Remove(type_id, _, _) => *type_id,
29 HostSyncEvent::Despawn(type_id, _) => *type_id,
30 }
31 }
32}
33
34pub fn on_host_owned_added(
35 query: Query<(Entity, &HostOwned), Changed<HostOwned>>,
36 mut host_owned_map: ResMut<HostOwnedMap>,
37) {
38 for (entity, host_owned) in query.iter() {
39 host_owned_map.insert(entity, *host_owned);
40 }
41}
42
43pub fn on_despawn(
44 mut events: EventWriter<HostSyncEvent>,
45 query: Query<Entity>,
46 mut removals: RemovedComponents<HostOwned>,
47 mut host_owned_map: ResMut<HostOwnedMap>,
48) {
49 for entity in removals.read() {
50 if let Ok(_) = query.get(entity) {
51 } else {
53 let Some(host_owned) = host_owned_map.remove(&entity) else {
55 panic!("HostOwned entity {:?} not found in HostOwnedMap", entity);
56 };
57 events.send(HostSyncEvent::Despawn(host_owned.type_id(), entity));
58 }
59 }
60}
61
62pub fn on_component_added<R: Replicate + Component>(
63 mut events: EventWriter<HostSyncEvent>,
64 query: Query<(Entity, &HostOwned), Added<R>>,
65) {
66 for (entity, host_owned) in query.iter() {
67 events.send(HostSyncEvent::Insert(
68 host_owned.type_id(),
69 entity,
70 ComponentKind::of::<R>(),
71 ));
72 }
73}
74
75pub fn on_component_removed<R: Replicate + Component>(
76 mut events: EventWriter<HostSyncEvent>,
77 query: Query<&HostOwned>,
78 mut removals: RemovedComponents<R>,
79) {
80 for entity in removals.read() {
81 if let Ok(host_owned) = query.get(entity) {
82 events.send(HostSyncEvent::Remove(
83 host_owned.type_id(),
84 entity,
85 ComponentKind::of::<R>(),
86 ));
87 }
88 }
89}