naia_bevy_shared/
world_proxy.rs

1use std::any::TypeId;
2
3use bevy_ecs::{
4    entity::Entity,
5    world::{Mut, World},
6};
7
8use naia_shared::{
9    ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType,
10    LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper,
11    ReplicaMutWrapper, ReplicaRefWrapper, Replicate, ReplicatedComponent, SerdeErr, WorldMutType,
12    WorldRefType,
13};
14
15use super::{
16    component_ref::{ComponentMut, ComponentRef},
17    world_data::WorldData,
18};
19
20// WorldProxy
21
22pub trait WorldProxy<'w> {
23    fn proxy(self) -> WorldRef<'w>;
24}
25
26impl<'w> WorldProxy<'w> for &'w World {
27    fn proxy(self) -> WorldRef<'w> {
28        WorldRef::new(self)
29    }
30}
31
32// WorldProxyMut
33
34pub trait WorldProxyMut<'w> {
35    fn proxy_mut(self) -> WorldMut<'w>;
36}
37
38impl<'w> WorldProxyMut<'w> for &'w mut World {
39    fn proxy_mut(self) -> WorldMut<'w> {
40        WorldMut::new(self)
41    }
42}
43
44// WorldRef //
45
46pub struct WorldRef<'w> {
47    world: &'w World,
48}
49
50impl<'w> WorldRef<'w> {
51    pub fn new(world: &'w World) -> Self {
52        WorldRef { world }
53    }
54}
55
56impl<'w> WorldRefType<Entity> for WorldRef<'w> {
57    fn has_entity(&self, entity: &Entity) -> bool {
58        has_entity(self.world, entity)
59    }
60
61    fn entities(&self) -> Vec<Entity> {
62        entities(self.world)
63    }
64
65    fn has_component<R: ReplicatedComponent>(&self, entity: &Entity) -> bool {
66        has_component::<R>(self.world, entity)
67    }
68
69    fn has_component_of_kind(&self, entity: &Entity, component_kind: &ComponentKind) -> bool {
70        has_component_of_kind(self.world, entity, component_kind)
71    }
72
73    fn component<R: ReplicatedComponent>(&self, entity: &Entity) -> Option<ReplicaRefWrapper<R>> {
74        component(self.world, entity)
75    }
76
77    fn component_of_kind(
78        &self,
79        entity: &Entity,
80        component_kind: &ComponentKind,
81    ) -> Option<ReplicaDynRefWrapper> {
82        component_of_kind(self.world, entity, component_kind)
83    }
84}
85
86// WorldMut
87
88pub struct WorldMut<'w> {
89    world: &'w mut World,
90}
91
92impl<'w> WorldMut<'w> {
93    pub fn new(world: &'w mut World) -> Self {
94        WorldMut { world }
95    }
96}
97
98impl<'w> WorldRefType<Entity> for WorldMut<'w> {
99    fn has_entity(&self, entity: &Entity) -> bool {
100        has_entity(self.world, entity)
101    }
102
103    fn entities(&self) -> Vec<Entity> {
104        entities(self.world)
105    }
106
107    fn has_component<R: ReplicatedComponent>(&self, entity: &Entity) -> bool {
108        has_component::<R>(self.world, entity)
109    }
110
111    fn has_component_of_kind(&self, entity: &Entity, component_kind: &ComponentKind) -> bool {
112        has_component_of_kind(self.world, entity, component_kind)
113    }
114
115    fn component<R: ReplicatedComponent>(&self, entity: &Entity) -> Option<ReplicaRefWrapper<R>> {
116        component(self.world, entity)
117    }
118
119    fn component_of_kind(
120        &self,
121        entity: &Entity,
122        component_kind: &ComponentKind,
123    ) -> Option<ReplicaDynRefWrapper> {
124        component_of_kind(self.world, entity, component_kind)
125    }
126}
127
128impl<'w> WorldMutType<Entity> for WorldMut<'w> {
129    fn spawn_entity(&mut self) -> Entity {
130        let entity = self.world.spawn_empty().id();
131
132        let mut world_data = world_data_unchecked_mut(self.world);
133        world_data.spawn_entity(&entity);
134
135        entity
136    }
137
138    fn local_duplicate_entity(&mut self, entity: &Entity) -> Entity {
139        let new_entity = WorldMutType::<Entity>::spawn_entity(self);
140
141        WorldMutType::<Entity>::local_duplicate_components(self, &new_entity, entity);
142
143        new_entity
144    }
145
146    fn local_duplicate_components(&mut self, mutable_entity: &Entity, immutable_entity: &Entity) {
147        for component_kind in WorldMutType::<Entity>::component_kinds(self, immutable_entity) {
148            let mut component_copy_opt: Option<Box<dyn Replicate>> = None;
149            if let Some(component) = self.component_of_kind(immutable_entity, &component_kind) {
150                component_copy_opt = Some(component.copy_to_box());
151            }
152            if let Some(mut component_copy) = component_copy_opt {
153                component_copy.localize();
154                self.insert_boxed_component(mutable_entity, component_copy);
155            }
156        }
157    }
158
159    fn despawn_entity(&mut self, entity: &Entity) {
160        let mut world_data = world_data_unchecked_mut(self.world);
161        world_data.despawn_entity(entity);
162
163        self.world.despawn(*entity);
164    }
165
166    fn component_kinds(&mut self, entity: &Entity) -> Vec<ComponentKind> {
167        let mut kinds = Vec::new();
168
169        let world_data = world_data(&self.world);
170
171        let components = self.world.components();
172
173        for component_id in self.world.entity(*entity).archetype().components() {
174            let component_info = components
175                .get_info(component_id)
176                .expect("Components need info to instantiate");
177            let type_id = component_info
178                .type_id()
179                .expect("Components need type_id to instantiate");
180            let component_kind = ComponentKind::from(type_id);
181
182            if world_data.has_kind(&component_kind) {
183                kinds.push(component_kind);
184            }
185        }
186
187        kinds
188    }
189
190    fn component_mut<R: ReplicatedComponent>(
191        &mut self,
192        entity: &Entity,
193    ) -> Option<ReplicaMutWrapper<R>> {
194        if let Some(bevy_mut) = self.world.get_mut::<R>(*entity) {
195            let wrapper = ComponentMut(bevy_mut);
196            let component_mut = ReplicaMutWrapper::new(wrapper);
197            return Some(component_mut);
198        }
199        None
200    }
201
202    fn component_mut_of_kind(
203        &mut self,
204        entity: &Entity,
205        component_kind: &ComponentKind,
206    ) -> Option<ReplicaDynMutWrapper> {
207        let world_data = world_data(&self.world);
208        let Some(component_access) = world_data.component_access(component_kind) else {
209            return None;
210        };
211        let new_component_access = component_access.box_clone();
212        new_component_access.component_mut(self.world, entity)
213    }
214
215    fn component_apply_update(
216        &mut self,
217        converter: &dyn LocalEntityAndGlobalEntityConverter,
218        entity: &Entity,
219        component_kind: &ComponentKind,
220        update: ComponentUpdate,
221    ) -> Result<(), SerdeErr> {
222        self.world
223            .resource_scope(|world: &mut World, data: Mut<WorldData>| {
224                let Some(accessor) = data.component_access(component_kind) else {
225                    panic!("ComponentKind has not been registered?");
226                };
227                if let Some(mut component) = accessor.component_mut(world, entity) {
228                    let _update_result = component.read_apply_update(converter, update);
229                }
230            });
231        Ok(())
232    }
233
234    fn component_apply_field_update(
235        &mut self,
236        converter: &dyn LocalEntityAndGlobalEntityConverter,
237        entity: &Entity,
238        component_kind: &ComponentKind,
239        update: ComponentFieldUpdate,
240    ) -> Result<(), SerdeErr> {
241        self.world
242            .resource_scope(|world: &mut World, data: Mut<WorldData>| {
243                let Some(accessor) = data.component_access(component_kind) else {
244                    panic!("ComponentKind has not been registered?");
245                };
246                if let Some(mut component) = accessor.component_mut(world, entity) {
247                    let _update_result = component.read_apply_field_update(converter, update);
248                }
249            });
250        Ok(())
251    }
252
253    fn mirror_entities(&mut self, new_entity: &Entity, old_entity: &Entity) {
254        for component_kind in WorldMutType::<Entity>::component_kinds(self, old_entity) {
255            WorldMutType::<Entity>::mirror_components(
256                self,
257                new_entity,
258                old_entity,
259                &component_kind,
260            );
261        }
262    }
263
264    fn mirror_components(
265        &mut self,
266        mutable_entity: &Entity,
267        immutable_entity: &Entity,
268        component_kind: &ComponentKind,
269    ) {
270        self.world
271            .resource_scope(|world: &mut World, data: Mut<WorldData>| {
272                let Some(accessor) = data.component_access(component_kind) else {
273                    panic!("ComponentKind has not been registered?");
274                };
275                accessor.mirror_components(world, mutable_entity, immutable_entity);
276            });
277    }
278
279    fn insert_component<R: ReplicatedComponent>(&mut self, entity: &Entity, component_ref: R) {
280        // insert into ecs
281        self.world.entity_mut(*entity).insert(component_ref);
282    }
283
284    fn insert_boxed_component(&mut self, entity: &Entity, boxed_component: Box<dyn Replicate>) {
285        let component_kind = boxed_component.kind();
286        self.world
287            .resource_scope(|world: &mut World, data: Mut<WorldData>| {
288                let Some(accessor) = data.component_access(&component_kind) else {
289                    panic!("ComponentKind has not been registered?");
290                };
291                accessor.insert_component(world, entity, boxed_component);
292            });
293    }
294
295    fn remove_component<R: ReplicatedComponent>(&mut self, entity: &Entity) -> Option<R> {
296        self.world.entity_mut(*entity).take::<R>()
297    }
298
299    fn remove_component_of_kind(
300        &mut self,
301        entity: &Entity,
302        component_kind: &ComponentKind,
303    ) -> Option<Box<dyn Replicate>> {
304        let mut output: Option<Box<dyn Replicate>> = None;
305        self.world
306            .resource_scope(|world: &mut World, data: Mut<WorldData>| {
307                let Some(accessor) = data.component_access(component_kind) else {
308                    panic!("ComponentKind has not been registered?");
309                };
310                output = accessor.remove_component(world, entity);
311            });
312        output
313    }
314
315    fn entity_publish(
316        &mut self,
317        global_world_manager: &dyn GlobalWorldManagerType<Entity>,
318        entity: &Entity,
319    ) {
320        for component_kind in WorldMutType::<Entity>::component_kinds(self, entity) {
321            WorldMutType::<Entity>::component_publish(
322                self,
323                global_world_manager,
324                entity,
325                &component_kind,
326            );
327        }
328    }
329
330    fn component_publish(
331        &mut self,
332        global_world_manager: &dyn GlobalWorldManagerType<Entity>,
333        entity: &Entity,
334        component_kind: &ComponentKind,
335    ) {
336        self.world
337            .resource_scope(|world: &mut World, data: Mut<WorldData>| {
338                let Some(accessor) = data.component_access(component_kind) else {
339                    panic!("ComponentKind has not been registered?");
340                };
341                accessor.component_publish(global_world_manager, world, entity);
342            });
343    }
344
345    fn entity_unpublish(&mut self, entity: &Entity) {
346        for component_kind in WorldMutType::<Entity>::component_kinds(self, entity) {
347            WorldMutType::<Entity>::component_unpublish(self, entity, &component_kind);
348        }
349    }
350
351    fn component_unpublish(&mut self, entity: &Entity, component_kind: &ComponentKind) {
352        self.world
353            .resource_scope(|world: &mut World, data: Mut<WorldData>| {
354                let Some(accessor) = data.component_access(component_kind) else {
355                    panic!("ComponentKind has not been registered?");
356                };
357                accessor.component_unpublish(world, entity);
358            });
359    }
360
361    fn entity_enable_delegation(
362        &mut self,
363        global_world_manager: &dyn GlobalWorldManagerType<Entity>,
364        entity: &Entity,
365    ) {
366        for component_kind in WorldMutType::<Entity>::component_kinds(self, entity) {
367            WorldMutType::<Entity>::component_enable_delegation(
368                self,
369                global_world_manager,
370                entity,
371                &component_kind,
372            );
373        }
374    }
375
376    fn component_enable_delegation(
377        &mut self,
378        global_world_manager: &dyn GlobalWorldManagerType<Entity>,
379        entity: &Entity,
380        component_kind: &ComponentKind,
381    ) {
382        self.world
383            .resource_scope(|world: &mut World, data: Mut<WorldData>| {
384                let Some(accessor) = data.component_access(component_kind) else {
385                    panic!("ComponentKind has not been registered?");
386                };
387                accessor.component_enable_delegation(global_world_manager, world, entity);
388            });
389    }
390
391    fn entity_disable_delegation(&mut self, entity: &Entity) {
392        for component_kind in WorldMutType::<Entity>::component_kinds(self, entity) {
393            WorldMutType::<Entity>::component_disable_delegation(self, entity, &component_kind);
394        }
395    }
396
397    fn component_disable_delegation(&mut self, entity: &Entity, component_kind: &ComponentKind) {
398        self.world
399            .resource_scope(|world: &mut World, data: Mut<WorldData>| {
400                let Some(accessor) = data.component_access(component_kind) else {
401                    panic!("ComponentKind has not been registered?");
402                };
403                accessor.component_disable_delegation(world, entity);
404            });
405    }
406}
407
408// private static methods
409
410fn has_entity(world: &World, entity: &Entity) -> bool {
411    world.get_entity(*entity).is_ok()
412}
413
414fn entities(world: &World) -> Vec<Entity> {
415    let world_data = world_data(world);
416    world_data.entities()
417}
418
419fn has_component<R: ReplicatedComponent>(world: &World, entity: &Entity) -> bool {
420    world.get::<R>(*entity).is_some()
421}
422
423fn has_component_of_kind(world: &World, entity: &Entity, component_kind: &ComponentKind) -> bool {
424    world
425        .entity(*entity)
426        .contains_type_id(<ComponentKind as Into<TypeId>>::into(*component_kind))
427}
428
429fn component<'a, R: ReplicatedComponent>(
430    world: &'a World,
431    entity: &Entity,
432) -> Option<ReplicaRefWrapper<'a, R>> {
433    if let Some(bevy_ref) = world.get::<R>(*entity) {
434        let wrapper = ComponentRef(bevy_ref);
435        let component_ref = ReplicaRefWrapper::new(wrapper);
436        return Some(component_ref);
437    }
438    None
439}
440
441fn component_of_kind<'a>(
442    world: &'a World,
443    entity: &Entity,
444    component_kind: &ComponentKind,
445) -> Option<ReplicaDynRefWrapper<'a>> {
446    let world_data = world_data(world);
447    let Some(component_access) = world_data.component_access(component_kind) else {
448        panic!("ComponentKind has not been registered?");
449    };
450    component_access.component(world, entity)
451}
452
453fn world_data(world: &World) -> &WorldData {
454    world
455        .get_resource::<WorldData>()
456        .expect("Need to instantiate by adding WorldData<Protocol> resource at startup!")
457}
458
459fn world_data_unchecked_mut(world: &mut World) -> Mut<WorldData> {
460    unsafe {
461        world
462            .as_unsafe_world_cell()
463            .get_resource_mut::<WorldData>()
464            .expect("Need to instantiate by adding WorldData<Protocol> resource at startup!")
465    }
466}