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}