Skip to main content

steel_core/world/
domain_entity_directory.rs

1use std::sync::{Arc, Weak};
2
3use steel_utils::locks::SyncRwLock;
4use uuid::Uuid;
5
6use crate::entity::SharedEntity;
7
8use super::World;
9
10/// Loaded worlds in one domain, without creating world ownership cycles.
11pub(crate) struct DomainEntityDirectory {
12    worlds: SyncRwLock<Vec<Weak<World>>>,
13}
14
15impl DomainEntityDirectory {
16    pub(crate) const fn new() -> Self {
17        Self {
18            worlds: SyncRwLock::new(Vec::new()),
19        }
20    }
21
22    pub(crate) fn add_world(&self, world: &Arc<World>) {
23        let mut worlds = self.worlds.write();
24        worlds.retain(|registered| registered.strong_count() > 0);
25        if worlds
26            .iter()
27            .filter_map(Weak::upgrade)
28            .any(|registered| Arc::ptr_eq(&registered, world))
29        {
30            return;
31        }
32        worlds.push(Arc::downgrade(world));
33    }
34
35    pub(crate) fn remove_world(&self, world: &Arc<World>) {
36        self.worlds.write().retain(|registered| {
37            registered
38                .upgrade()
39                .is_some_and(|registered| !Arc::ptr_eq(&registered, world))
40        });
41    }
42
43    pub(crate) fn get_entity_by_uuid(&self, uuid: &Uuid) -> Option<SharedEntity> {
44        self.worlds
45            .read()
46            .iter()
47            .filter_map(Weak::upgrade)
48            .find_map(|world| world.get_entity_by_uuid(uuid))
49    }
50}