1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
#include "Core.h"
#include "Constants.h"
#include "Chat.h"
#include "Platform.h"
#include "Queue.h"
void Queue_Init(struct Queue* queue, cc_uint32 structSize) {
queue->entries = NULL;
queue->structSize = structSize;
queue->capacity = 0;
queue->mask = 0;
queue->count = 0;
queue->head = 0;
queue->tail = 0;
}
void Queue_Clear(struct Queue* queue) {
if (!queue->entries) return;
Mem_Free(queue->entries);
Queue_Init(queue, queue->structSize);
}
static void Queue_Resize(struct Queue* queue) {
cc_uint8* entries;
int capacity, headToEndSize, byteOffsetToHead;
if (queue->capacity >= (Int32_MaxValue / 4)) {
Chat_AddRaw("&cToo many generic queue entries, clearing");
Queue_Clear(queue);
return;
}
capacity = queue->capacity * 2;
if (capacity < 32) capacity = 32;
entries = (cc_uint8*)Mem_Alloc(capacity, queue->structSize, "Generic queue");
/* Elements must be readjusted to avoid index wrapping issues */
headToEndSize = (queue->capacity - queue->head) * queue->structSize;
byteOffsetToHead = queue->head * queue->structSize;
/* Copy from head to end */
Mem_Copy(entries, queue->entries + byteOffsetToHead, headToEndSize);
if (queue->head != 0) {
/* If there's any leftover before the head, copy that bit too */
Mem_Copy(entries + headToEndSize, queue->entries, byteOffsetToHead);
}
Mem_Free(queue->entries);
queue->entries = entries;
queue->capacity = capacity;
queue->mask = capacity - 1; /* capacity is power of two */
queue->head = 0;
queue->tail = queue->count;
}
/* Appends an entry to the end of the queue, resizing if necessary. */
void Queue_Enqueue(struct Queue* queue, void* item) {
if (queue->count == queue->capacity)
Queue_Resize(queue);
//queue->entries[queue->tail] = item;
Mem_Copy(queue->entries + queue->tail * queue->structSize, item, queue->structSize);
queue->tail = (queue->tail + 1) & queue->mask;
queue->count++;
}
/* Retrieves the entry from the front of the queue. */
void* Queue_Dequeue(struct Queue* queue) {
void* result = queue->entries + queue->head * queue->structSize;
queue->head = (queue->head + 1) & queue->mask;
queue->count--;
return result;
}
|