Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/priorityqueue.hpp
2 views
1
#ifndef NALL_PRIORITYQUEUE_HPP
2
#define NALL_PRIORITYQUEUE_HPP
3
4
#include <limits>
5
#include <nall/function.hpp>
6
#include <nall/serializer.hpp>
7
#include <nall/utility.hpp>
8
9
namespace nall {
10
template<typename type_t> void priority_queue_nocallback(type_t) {}
11
12
//priority queue implementation using binary min-heap array;
13
//does not require normalize() function.
14
//O(1) find (tick)
15
//O(log n) append (enqueue)
16
//O(log n) remove (dequeue)
17
template<typename type_t> class priority_queue {
18
public:
19
inline void tick(unsigned ticks) {
20
basecounter += ticks;
21
while(heapsize && gte(basecounter, heap[0].counter)) callback(dequeue());
22
}
23
24
//counter is relative to current time (eg enqueue(64, ...) fires in 64 ticks);
25
//counter cannot exceed std::numeric_limits<unsigned>::max() >> 1.
26
void enqueue(unsigned counter, type_t event) {
27
unsigned child = heapsize++;
28
counter += basecounter;
29
30
while(child) {
31
unsigned parent = (child - 1) >> 1;
32
if(gte(counter, heap[parent].counter)) break;
33
34
heap[child].counter = heap[parent].counter;
35
heap[child].event = heap[parent].event;
36
child = parent;
37
}
38
39
heap[child].counter = counter;
40
heap[child].event = event;
41
}
42
43
type_t dequeue() {
44
type_t event(heap[0].event);
45
unsigned parent = 0;
46
unsigned counter = heap[--heapsize].counter;
47
48
while(true) {
49
unsigned child = (parent << 1) + 1;
50
if(child >= heapsize) break;
51
if(child + 1 < heapsize && gte(heap[child].counter, heap[child + 1].counter)) child++;
52
if(gte(heap[child].counter, counter)) break;
53
54
heap[parent].counter = heap[child].counter;
55
heap[parent].event = heap[child].event;
56
parent = child;
57
}
58
59
heap[parent].counter = counter;
60
heap[parent].event = heap[heapsize].event;
61
return event;
62
}
63
64
void reset() {
65
basecounter = 0;
66
heapsize = 0;
67
}
68
69
void serialize(serializer &s) {
70
s.integer(basecounter);
71
s.integer(heapsize);
72
for(unsigned n = 0; n < heapcapacity; n++) {
73
s.integer(heap[n].counter);
74
s.integer(heap[n].event);
75
}
76
}
77
78
priority_queue(unsigned size, function<void (type_t)> callback_ = &priority_queue_nocallback<type_t>)
79
: callback(callback_) {
80
heap = new heap_t[size];
81
heapcapacity = size;
82
reset();
83
}
84
85
~priority_queue() {
86
delete[] heap;
87
}
88
89
priority_queue& operator=(const priority_queue&) = delete;
90
priority_queue(const priority_queue&) = delete;
91
92
private:
93
function<void (type_t)> callback;
94
unsigned basecounter;
95
unsigned heapsize;
96
unsigned heapcapacity;
97
struct heap_t {
98
unsigned counter;
99
type_t event;
100
} *heap;
101
102
//return true if x is greater than or equal to y
103
inline bool gte(unsigned x, unsigned y) {
104
return x - y < (std::numeric_limits<unsigned>::max() >> 1);
105
}
106
};
107
}
108
109
#endif
110
111