@@ -135,15 +135,13 @@ int32_t staticQueueErase(staticQueue_t* queue, staticQueueItem_t* item)
135135 item -> active = false;
136136
137137 // Special case: if this was the only item in the queue
138- if (queue -> tail == queue -> head -> last ) {
138+ if (queue -> tail == queue -> head -> last && queue -> tail == item ) {
139139 // Queue is now empty, reset pointers
140140 queue -> head = queue -> first_item ;
141141 queue -> tail = queue -> first_item ;
142142 return STATIC_QUEUE_SUCCESS ;
143- }
144-
145- // If erasing the tail item (oldest item), just move tail to next
146- if (item == queue -> tail ) {
143+ } else if (item == queue -> tail ) {
144+ // If erasing the tail item (oldest item), just move tail to next
147145 queue -> tail = queue -> tail -> next ;
148146
149147 // Skip over any remaining inactive items at tail
@@ -158,10 +156,8 @@ int32_t staticQueueErase(staticQueue_t* queue, staticQueueItem_t* item)
158156 }
159157
160158 return STATIC_QUEUE_SUCCESS ;
161- }
162-
163- // If erasing the item just before head (newest item), move head backward
164- if (item -> next == queue -> head ) {
159+ } else if (item -> next == queue -> head ) {
160+ // If erasing the item just before head (newest item), move head backward
165161 queue -> head = item ;
166162
167163 // Check if head caught up to tail with exactly one active item
@@ -173,7 +169,24 @@ int32_t staticQueueErase(staticQueue_t* queue, staticQueueItem_t* item)
173169 return STATIC_QUEUE_SUCCESS ;
174170 }
175171
176- // For items in the middle: remove from current position and relink immediately before tail
172+ // For items in the middle: first verify the item is actually in the queue
173+ // We can start from the element one from the tail as we have allready checked the tail item above.
174+ staticQueueItem_t * current = queue -> tail -> next ;
175+ bool found = false;
176+
177+ // Traverse from tail to head to find the item
178+ while (current != queue -> head ) {
179+ if (current == item ) {
180+ found = true;
181+ break ;
182+ }
183+ current = current -> next ;
184+ }
185+
186+ // If not found, the item is not in this queue
187+ if (!found ) {
188+ return STATIC_QUEUE_NOT_IN_QUEUE ;
189+ }
177190
178191 // Step 1: Remove item from its current position in the list
179192 staticQueueItem_t * prev_item = item -> last ;
@@ -198,3 +211,87 @@ int32_t staticQueueErase(staticQueue_t* queue, staticQueueItem_t* item)
198211
199212 return STATIC_QUEUE_SUCCESS ;
200213}
214+
215+ int32_t staticQueueGetNumItems (staticQueue_t * queue )
216+ {
217+ if (queue == NULL ) {
218+ return STATIC_QUEUE_EMPTY ;
219+ }
220+
221+ if (staticQueueEmpty (queue )) {
222+ return 0 ;
223+ }
224+
225+ // Check if queue is full
226+ if (staticQueuefull (queue )) {
227+ return queue -> queue_length ;
228+ }
229+
230+ // Count active items from tail to head
231+ int32_t count = 0 ;
232+ staticQueueItem_t * current = queue -> tail ;
233+
234+ while (current != queue -> head ) {
235+ if (current -> active ) {
236+ count ++ ;
237+ }
238+ current = current -> next ;
239+ }
240+
241+ return count ;
242+ }
243+
244+ int32_t staticQueueForEach (staticQueue_t * queue , int32_t (* callback )(staticQueue_t * queue , staticQueueItem_t * item ))
245+ {
246+ if (queue == NULL || callback == NULL ) {
247+ return STATIC_QUEUE_EMPTY ;
248+ }
249+
250+ if (staticQueueEmpty (queue )) {
251+ return STATIC_QUEUE_SUCCESS ;
252+ }
253+
254+ // Get the number of items to process
255+ int32_t num_items = staticQueueGetNumItems (queue );
256+ if (num_items <= 0 ) {
257+ return STATIC_QUEUE_SUCCESS ;
258+ }
259+
260+ staticQueueItem_t * current = queue -> tail ;
261+ int32_t processed = 0 ;
262+
263+ // Process exactly num_items active items
264+ while (processed < num_items ) {
265+ // Only process active items
266+ if (current -> active ) {
267+ int32_t cb_res = callback (queue , current );
268+ switch (cb_res ) {
269+ case STATIC_QUEUE_CB_NEXT :
270+ current = current -> next ;
271+ processed ++ ;
272+ break ;
273+ case STATIC_QUEUE_CB_STOP :
274+ return STATIC_QUEUE_SUCCESS ;
275+ case STATIC_QUEUE_CB_ERASE : {
276+ staticQueueItem_t * tmp = current ;
277+ current = current -> next ;
278+ processed ++ ;
279+ // Erase this item from the queue
280+ if ((cb_res = staticQueueErase (queue , tmp )) != STATIC_QUEUE_SUCCESS ) {
281+ return cb_res ;
282+ }
283+ // Check if queue is now empty after erase
284+ if (staticQueueEmpty (queue )) {
285+ return STATIC_QUEUE_SUCCESS ;
286+ }
287+ } break ;
288+ default :
289+ return cb_res ;
290+ }
291+ } else {
292+ current = current -> next ;
293+ }
294+ }
295+
296+ return STATIC_QUEUE_SUCCESS ;
297+ }
0 commit comments