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