summary refs log tree commit diff
path: root/src/Queue.c
diff options
context:
space:
mode:
authorWlodekM <[email protected]>2024-06-16 10:35:45 +0300
committerWlodekM <[email protected]>2024-06-16 10:35:45 +0300
commitabef6da56913f1c55528103e60a50451a39628b1 (patch)
treeb3c8092471ecbb73e568cd0d336efa0e7871ee8d /src/Queue.c
initial commit
Diffstat (limited to 'src/Queue.c')
-rw-r--r--src/Queue.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/Queue.c b/src/Queue.c
new file mode 100644
index 0000000..a363faf
--- /dev/null
+++ b/src/Queue.c
@@ -0,0 +1,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;
+}
\ No newline at end of file