UFO: Alien Invasion
pqueue.cpp
Go to the documentation of this file.
1 
7 /*
8 Originally written by Justin-Heyes Jones
9 Modified by Shlomi Fish, 2000
10 Modified by Florian Festi, 2007
11 
12 This file is in the public domain (it's uncopyrighted).
13 
14 Bases on Justin-Heyes Jones' A* tutorial
15 */
16 
17 #include "common.h"
18 #include "pqueue.h"
19 
20 /* given an index to any element in a binary tree stored in a linear array with the root at 1 and
21  * a "sentinel" value at 0 these macros are useful in making the code clearer */
22 
23 /* the parent is always given by index/2 */
24 #define PQ_PARENT_INDEX(i) ((i)>>1)
25 #define PQ_FIRST_ENTRY (1)
26 
27 /* left and right children are index * 2 and (index * 2) +1 respectively */
28 #define PQ_LEFT_CHILD_INDEX(i) ((i)<<1)
29 #define PQ_RIGHT_CHILD_INDEX(i) (((i)<<1)+1)
30 #define PGetRating(elem) ((elem).rating)
31 
32 
36 void PQueueInitialise (priorityQueue_t* pq, uint32_t maxElements)
37 {
38  pq->maxSize = maxElements;
39  pq->currentSize = 0;
40 
41  pq->elements = Mem_AllocTypeN(priorityQueueElement_t, maxElements + 1);
42 
43  if (pq->elements == nullptr)
44  Sys_Error("PQueueInitialise: Memory alloc failed!");
45 }
46 
48 {
49  uint32_t currentSize = pq->currentSize;
50 
51  if (currentSize == pq->maxSize) {
52  const int new_size = pq->maxSize * 2;
53  pq->elements = (priorityQueueElement_t*)Mem_ReAlloc(pq->elements, sizeof(*pq->elements) * (new_size + 1));
54  pq->maxSize = new_size;
55  }
56 
57  /* set i to the first unused element and increment CurrentSize */
58  uint32_t i = (++currentSize);
59 
60  /* while the parent of the space we're putting the new node into is worse than
61  * our new node, swap the space with the worse node. We keep doing that until we
62  * get to a worse node or until we get to the top
63  * note that we also can sort so that the minimum elements bubble up so we need to loops
64  * with the comparison operator flipped... */
65 
66  while (i > PQ_FIRST_ENTRY && pq->elements[PQ_PARENT_INDEX(i)].rating > r) {
67  pq->elements[i] = pq->elements[PQ_PARENT_INDEX(i)];
68  i = PQ_PARENT_INDEX(i);
69  }
70 
71  /* then add the element at the space we created. */
72  for (int j = 0; j < 4; j++)
73  pq->elements[i].item[j] = item[j];
74 
75  pq->elements[i].rating = r;
76 
77  pq->currentSize = currentSize;
78 }
79 
84 {
85  Mem_Free(pq->elements);
86 }
87 
92 {
93 
94  if (PQueueIsEmpty(pq))
95  return;
96 
97  priorityQueueElement_t* elements = pq->elements;
98  const priorityQueueElement_t pMaxElement = elements[PQ_FIRST_ENTRY];
99 
100  /* get pointer to last element in tree */
101  uint32_t currentSize = pq->currentSize;
102  const priorityQueueElement_t pLastElement = elements[currentSize--];
103 
104  for (int j = 0; j < 4; j++)
105  item[j] = pMaxElement.item[j];
106 
107  uint32_t i;
108  uint32_t child;
109  for (i = PQ_FIRST_ENTRY; (child = PQ_LEFT_CHILD_INDEX(i)) <= currentSize; i = child) {
110  /* set child to the smaller of the two children... */
111 
112  if ((child != currentSize) && (elements[child + 1].rating < elements[child].rating))
113  child ++;
114 
115  if (pLastElement.rating > elements[child].rating)
116  elements[i] = elements[child];
117  else
118  break;
119  }
120 
121  elements[i] = pLastElement;
122  pq->currentSize = currentSize;
123 }
#define Mem_AllocTypeN(type, n)
Definition: mem.h:38
uint32_t maxSize
Definition: pqueue.h:40
void Sys_Error(const char *error,...)
Definition: g_main.cpp:421
#define Mem_ReAlloc(ptr, size)
Definition: mem.h:44
void PQueuePush(priorityQueue_t *pq, const pos4_t item, priorityQueueRating_t r)
Definition: pqueue.cpp:47
the priority queue struct the actual data is stored in priorityQueueElement_t
Definition: pqueue.h:39
#define PQ_FIRST_ENTRY
Definition: pqueue.cpp:25
void PQueueFree(priorityQueue_t *pq)
free up memory for pqueue
Definition: pqueue.cpp:83
int priorityQueueRating_t
Definition: pqueue.h:28
uint32_t currentSize
Definition: pqueue.h:41
pos_t pos4_t[4]
Definition: ufotypes.h:59
#define PQueueIsEmpty(pq)
Definition: pqueue.h:48
Header file for the priority queue implementation.
priorityQueueElement_t * elements
Definition: pqueue.h:42
#define PQ_LEFT_CHILD_INDEX(i)
Definition: pqueue.cpp:28
QGL_EXTERN GLint i
Definition: r_gl.h:113
#define PQ_PARENT_INDEX(i)
Definition: pqueue.cpp:24
#define Mem_Free(ptr)
Definition: mem.h:35
void PQueuePop(priorityQueue_t *pq, pos4_t item)
remove the first node from the pqueue and provide a pointer to it
Definition: pqueue.cpp:91
definitions common between client and server, but not game lib
priorityQueueRating_t rating
Definition: pqueue.h:32
void PQueueInitialise(priorityQueue_t *pq, uint32_t maxElements)
initialise the priority queue with a maximum size of maxelements.
Definition: pqueue.cpp:36