naia_shared/world/entity/
entity_converters.rs

1use std::{
2    hash::Hash,
3    sync::{Arc, RwLock},
4};
5
6use log::warn;
7
8use crate::{
9    bigmap::BigMapKey,
10    world::{
11        delegation::auth_channel::EntityAuthAccessor,
12        entity::{
13            error::EntityDoesNotExistError,
14            global_entity::GlobalEntity,
15            local_entity::{HostEntity, OwnedLocalEntity, RemoteEntity},
16        },
17        host::mut_channel::MutChannelType,
18    },
19    ComponentKind, GlobalDiffHandler, LocalWorldManager, PropertyMutator,
20};
21
22pub trait GlobalWorldManagerType<E: Copy + Eq + Hash>: EntityAndGlobalEntityConverter<E> {
23    fn component_kinds(&self, entity: &E) -> Option<Vec<ComponentKind>>;
24    fn to_global_entity_converter(&self) -> &dyn EntityAndGlobalEntityConverter<E>;
25    /// Whether or not a given user can receive a Message/Componet with an EntityProperty relating to the given Entity
26    fn entity_can_relate_to_user(&self, entity: &E, user_key: &u64) -> bool;
27    fn new_mut_channel(&self, diff_mask_length: u8) -> Arc<RwLock<dyn MutChannelType>>;
28    fn diff_handler(&self) -> Arc<RwLock<GlobalDiffHandler<E>>>;
29    fn register_component(
30        &self,
31        entity: &E,
32        component_kind: &ComponentKind,
33        diff_mask_length: u8,
34    ) -> PropertyMutator;
35    fn get_entity_auth_accessor(&self, entity: &E) -> EntityAuthAccessor;
36    fn entity_needs_mutator_for_delegation(&self, entity: &E) -> bool;
37    fn entity_is_replicating(&self, entity: &E) -> bool;
38}
39
40pub trait EntityAndGlobalEntityConverter<E: Copy + Eq + Hash> {
41    fn global_entity_to_entity(
42        &self,
43        global_entity: &GlobalEntity,
44    ) -> Result<E, EntityDoesNotExistError>;
45    fn entity_to_global_entity(&self, entity: &E) -> Result<GlobalEntity, EntityDoesNotExistError>;
46}
47
48pub trait LocalEntityAndGlobalEntityConverter {
49    fn global_entity_to_host_entity(
50        &self,
51        global_entity: &GlobalEntity,
52    ) -> Result<HostEntity, EntityDoesNotExistError>;
53    fn global_entity_to_remote_entity(
54        &self,
55        global_entity: &GlobalEntity,
56    ) -> Result<RemoteEntity, EntityDoesNotExistError>;
57    fn global_entity_to_owned_entity(
58        &self,
59        global_entity: &GlobalEntity,
60    ) -> Result<OwnedLocalEntity, EntityDoesNotExistError>;
61    fn host_entity_to_global_entity(
62        &self,
63        host_entity: &HostEntity,
64    ) -> Result<GlobalEntity, EntityDoesNotExistError>;
65    fn remote_entity_to_global_entity(
66        &self,
67        remote_entity: &RemoteEntity,
68    ) -> Result<GlobalEntity, EntityDoesNotExistError>;
69}
70
71pub trait EntityAndLocalEntityConverter<E: Copy + Eq + Hash> {
72    fn entity_to_host_entity(&self, entity: &E) -> Result<HostEntity, EntityDoesNotExistError>;
73    fn entity_to_remote_entity(&self, entity: &E) -> Result<RemoteEntity, EntityDoesNotExistError>;
74    fn entity_to_owned_entity(
75        &self,
76        entity: &E,
77    ) -> Result<OwnedLocalEntity, EntityDoesNotExistError>;
78    fn host_entity_to_entity(&self, host_entity: &HostEntity)
79        -> Result<E, EntityDoesNotExistError>;
80    fn remote_entity_to_entity(
81        &self,
82        remote_entity: &RemoteEntity,
83    ) -> Result<E, EntityDoesNotExistError>;
84}
85
86pub struct FakeEntityConverter;
87
88impl LocalEntityAndGlobalEntityConverter for FakeEntityConverter {
89    fn global_entity_to_host_entity(
90        &self,
91        _: &GlobalEntity,
92    ) -> Result<HostEntity, EntityDoesNotExistError> {
93        Ok(HostEntity::new(0))
94    }
95
96    fn global_entity_to_remote_entity(
97        &self,
98        _: &GlobalEntity,
99    ) -> Result<RemoteEntity, EntityDoesNotExistError> {
100        Ok(RemoteEntity::new(0))
101    }
102
103    fn global_entity_to_owned_entity(
104        &self,
105        _global_entity: &GlobalEntity,
106    ) -> Result<OwnedLocalEntity, EntityDoesNotExistError> {
107        Ok(OwnedLocalEntity::Host(0))
108    }
109
110    fn host_entity_to_global_entity(
111        &self,
112        _: &HostEntity,
113    ) -> Result<GlobalEntity, EntityDoesNotExistError> {
114        Ok(GlobalEntity::from_u64(0))
115    }
116
117    fn remote_entity_to_global_entity(
118        &self,
119        _: &RemoteEntity,
120    ) -> Result<GlobalEntity, EntityDoesNotExistError> {
121        Ok(GlobalEntity::from_u64(0))
122    }
123}
124
125impl LocalEntityAndGlobalEntityConverterMut for FakeEntityConverter {
126    fn get_or_reserve_entity(
127        &mut self,
128        _global_entity: &GlobalEntity,
129    ) -> Result<OwnedLocalEntity, EntityDoesNotExistError> {
130        Ok(OwnedLocalEntity::Host(0))
131    }
132}
133
134pub struct EntityConverter<'a, 'b, E: Eq + Copy + Hash> {
135    global_entity_converter: &'a dyn EntityAndGlobalEntityConverter<E>,
136    local_entity_converter: &'b dyn EntityAndLocalEntityConverter<E>,
137}
138
139impl<'a, 'b, E: Eq + Copy + Hash> EntityConverter<'a, 'b, E> {
140    pub fn new(
141        global_entity_converter: &'a dyn EntityAndGlobalEntityConverter<E>,
142        local_entity_converter: &'b dyn EntityAndLocalEntityConverter<E>,
143    ) -> Self {
144        Self {
145            global_entity_converter,
146            local_entity_converter,
147        }
148    }
149}
150
151impl<'a, 'b, E: Copy + Eq + Hash> LocalEntityAndGlobalEntityConverter
152    for EntityConverter<'a, 'b, E>
153{
154    fn global_entity_to_host_entity(
155        &self,
156        global_entity: &GlobalEntity,
157    ) -> Result<HostEntity, EntityDoesNotExistError> {
158        if let Ok(entity) = self
159            .global_entity_converter
160            .global_entity_to_entity(global_entity)
161        {
162            return self.local_entity_converter.entity_to_host_entity(&entity);
163        }
164        return Err(EntityDoesNotExistError);
165    }
166
167    fn global_entity_to_remote_entity(
168        &self,
169        global_entity: &GlobalEntity,
170    ) -> Result<RemoteEntity, EntityDoesNotExistError> {
171        if let Ok(entity) = self
172            .global_entity_converter
173            .global_entity_to_entity(global_entity)
174        {
175            return self.local_entity_converter.entity_to_remote_entity(&entity);
176        }
177        return Err(EntityDoesNotExistError);
178    }
179
180    fn global_entity_to_owned_entity(
181        &self,
182        global_entity: &GlobalEntity,
183    ) -> Result<OwnedLocalEntity, EntityDoesNotExistError> {
184        if let Ok(entity) = self
185            .global_entity_converter
186            .global_entity_to_entity(global_entity)
187        {
188            return self.local_entity_converter.entity_to_owned_entity(&entity);
189        }
190        return Err(EntityDoesNotExistError);
191    }
192
193    fn host_entity_to_global_entity(
194        &self,
195        host_entity: &HostEntity,
196    ) -> Result<GlobalEntity, EntityDoesNotExistError> {
197        if let Ok(entity) = self
198            .local_entity_converter
199            .host_entity_to_entity(host_entity)
200        {
201            return self
202                .global_entity_converter
203                .entity_to_global_entity(&entity);
204        }
205        warn!("host_entity_to_global_entity() failed!");
206        return Err(EntityDoesNotExistError);
207    }
208
209    fn remote_entity_to_global_entity(
210        &self,
211        remote_entity: &RemoteEntity,
212    ) -> Result<GlobalEntity, EntityDoesNotExistError> {
213        if let Ok(entity) = self
214            .local_entity_converter
215            .remote_entity_to_entity(remote_entity)
216        {
217            return self
218                .global_entity_converter
219                .entity_to_global_entity(&entity);
220        }
221        return Err(EntityDoesNotExistError);
222    }
223}
224
225// Probably only should be used for writing messages
226pub struct EntityConverterMut<'a, 'b, E: Eq + Copy + Hash> {
227    global_world_manager: &'a dyn GlobalWorldManagerType<E>,
228    local_world_manager: &'b mut LocalWorldManager<E>,
229}
230
231impl<'a, 'b, E: Eq + Copy + Hash> EntityConverterMut<'a, 'b, E> {
232    pub fn new(
233        global_world_manager: &'a dyn GlobalWorldManagerType<E>,
234        local_world_manager: &'b mut LocalWorldManager<E>,
235    ) -> Self {
236        Self {
237            global_world_manager,
238            local_world_manager,
239        }
240    }
241}
242
243pub trait LocalEntityAndGlobalEntityConverterMut: LocalEntityAndGlobalEntityConverter {
244    fn get_or_reserve_entity(
245        &mut self,
246        global_entity: &GlobalEntity,
247    ) -> Result<OwnedLocalEntity, EntityDoesNotExistError>;
248}
249
250impl<'a, 'b, E: Copy + Eq + Hash> LocalEntityAndGlobalEntityConverter
251    for EntityConverterMut<'a, 'b, E>
252{
253    fn global_entity_to_host_entity(
254        &self,
255        global_entity: &GlobalEntity,
256    ) -> Result<HostEntity, EntityDoesNotExistError> {
257        if let Ok(entity) = self
258            .global_world_manager
259            .global_entity_to_entity(global_entity)
260        {
261            return self.local_world_manager.entity_to_host_entity(&entity);
262        }
263        return Err(EntityDoesNotExistError);
264    }
265
266    fn global_entity_to_remote_entity(
267        &self,
268        global_entity: &GlobalEntity,
269    ) -> Result<RemoteEntity, EntityDoesNotExistError> {
270        if let Ok(entity) = self
271            .global_world_manager
272            .global_entity_to_entity(global_entity)
273        {
274            return self.local_world_manager.entity_to_remote_entity(&entity);
275        }
276        return Err(EntityDoesNotExistError);
277    }
278
279    fn global_entity_to_owned_entity(
280        &self,
281        global_entity: &GlobalEntity,
282    ) -> Result<OwnedLocalEntity, EntityDoesNotExistError> {
283        if let Ok(entity) = self
284            .global_world_manager
285            .global_entity_to_entity(global_entity)
286        {
287            return self.local_world_manager.entity_to_owned_entity(&entity);
288        }
289        return Err(EntityDoesNotExistError);
290    }
291
292    fn host_entity_to_global_entity(
293        &self,
294        host_entity: &HostEntity,
295    ) -> Result<GlobalEntity, EntityDoesNotExistError> {
296        if let Ok(entity) = self.local_world_manager.host_entity_to_entity(host_entity) {
297            return self.global_world_manager.entity_to_global_entity(&entity);
298        }
299        return Err(EntityDoesNotExistError);
300    }
301
302    fn remote_entity_to_global_entity(
303        &self,
304        remote_entity: &RemoteEntity,
305    ) -> Result<GlobalEntity, EntityDoesNotExistError> {
306        if let Ok(entity) = self
307            .local_world_manager
308            .remote_entity_to_entity(remote_entity)
309        {
310            return self.global_world_manager.entity_to_global_entity(&entity);
311        }
312        return Err(EntityDoesNotExistError);
313    }
314}
315
316impl<'a, 'b, E: Copy + Eq + Hash> LocalEntityAndGlobalEntityConverterMut
317    for EntityConverterMut<'a, 'b, E>
318{
319    fn get_or_reserve_entity(
320        &mut self,
321        global_entity: &GlobalEntity,
322    ) -> Result<OwnedLocalEntity, EntityDoesNotExistError> {
323        let Ok(entity) = self
324            .global_world_manager
325            .global_entity_to_entity(global_entity)
326        else {
327            return Err(EntityDoesNotExistError);
328        };
329        if !self
330            .global_world_manager
331            .entity_can_relate_to_user(&entity, self.local_world_manager.get_user_key())
332        {
333            return Err(EntityDoesNotExistError);
334        }
335        let result = self.local_world_manager.entity_to_owned_entity(&entity);
336        if result.is_ok() {
337            return result;
338        }
339
340        let host_entity = self.local_world_manager.host_reserve_entity(&entity);
341
342        warn!("get_or_reserve_entity(): entity is not owned by user, attempting to reserve. HostEntity: {:?}", host_entity);
343        return Ok(host_entity.copy_to_owned());
344    }
345}