d569534f2f340dc9aff7d0f5836f0adca9e249a9
[blender.git] / source / blender / blenlib / intern / gsqueue.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenlib/intern/gsqueue.c
29  *  \ingroup bli
30  */
31
32 #include <string.h>
33
34 #include "MEM_guardedalloc.h"
35 #include "BLI_gsqueue.h"
36
37 typedef struct _GSQueueElem GSQueueElem;
38 struct _GSQueueElem {
39         GSQueueElem *next;
40 };
41
42 struct _GSQueue {
43         GSQueueElem *head;
44         GSQueueElem *tail;
45         int elem_size;
46 };
47
48 GSQueue *BLI_gsqueue_new(int elem_size)
49 {
50         GSQueue *gq = MEM_mallocN(sizeof(*gq), "gqueue_new");
51         gq->head = gq->tail = NULL;
52         gq->elem_size = elem_size;
53         
54         return gq;
55 }
56
57 int BLI_gsqueue_is_empty(GSQueue *gq)
58 {
59         return (gq->head == NULL);
60 }
61
62 int BLI_gsqueue_size(GSQueue *gq)
63
64         GSQueueElem *elem;
65         int size = 0;
66
67         for (elem = gq->head; elem; elem = elem->next)
68                 size++;
69         
70         return size;
71 }
72
73 void BLI_gsqueue_peek(GSQueue *gq, void *item_r)
74 {
75         memcpy(item_r, &gq->head[1], gq->elem_size);
76 }
77 void BLI_gsqueue_pop(GSQueue *gq, void *item_r)
78 {
79         GSQueueElem *elem = gq->head;
80         if (elem == gq->tail) {
81                 gq->head = gq->tail = NULL;
82         }
83         else {
84                 gq->head = gq->head->next;
85         }
86         
87         if (item_r) memcpy(item_r, &elem[1], gq->elem_size);
88         MEM_freeN(elem);
89 }
90 void BLI_gsqueue_push(GSQueue *gq, void *item)
91 {
92         GSQueueElem *elem;
93         
94         /* compare: prevent events added double in row */
95         if (!BLI_gsqueue_is_empty(gq)) {
96                 if (0 == memcmp(item, &gq->head[1], gq->elem_size))
97                         return;
98         }
99         elem = MEM_mallocN(sizeof(*elem) + gq->elem_size, "gqueue_push");
100         memcpy(&elem[1], item, gq->elem_size);
101         elem->next = NULL;
102         
103         if (BLI_gsqueue_is_empty(gq)) {
104                 gq->tail = gq->head = elem;
105         }
106         else {
107                 gq->tail = gq->tail->next = elem;
108         }
109 }
110 void BLI_gsqueue_pushback(GSQueue *gq, void *item)
111 {
112         GSQueueElem *elem = MEM_mallocN(sizeof(*elem) + gq->elem_size, "gqueue_push");
113         memcpy(&elem[1], item, gq->elem_size);
114         elem->next = gq->head;
115
116         if (BLI_gsqueue_is_empty(gq)) {
117                 gq->head = gq->tail = elem;
118         }
119         else {
120                 gq->head = elem;
121         }
122 }
123
124 void BLI_gsqueue_free(GSQueue *gq)
125 {
126         while (gq->head) {
127                 BLI_gsqueue_pop(gq, NULL);
128         }
129         MEM_freeN(gq);
130 }
131
132