naia_shared/world/
local_world_manager.rs1use 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 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 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 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}