bevy_ecs/world/
identifier.rs1use crate::system::{ExclusiveSystemParam, SystemMeta};
2use crate::{
3 component::Tick,
4 storage::SparseSetIndex,
5 system::{ReadOnlySystemParam, SystemParam},
6 world::{FromWorld, World},
7};
8use std::sync::atomic::{AtomicUsize, Ordering};
9
10use super::unsafe_world_cell::UnsafeWorldCell;
11
12#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
13pub struct WorldId(usize);
20
21static MAX_WORLD_ID: AtomicUsize = AtomicUsize::new(0);
23
24impl WorldId {
25 pub fn new() -> Option<Self> {
31 MAX_WORLD_ID
32 .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |val| {
34 val.checked_add(1)
35 })
36 .map(WorldId)
37 .ok()
38 }
39}
40
41impl FromWorld for WorldId {
42 #[inline]
43 fn from_world(world: &mut World) -> Self {
44 world.id()
45 }
46}
47
48unsafe impl ReadOnlySystemParam for WorldId {}
50
51unsafe impl SystemParam for WorldId {
53 type State = ();
54
55 type Item<'world, 'state> = WorldId;
56
57 fn init_state(_: &mut World, _: &mut crate::system::SystemMeta) -> Self::State {}
58
59 unsafe fn get_param<'world, 'state>(
60 _: &'state mut Self::State,
61 _: &crate::system::SystemMeta,
62 world: UnsafeWorldCell<'world>,
63 _: Tick,
64 ) -> Self::Item<'world, 'state> {
65 world.id()
66 }
67}
68
69impl ExclusiveSystemParam for WorldId {
70 type State = WorldId;
71 type Item<'s> = WorldId;
72
73 fn init(world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
74 world.id()
75 }
76
77 fn get_param<'s>(state: &'s mut Self::State, _system_meta: &SystemMeta) -> Self::Item<'s> {
78 *state
79 }
80}
81
82impl SparseSetIndex for WorldId {
83 #[inline]
84 fn sparse_set_index(&self) -> usize {
85 self.0
86 }
87
88 #[inline]
89 fn get_sparse_set_index(value: usize) -> Self {
90 Self(value)
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn world_ids_unique() {
100 let ids = std::iter::repeat_with(WorldId::new)
101 .take(50)
102 .map(Option::unwrap)
103 .collect::<Vec<_>>();
104 for (i, &id1) in ids.iter().enumerate() {
105 for &id2 in ids.iter().skip(i + 1) {
107 assert_ne!(id1, id2, "WorldIds should not repeat");
108 }
109 }
110 }
111
112 #[test]
113 fn world_id_system_param() {
114 fn test_system(world_id: WorldId) -> WorldId {
115 world_id
116 }
117
118 let mut world = World::default();
119 let system_id = world.register_system(test_system);
120 let world_id = world.run_system(system_id).unwrap();
121 assert_eq!(world.id(), world_id);
122 }
123
124 #[test]
125 fn world_id_exclusive_system_param() {
126 fn test_system(_world: &mut World, world_id: WorldId) -> WorldId {
127 world_id
128 }
129
130 let mut world = World::default();
131 let system_id = world.register_system(test_system);
132 let world_id = world.run_system(system_id).unwrap();
133 assert_eq!(world.id(), world_id);
134 }
135
136 }