#include "type.h" static_queue* static_queue_init(unsigned int data_size) { static_queue *q; q = (static_queue *)malloc(sizeof(static_queue)); assert(q); q->front = 0; q->rear = 0; q->size = 0; q->data_size = data_size; q->capacity = MAX_QUEUE_SIZE; q->data = (char *)malloc(q->capacity * q->data_size); assert(q->data); if (!q->data) { q->capacity = 0; } } int static_queue_push(static_queue *q, const void *value) { assert(q); if (q->size == q->capacity) { return -1; // Queue full } char *target = q->data + (q->rear * q->data_size); memcpy(target, value, q->data_size); q->rear = (q->rear + 1) % q->capacity; q->size++; return 0; } int static_queue_pop(static_queue *q, void *value) { assert(q); if (q->size == 0) { return -1; // Queue empty } const char *source = q->data + (q->front * q->data_size); memcpy(value, source, q->data_size); q->front = (q->front + 1) % q->capacity; q->size--; return 0; } void static_queue_destroy(static_queue *q) { assert(q); free(q->data); q->data = NULL; q->capacity = 0; q->size = 0; } /* DYNAMIC QUEUE */ void dynamic_queue_init(dynamic_queue *q, unsigned int data_size) { assert(q); q->front = 0; q->rear = 0; q->size = 0; q->data_size = data_size; q->capacity = MAX_QUEUE_SIZE; q->data = (char *)malloc(q->capacity * q->data_size); assert(q->data); if (!q->data) { // Handle allocation failure (e.g., set capacity to 0) q->capacity = 0; } } int dynamic_queue_push(dynamic_queue *q, const void *value) { assert(q); if (q->size == q->capacity) { return -1; // Queue full } char *target = q->data + (q->rear * q->data_size); memcpy(target, value, q->data_size); q->rear = (q->rear + 1) % q->capacity; q->size++; return 0; } int dynamic_queue_pop(dynamic_queue *q, void *value) { assert(q); if (q->size == 0) { return -1; // Queue empty } const char *source = q->data + (q->front * q->data_size); memcpy(value, source, q->data_size); q->front = (q->front + 1) % q->capacity; q->size--; return 0; } void dynamic_queue_destroy(dynamic_queue *q) { assert(q); free(q->data); q->data = NULL; q->capacity = 0; q->size = 0; } /* OCTREE */ octree_node* octree_node_create(float center[3], float extent) { octree_node* node = (octree_node*)malloc(sizeof(octree_node)); assert(node); memcpy(node->center, center, sizeof(float) * 3); node->extent = extent; node->child_mask = 0; node->data = 0x00; memset(node->children, 0, sizeof(octree_node *) * 8); return (node); } int octree_node_child_index(octree_node* node, float point[3]) { assert(node); int index = 0; if (point[0] >= node->center[0]) { index |= 1; } if (point[1] >= node->center[1]) { index |= 2; } if (point[2] >= node->center[2]) { index |= 4; } return (index); } bool octree_node_isleaf(octree_node* node, int index) { assert(node); return ((node->child_mask & (1 << index)) != 0); } octree_node* octree_node_get_or_create(octree_node* parent, int index) { assert(parent); if (parent->children[index]) { return (parent->children[index]); } float half = parent->extent * 0.5f; float child_center[3] = { parent->center[0] + ((index & 1) ? half : -half), parent->center[1] + ((index & 2) ? half : -half), parent->center[2] + ((index & 4) ? half : -half), }; octree_node* child = octree_node_create(child_center, half); assert(child); parent->children[index] = child; parent->child_mask |= (1 << index); return (child); } octree_node* octree_node_lookup(octree_node* root, float point[3]) { assert(root); octree_node* current = root; while(current) { int idx = octree_node_child_index(current, point); if (!octree_node_isleaf(current, idx)) { break; } current = current->children[idx]; } return (current); } void* octree_node_insert(octree_node* root, float point[3], void* data, float min_extent) { assert(root); octree_node* current = root; while(current->extent > min_extent) { int idx = octree_node_child_index(current, point); if (!octree_node_isleaf(current, idx) && !octree_node_get_or_create(current, idx)) { return (NULL); } current = current->children[idx]; } void* old_data = current->data; current->data = data; return (old_data); } void octree_node_free(octree_node *node) { if (!node) { return; } for (int i = 0; i < 8; i++) { if (node->children[i]) { node_free(node->children[i]); } } free(node); } octree_node* octree_traversal() { octree_node* node = 0x00; return (node); } bool octree_insert() { return (false); } void* octree_extract() { return (0x00); } octree* octree_init(const uint8_t max_depth) { octree* tree = 0x00; return (tree); } /* dynamic array */ void dynamic_array_add(dynamic_array *array, const void *element) { assert(array); if ((array->size + 1) * array->data_size >= array->capacity) { const uint32_t new_capacity = (unsigned int)(array->capacity * ARRAY_ALLOC_STEP); void *tmp = _aligned_malloc(new_capacity, array->alignement); assert(tmp); memcpy(tmp, array->data, array->size * array->data_size); _aligned_free(array->data); array->data = tmp; array->capacity = new_capacity; } memcpy((unsigned char *)array->data + array->size * array->data_size, element, array->data_size); array->size++; } void dynamic_array_del(dynamic_array *array, const unsigned int idx) { assert(array); if (idx >= array->size) return; memmove((unsigned char *)array->data + idx * array->data_size, (unsigned char *)array->data + (idx + 1) * array->data_size, (array->size - idx - 1) * array->data_size); array->size--; if (array->size * array->data_size < array->capacity * 0.5 && array->capacity > 8 * array->data_size) { const uint32_t new_capacity = (unsigned int)(array->capacity * 0.5); void *tmp = _aligned_malloc(new_capacity, array->alignement); assert(tmp); memcpy(tmp, array->data, array->size * array->data_size); _aligned_free(array->data); array->data = tmp; array->capacity = new_capacity; } } void dynamic_array_clear(dynamic_array *array) { assert(array); memset(array->data, 0, array->capacity); array->size = 0; } dynamic_array* dynamic_array_init(const char data_size, const size_t alignement) { dynamic_array* array = (dynamic_array *)malloc(sizeof(dynamic_array)); assert(array); array->data = _aligned_malloc(data_size * 8, array->alignement); assert(array->data); array->capacity = data_size * 8; array->data_size = data_size; array->size = 0; haven_darray_clear(array); return array; } void dynamic_array_destroy(dynamic_array* array) { assert(array); _aligned_free(array->data); free(array); } void dynamic_array_range_remove(dynamic_array* array, const uint32_t start, const uint32_t end) { assert(array); if (start >= array->size || end >= array->size || start > end) { return; } const uint32_t num_elements_to_remove = end - start + 1; memmove( (unsigned char *)array->data + start * array->data_size, (unsigned char *)array->data + (end + 1) * array->data_size, (array->size - end - 1) * array->data_size ); array->size -= num_elements_to_remove; if (array->size * array->data_size < array->capacity * 0.5 && array->capacity > 8 * array->data_size) { const uint32_t new_capacity = (unsigned int)(array->capacity * 0.5); void *tmp = _aligned_malloc(new_capacity, array->alignement); assert(tmp); memcpy(tmp, array->data, array->size * array->data_size); _aligned_free(array->data); array->data = tmp; array->capacity = new_capacity; } } void dynamic_array_sort(const dynamic_array *array, int (*comparator)(const void *, const void *)) { assert(array); qsort(array->data, array->size, array->data_size, comparator); } //return a pointer to data idx; void* dynamic_array_get(const dynamic_array *array, const uint32_t idx) { assert(array); void *ret = (unsigned char *)array->data + (idx * array->data_size); return (ret); } void dynamic_array_foreach(dynamic_array *array, void (*callback)(void *)) { assert(array); for (uint32_t i = 0; i < array->size; i++) { callback(haven_darray_get(array, i)); } }