#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; }