bevy_utils/once.rs
1use bevy_platform::sync::atomic::{AtomicBool, Ordering};
2
3/// Wrapper around an [`AtomicBool`], abstracting the backing implementation and
4/// ordering considerations.
5#[doc(hidden)]
6pub struct OnceFlag(AtomicBool);
7
8impl OnceFlag {
9 /// Create a new flag in the unset state.
10 pub const fn new() -> Self {
11 Self(AtomicBool::new(true))
12 }
13
14 /// Sets this flag. Will return `true` if this flag hasn't been set before.
15 pub fn set(&self) -> bool {
16 self.0.swap(false, Ordering::Relaxed)
17 }
18}
19
20impl Default for OnceFlag {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26/// Call some expression only once per call site.
27#[macro_export]
28macro_rules! once {
29 ($expression:expr) => {{
30 static SHOULD_FIRE: $crate::OnceFlag = $crate::OnceFlag::new();
31 if SHOULD_FIRE.set() {
32 $expression;
33 }
34 }};
35}