Skip to main content

pui_core/pool/
flag.rs

1use core::{
2    marker::PhantomData,
3    mem,
4    sync::atomic::{Ordering::*, *},
5};
6
7use crate::{
8    pool::{Pool, PoolMut},
9    scalar::{OpaqueScalar, ScalarAllocator},
10    Init,
11};
12
13/// A [`Pool`] that can hold one scalar element of type `()`
14pub struct Flag<A> {
15    flag: AtomicBool,
16    alloc: PhantomData<A>,
17}
18
19impl<A> Init for Flag<A> {
20    const INIT: Self = Self::new();
21}
22
23impl<A> Flag<A> {
24    /// Create a new `Flag`
25    pub const fn new() -> Self {
26        Self {
27            flag: AtomicBool::new(false),
28            alloc: PhantomData,
29        }
30    }
31}
32
33impl<A: ScalarAllocator<Scalar = ()>> PoolMut<A> for Flag<A> {
34    fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
35        let filled = self.flag.get_mut();
36        if mem::replace(filled, true) {
37            Some(scalar)
38        } else {
39            None
40        }
41    }
42
43    fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> {
44        let filled = self.flag.get_mut();
45        if mem::replace(filled, false) {
46            Some(unsafe { OpaqueScalar::new(()) })
47        } else {
48            None
49        }
50    }
51}
52
53impl<A: ScalarAllocator<Scalar = ()>> Pool<A> for Flag<A> {
54    fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
55        if self.flag.swap(true, Acquire) {
56            Some(scalar)
57        } else {
58            None
59        }
60    }
61
62    fn remove(&self) -> Option<OpaqueScalar<A>> {
63        if self.flag.swap(false, Release) {
64            Some(unsafe { OpaqueScalar::new(()) })
65        } else {
66            None
67        }
68    }
69}