my_ecs/ds/
queue.rs

1use std::{collections::VecDeque, ops::Deref};
2
3/// A queue with generation.
4///
5/// Generation increases whenever you take a value out of the queue, so that
6/// this would be useful when you need to know how many items are taken out
7/// since a specific time.
8///
9/// # Examples
10///
11/// ```
12/// use my_ecs::ds::GenQueue;
13///
14/// let mut queue = GenQueue::new();
15///
16/// // Calls lots of push_back() and pop_front() on the queue...
17/// # for _ in 0..10 {
18/// #     queue.push_back(0);
19/// # }
20/// # for _ in 0..5 {
21/// #     queue.pop_front();
22/// # }
23///
24/// // We're going to detect when this value will be returned.
25/// let value = 123;
26/// queue.push_back(value);
27/// let expire = queue.generation() + queue.len() as u64;
28///
29/// // Calls lots of push_back() and pop_front() on the queue...
30/// # for _ in 0..10 {
31/// #     queue.push_back(0);
32/// # }
33/// # for _ in 0..5 {
34/// #     queue.pop_front();
35/// # }
36///
37/// // `value` will be returned when queue's generation reaches `expire`.
38/// while let Some(taken) = queue.pop_front() {
39///     if queue.generation() == expire {
40///         assert_eq!(taken, value);
41///     }
42/// }
43/// ```
44#[derive(Debug, Clone)]
45pub struct GenQueue<T> {
46    queue: VecDeque<T>,
47    generation: u64,
48}
49
50impl<T> GenQueue<T> {
51    /// Creates a new empty [`GenQueue`].
52    ///
53    /// # Examples
54    ///
55    /// See [`GenQueue`] document.
56    pub const fn new() -> Self {
57        Self {
58            queue: VecDeque::new(),
59            generation: 0,
60        }
61    }
62
63    /// Returns current generation of the queue.
64    ///
65    /// Note that generation increases by 1 whenever you call
66    /// [`GenQueue::pop_front`].
67    ///
68    /// # Examples
69    ///
70    /// See [`GenQueue`] document.
71    pub fn generation(&self) -> u64 {
72        self.generation
73    }
74
75    /// Returns a mutable reference to the value at the beginning of the queue.
76    ///
77    /// # Examples
78    ///
79    /// ```
80    /// use my_ecs::ds::GenQueue;
81    ///
82    /// let mut queue = GenQueue::new();
83    /// queue.push_back(0);
84    /// queue.push_back(1);
85    /// assert_eq!(queue.front_mut(), Some(&mut 0));
86    /// ```
87    pub fn front_mut(&mut self) -> Option<&mut T> {
88        self.queue.front_mut()
89    }
90
91    /// Returns a mutable reference to the value at the end of the queue.
92    ///
93    /// # Examples
94    ///
95    /// ```
96    /// use my_ecs::ds::GenQueue;
97    ///
98    /// let mut queue = GenQueue::new();
99    /// queue.push_back(0);
100    /// queue.push_back(1);
101    /// assert_eq!(queue.back_mut(), Some(&mut 1));
102    /// ```
103    pub fn back_mut(&mut self) -> Option<&mut T> {
104        self.queue.back_mut()
105    }
106
107    /// Appends the given value to the end of the queue.
108    ///
109    /// # Examples
110    ///
111    /// See [`GenQueue`] document.
112    pub fn push_back(&mut self, value: T) {
113        self.queue.push_back(value);
114    }
115
116    /// Removes a value from the beginning of the queue then returns it.
117    ///
118    /// Note that this operation increases queue's generation by 1.
119    ///
120    /// # Examples
121    ///
122    /// See [`GenQueue`] document.
123    pub fn pop_front(&mut self) -> Option<T> {
124        let old = self.queue.pop_front();
125        if old.is_some() {
126            self.generation += 1;
127        }
128        old
129    }
130}
131
132impl<T> Default for GenQueue<T> {
133    fn default() -> Self {
134        Self::new()
135    }
136}
137
138impl<T> Deref for GenQueue<T> {
139    type Target = VecDeque<T>;
140
141    fn deref(&self) -> &Self::Target {
142        &self.queue
143    }
144}