ScummVM API documentation
priqueue.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 *
21 * Based on the original sources
22 * Faery Tale II -- The Halls of the Dead
23 * (c) 1993-1996 The Wyrmkeep Entertainment Co.
24 */
25
26#ifndef SAGA2_PRIQUEUE_H
27#define SAGA2_PRIQUEUE_H
28
29namespace Saga2 {
30
31template <class ITEM, int size>
33 int16 _tail; // end index of queue
34 ITEM _queue[size + 1];
35
36 static int16 parentIndex(int16 index) {
37 return index >> 1;
38 }
39 static int16 child1Index(int16 index) {
40 return index << 1;
41 }
42 static int16 child2Index(int16 index) {
43 return (index >> 1) + 1;
44 }
45
46public:
47 PriorityQueue() { // constructor
48 _tail = 1;
49 }
50
51 bool insert(ITEM &newItem); // insert an item
52 bool remove(ITEM &result); // remove an item
53 void clear() {
54 _tail = 1; // clear the queue
55 }
56 int16 getCount() {
57 return _tail - 1;
58 }
59};
60
61// Function to insert an element into the queue
62
63template <class ITEM, int size>
64bool PriorityQueue<ITEM, size>::insert(ITEM &newItem) {
65 int16 index,
66 parentIndex,
67 newVal = (int)newItem;
68 ITEM *qi,
69 *parentItem;
70
71 if (_tail >= size + 1) return false;
72
73 for (index = _tail, qi = &_queue[index];
74 index > 1;
75 index = parentIndex, qi = parentItem) {
76 parentIndex = PriorityQueue::parentIndex(index);
77 parentItem = &_queue[parentIndex];
78
79 if ((int)*parentItem <= newVal) break;
80 *qi = *parentItem;
81 }
82 *qi = newItem;
83 _tail++;
84
85 return true;
86}
87
88// Function to remove the lowest element from the queue
89
90template <class ITEM, int size>
91bool PriorityQueue<ITEM, size>::remove(ITEM &result) {
92 ITEM *item = &_queue[1],
93 *child;
94 int16 itemNum = 1,
95 childNum,
96 tailVal;
97
98 if (_tail <= 1) return false;
99
100 result = *item;
101 _tail--;
102 tailVal = (int)_queue[_tail];
103
104 for (;;) {
105 childNum = child1Index(itemNum);
106 if (childNum >= _tail) break;
107
108 child = &_queue[childNum];
109
110 // Select the lowest of the two children
111 if (childNum + 1 < _tail
112 && (int)child[0] > (int)child[1]) {
113 childNum++;
114 child++;
115 }
116
117 if ((int)*child >= tailVal) break;
118 *item = *child;
119 item = child;
120 itemNum = childNum;
121 }
122
123 if (itemNum != _tail) {
124 *item = _queue[_tail];
125 }
126 return true;
127}
128
129} // end of namepsace Saga2
130
131#endif
Definition: priqueue.h:32