use 'bool' for BLI_/BKE_ functions.
[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
36 #include "BLI_utildefines.h"
37 #include "BLI_gsqueue.h"
38
39 typedef struct _GSQueueElem GSQueueElem;
40 struct _GSQueueElem {
41         GSQueueElem *next;
42 };
43
44 struct _GSQueue {
45         GSQueueElem *head;
46         GSQueueElem *tail;
47         int elem_size;
48 };
49
50 GSQueue *BLI_gsqueue_new(int elem_size)
51 {
52         GSQueue *gq = MEM_mallocN(sizeof(*gq), "gqueue_new");
53         gq->head = gq->tail = NULL;
54         gq->elem_size = elem_size;
55         
56         return gq;
57 }
58
59 bool BLI_gsqueue_is_empty(GSQueue *gq)
60 {
61         return (gq->head == NULL);
62 }
63
64 int BLI_gsqueue_size(GSQueue *gq)
65
66         GSQueueElem *elem;
67         int size = 0;
68
69         for (elem = gq->head; elem; elem = elem->next)
70                 size++;
71         
72         return size;
73 }
74
75 void BLI_gsqueue_peek(GSQueue *gq, void *item_r)
76 {
77         memcpy(item_r, &gq->head[1], gq->elem_size);
78 }
79 void BLI_gsqueue_pop(GSQueue *gq, void *item_r)
80 {
81         GSQueueElem *elem = gq->head;
82         if (elem == gq->tail) {
83                 gq->head = gq->tail = NULL;
84         }
85         else {
86                 gq->head = gq->head->next;
87         }
88         
89         if (item_r) memcpy(item_r, &elem[1], gq->elem_size);
90         MEM_freeN(elem);
91 }
92 void BLI_gsqueue_push(GSQueue *gq, void *item)
93 {
94         GSQueueElem *elem;
95         
96         /* compare: prevent events added double in row */
97         if (!BLI_gsqueue_is_empty(gq)) {
98                 if (0 == memcmp(item, &gq->head[1], gq->elem_size))
99                         return;
100         }
101         elem = MEM_mallocN(sizeof(*elem) + gq->elem_size, "gqueue_push");
102         memcpy(&elem[1], item, gq->elem_size);
103         elem->next = NULL;
104         
105         if (BLI_gsqueue_is_empty(gq)) {
106                 gq->tail = gq->head = elem;
107         }
108         else {
109                 gq->tail = gq->tail->next = elem;
110         }
111 }
112 void BLI_gsqueue_pushback(GSQueue *gq, void *item)
113 {
114         GSQueueElem *elem = MEM_mallocN(sizeof(*elem) + gq->elem_size, "gqueue_push");
115         memcpy(&elem[1], item, gq->elem_size);
116         elem->next = gq->head;
117
118         if (BLI_gsqueue_is_empty(gq)) {
119                 gq->head = gq->tail = elem;
120         }
121         else {
122                 gq->head = elem;
123         }
124 }
125
126 void BLI_gsqueue_free(GSQueue *gq)
127 {
128         while (gq->head) {
129                 BLI_gsqueue_pop(gq, NULL);
130         }
131         MEM_freeN(gq);
132 }
133
134