diff options
author | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
---|---|---|
committer | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
commit | abef6da56913f1c55528103e60a50451a39628b1 (patch) | |
tree | b3c8092471ecbb73e568cd0d336efa0e7871ee8d /src/Queue.c |
initial commit
Diffstat (limited to 'src/Queue.c')
-rw-r--r-- | src/Queue.c | 72 |
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 |