naia_shared/world/
local_world_manager.rs

1use std::{
2    collections::{HashMap, VecDeque},
3    hash::Hash,
4    time::Duration,
5};
6
7use naia_socket_shared::Instant;
8
9use crate::{
10    world::{
11        entity::local_entity::{HostEntity, OwnedLocalEntity, RemoteEntity},
12        local_entity_map::LocalEntityMap,
13    },
14    EntityAndLocalEntityConverter, EntityDoesNotExistError, KeyGenerator,
15};
16
17pub struct LocalWorldManager<E: Copy + Eq + Hash> {
18    user_key: u64,
19    host_entity_generator: KeyGenerator<u16>,
20    entity_map: LocalEntityMap<E>,
21    reserved_entities: HashMap<E, HostEntity>,
22    reserved_entity_ttl: Duration,
23    reserved_entities_ttls: VecDeque<(Instant, E)>,
24}
25
26impl<E: Copy + Eq + Hash> LocalWorldManager<E> {
27    pub fn new(user_key: u64) -> Self {
28        Self {
29            user_key,
30            host_entity_generator: KeyGenerator::new(Duration::from_secs(60)),
31            entity_map: LocalEntityMap::new(),
32            reserved_entities: HashMap::new(),
33            reserved_entity_ttl: Duration::from_secs(60),
34            reserved_entities_ttls: VecDeque::new(),
35        }
36    }
37
38    // Host entities
39
40    pub fn host_reserve_entity(&mut self, world_entity: &E) -> HostEntity {
41        self.process_reserved_entity_timeouts();
42
43        if self.reserved_entities.contains_key(world_entity) {
44            panic!("World Entity has already reserved Local Entity!");
45        }
46        let host_entity = self.generate_host_entity();
47        self.entity_map
48            .insert_with_host_entity(*world_entity, host_entity);
49        self.reserved_entities.insert(*world_entity, host_entity);
50        host_entity
51    }
52
53    fn process_reserved_entity_timeouts(&mut self) {
54        let now = Instant::now();
55
56        loop {
57            let Some((timeout, _)) = self.reserved_entities_ttls.front() else {
58                break;
59            };
60            if timeout.elapsed(&now) < self.reserved_entity_ttl {
61                break;
62            }
63            let (_, world_entity) = self.reserved_entities_ttls.pop_front().unwrap();
64            let Some(_) = self.reserved_entities.remove(&world_entity) else {
65                panic!("Reserved Entity does not exist!");
66            };
67        }
68    }
69
70    pub fn remove_reserved_host_entity(&mut self, world_entity: &E) -> Option<HostEntity> {
71        self.reserved_entities.remove(world_entity)
72    }
73
74    pub(crate) fn generate_host_entity(&mut self) -> HostEntity {
75        HostEntity::new(self.host_entity_generator.generate())
76    }
77
78    pub(crate) fn insert_host_entity(&mut self, world_entity: E, host_entity: HostEntity) {
79        if self.entity_map.contains_host_entity(&host_entity) {
80            panic!("Local Entity already exists!");
81        }
82
83        self.entity_map
84            .insert_with_host_entity(world_entity, host_entity);
85    }
86
87    pub fn insert_remote_entity(&mut self, world_entity: &E, remote_entity: RemoteEntity) {
88        if self.entity_map.contains_remote_entity(&remote_entity) {
89            panic!("Remote Entity `{:?}` already exists!", remote_entity);
90        }
91
92        self.entity_map
93            .insert_with_remote_entity(*world_entity, remote_entity);
94    }
95
96    pub(crate) fn remove_by_world_entity(&mut self, world_entity: &E) {
97        let record = self
98            .entity_map
99            .remove_by_world_entity(world_entity)
100            .expect("Attempting to despawn entity which does not exist!");
101        let host_entity = record.host().unwrap();
102        self.recycle_host_entity(host_entity);
103    }
104
105    pub fn remove_by_remote_entity(&mut self, remote_entity: &RemoteEntity) -> E {
106        let world_entity = *(self
107            .entity_map
108            .world_entity_from_remote(remote_entity)
109            .expect("Attempting to despawn entity which does not exist!"));
110        let record = self
111            .entity_map
112            .remove_by_world_entity(&world_entity)
113            .expect("Attempting to despawn entity which does not exist!");
114        if let Some(host_entity) = record.host() {
115            self.recycle_host_entity(host_entity);
116        }
117        world_entity
118    }
119
120    pub(crate) fn recycle_host_entity(&mut self, host_entity: HostEntity) {
121        self.host_entity_generator.recycle_key(&host_entity.value());
122    }
123
124    // Remote entities
125
126    pub fn has_remote_entity(&self, remote_entity: &RemoteEntity) -> bool {
127        self.entity_map.contains_remote_entity(remote_entity)
128    }
129
130    pub(crate) fn world_entity_from_remote(&self, remote_entity: &RemoteEntity) -> E {
131        if let Some(world_entity) = self.entity_map.world_entity_from_remote(remote_entity) {
132            return *world_entity;
133        } else {
134            panic!(
135                "Attempting to get world entity for local entity which does not exist!: `{:?}`",
136                remote_entity
137            );
138        }
139    }
140
141    pub(crate) fn remote_entities(&self) -> Vec<E> {
142        self.entity_map
143            .iter()
144            .filter(|(_, record)| record.is_only_remote())
145            .map(|(world_entity, _)| *world_entity)
146            .collect::<Vec<E>>()
147    }
148
149    // Misc
150
151    pub fn has_both_host_and_remote_entity(&self, world_entity: &E) -> bool {
152        self.entity_map
153            .has_both_host_and_remote_entity(world_entity)
154    }
155
156    pub fn has_world_entity(&self, world_entity: &E) -> bool {
157        self.entity_map.contains_world_entity(world_entity)
158    }
159
160    pub fn remove_redundant_host_entity(&mut self, world_entity: &E) {
161        if let Some(host_entity) = self.entity_map.remove_redundant_host_entity(world_entity) {
162            self.recycle_host_entity(host_entity);
163        }
164    }
165
166    pub fn remove_redundant_remote_entity(&mut self, world_entity: &E) -> RemoteEntity {
167        self.entity_map.remove_redundant_remote_entity(world_entity)
168    }
169
170    pub fn get_user_key(&self) -> &u64 {
171        &self.user_key
172    }
173}
174
175impl<E: Copy + Eq + Hash> EntityAndLocalEntityConverter<E> for LocalWorldManager<E> {
176    fn entity_to_host_entity(
177        &self,
178        world_entity: &E,
179    ) -> Result<HostEntity, EntityDoesNotExistError> {
180        if let Some(local_entity) = self.entity_map.get_host_entity(world_entity) {
181            return Ok(local_entity);
182        } else {
183            return Err(EntityDoesNotExistError);
184        }
185    }
186
187    fn entity_to_remote_entity(
188        &self,
189        world_entity: &E,
190    ) -> Result<RemoteEntity, EntityDoesNotExistError> {
191        if let Some(local_entity) = self.entity_map.get_remote_entity(world_entity) {
192            return Ok(local_entity);
193        } else {
194            return Err(EntityDoesNotExistError);
195        }
196    }
197
198    fn entity_to_owned_entity(
199        &self,
200        world_entity: &E,
201    ) -> Result<OwnedLocalEntity, EntityDoesNotExistError> {
202        if let Some(local_entity) = self.entity_map.get_owned_entity(world_entity) {
203            return Ok(local_entity);
204        } else {
205            return Err(EntityDoesNotExistError);
206        }
207    }
208
209    fn host_entity_to_entity(
210        &self,
211        host_entity: &HostEntity,
212    ) -> Result<E, EntityDoesNotExistError> {
213        if let Some(entity) = self.entity_map.world_entity_from_host(host_entity) {
214            return Ok(*entity);
215        } else {
216            return Err(EntityDoesNotExistError);
217        }
218    }
219
220    fn remote_entity_to_entity(
221        &self,
222        remote_entity: &RemoteEntity,
223    ) -> Result<E, EntityDoesNotExistError> {
224        if let Some(entity) = self.entity_map.world_entity_from_remote(remote_entity) {
225            return Ok(*entity);
226        } else {
227            return Err(EntityDoesNotExistError);
228        }
229    }
230}