You've already forked flecs_tests
Add shapes and basic selective actions
This commit is contained in:
266
src/util.h
266
src/util.h
@@ -1,241 +1,61 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include "api.h"
|
||||
|
||||
/*typedef struct linked_list_t {
|
||||
linked_item_t *first, *last;
|
||||
uint16_t size;
|
||||
} linked_list_t;
|
||||
|
||||
typedef struct linked_item_t {
|
||||
linked_item_t *next, *prev;
|
||||
void *data;
|
||||
} linked_item_t;
|
||||
|
||||
typedef void (*linked_list_callback)(void *item);
|
||||
|
||||
//Currently, these are the only method required.
|
||||
//Many more could be implemented but this is unnecessary.
|
||||
static void l_list_push(linked_list_t *l_list, void *item);
|
||||
static void l_list_append(linked_list_t *l_list, void *item);
|
||||
static void* l_list_pop(linked_list_t *l_list);
|
||||
static void* l_list_unppend(linked_list_t *l_list);
|
||||
static void l_list_each(linked_list_t *l_list, linked_list_callback callback);
|
||||
|
||||
static inline void l_list_push(linked_list_t *l_list, void *item)
|
||||
{
|
||||
linked_item_t l_item = (linked_item_t) { .data = item, .prev = l_list->last, .next = nullptr };
|
||||
|
||||
if(l_list->first == nullptr)
|
||||
l_list->first = &l_item;
|
||||
|
||||
l_list->last->next = &l_item;
|
||||
l_list->last = &l_item;
|
||||
l_list->size++;
|
||||
}
|
||||
static inline void l_list_append(linked_list_t *l_list, void *item)
|
||||
{
|
||||
linked_item_t l_item = (linked_item_t) { .data = item, .prev = nullptr, .next = l_list->last };
|
||||
|
||||
if(l_list->last == nullptr)
|
||||
l_list->last = &l_item;
|
||||
|
||||
l_list->first->prev = &l_item;
|
||||
l_list->first = &l_item;
|
||||
l_list->size++;
|
||||
}
|
||||
static inline void* l_list_pop(linked_list_t *l_list)
|
||||
{
|
||||
if(l_list->last == nullptr)
|
||||
return;
|
||||
|
||||
if(l_list->first == l_list->last)
|
||||
l_list->first = nullptr;
|
||||
|
||||
linked_item_t *item = l_list->last->prev;
|
||||
l_list->last->prev = nullptr;
|
||||
l_list->last = item;
|
||||
l_list->size--;
|
||||
}
|
||||
static inline void* l_list_unppend(linked_list_t *l_list)
|
||||
{
|
||||
if(l_list->first == nullptr)
|
||||
return;
|
||||
|
||||
if(l_list->last == l_list->first)
|
||||
l_list->last = nullptr;
|
||||
|
||||
linked_item_t *item = l_list->first->next;
|
||||
l_list->first->next = nullptr;
|
||||
l_list->first = item;
|
||||
l_list->size--;
|
||||
}
|
||||
static inline void l_list_each(linked_list_t *l_list, linked_list_callback callback)
|
||||
{
|
||||
|
||||
}*/
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct vector_t {
|
||||
void **data; //Memory pool
|
||||
uint16_t stripe; //Bit per item
|
||||
uint32_t size; //Current amount of items
|
||||
uint32_t capacity; //Max capacity
|
||||
uint8_t *data;
|
||||
int count;
|
||||
int capacity;
|
||||
int stride;
|
||||
} vector_t;
|
||||
|
||||
#define MAX_BUCKET_SIZE (0xffffffffu)
|
||||
#define MAX_STRIPE_SIZE (0xffffffu)
|
||||
#define FIXED_START (0xfffu)
|
||||
|
||||
static vector_t vector_create(uint32_t stripe); //Create a new vector with a default size
|
||||
static void vector_clear(vector_t *vector);
|
||||
static void vector_free(vector_t *vector);
|
||||
|
||||
static uint32_t vector_length(vector_t *vector);
|
||||
static void* vector_get(vector_t *vector, uint32_t index);
|
||||
static void vector_set(vector_t *vector, uint32_t index, void *data);
|
||||
static uint32_t vector_push(vector_t *vector, void *data);
|
||||
static sg_range vector_range(vector_t *vector);
|
||||
|
||||
static vector_t vector_create(uint32_t stripe)
|
||||
{
|
||||
assert(stripe >= sizeof(uint32_t));
|
||||
assert(stripe <= MAX_STRIPE_SIZE);
|
||||
assert(FIXED_START * stripe <= MAX_BUCKET_SIZE);
|
||||
|
||||
return (vector_t) {
|
||||
.capacity = FIXED_START,
|
||||
.size = 0,
|
||||
.stripe = stripe,
|
||||
.data = (void**) malloc(FIXED_START * stripe),
|
||||
};
|
||||
}
|
||||
static void vector_clear(vector_t *vector)
|
||||
{
|
||||
vector->size = 0;
|
||||
}
|
||||
static void vector_free(vector_t *vector)
|
||||
{
|
||||
free(vector->data);
|
||||
static void vec_init(vector_t *v, int stride) {
|
||||
memset(v, 0, sizeof(*v));
|
||||
v->stride = stride;
|
||||
}
|
||||
|
||||
static uint32_t vector_length(vector_t *vector)
|
||||
{
|
||||
return vector->size;
|
||||
}
|
||||
static void* vector_get(vector_t *vector, uint32_t index)
|
||||
{
|
||||
assert(index > 0);
|
||||
assert(index < vector->size);
|
||||
|
||||
return vector->data[index * vector->stripe];
|
||||
}
|
||||
static void vector_set(vector_t *vector, uint32_t index, void *data)
|
||||
{
|
||||
assert(index > 0);
|
||||
assert(index < vector->size);
|
||||
|
||||
vector->data[index * vector->stripe] = data;
|
||||
}
|
||||
static uint32_t vector_push(vector_t *vector, void *data)
|
||||
{
|
||||
if(vector->size >= vector->capacity)
|
||||
{
|
||||
vector->capacity *= 2;
|
||||
|
||||
vector->data = (void**) realloc(vector->data, vector->capacity * vector->stripe);
|
||||
static void vec_grow(vector_t *v, int min_capacity) {
|
||||
int new_cap = v->capacity ? v->capacity * 2 : 8;
|
||||
if (new_cap < min_capacity) new_cap = min_capacity;
|
||||
uint8_t *new_data = (uint8_t*) ALLOC(new_cap * v->stride);
|
||||
if (v->data) {
|
||||
memcpy(new_data, v->data, v->count * v->stride);
|
||||
FREE(v->data);
|
||||
}
|
||||
|
||||
return vector->size++;
|
||||
}
|
||||
static sg_range vector_range(vector_t *vector)
|
||||
{
|
||||
return (sg_range) {
|
||||
.ptr = vector->data,
|
||||
.size = vector->size,
|
||||
};
|
||||
v->data = new_data;
|
||||
v->capacity = new_cap;
|
||||
}
|
||||
|
||||
typedef struct mem_pool_t {
|
||||
void **data; //Memory pool
|
||||
uint32_t stripe; //Bit per item
|
||||
uint32_t size; //Current amount of items
|
||||
uint32_t capacity; //Max capacity
|
||||
uint32_t free; //Linked list of available indices
|
||||
} mem_pool_t;
|
||||
|
||||
static mem_pool_t pool_create_default(uint32_t stripe); //Create a new memory pool with a default size
|
||||
static mem_pool_t pool_create(uint32_t stripe, uint32_t size); //Create a new memory pool with a default size
|
||||
static void pool_clear(mem_pool_t *pool);
|
||||
static void pool_free(mem_pool_t *pool);
|
||||
|
||||
static const uint32_t pool_add(mem_pool_t *pool); //Request a new free index
|
||||
static const void* pool_get(mem_pool_t *pool, uint32_t index); //Get the pointer
|
||||
static void pool_remove(mem_pool_t *pool, uint32_t index); //Flag the given index as free
|
||||
|
||||
static mem_pool_t pool_create_default(uint32_t stripe)
|
||||
{
|
||||
return pool_create(stripe, FIXED_START);
|
||||
}
|
||||
static mem_pool_t pool_create(uint32_t stripe, uint32_t size)
|
||||
{
|
||||
assert(stripe >= sizeof(uint32_t));
|
||||
assert(stripe <= MAX_STRIPE_SIZE);
|
||||
assert(size * stripe <= MAX_BUCKET_SIZE);
|
||||
|
||||
return (mem_pool_t) {
|
||||
.capacity = size,
|
||||
.size = 0,
|
||||
.stripe = stripe,
|
||||
.free = UINT32_MAX,
|
||||
.data = (void**) malloc(size * stripe),
|
||||
};
|
||||
}
|
||||
static void pool_clear(mem_pool_t *pool)
|
||||
{
|
||||
pool->size = 0;
|
||||
pool->free = UINT32_MAX;
|
||||
}
|
||||
static void pool_free(mem_pool_t *pool)
|
||||
{
|
||||
free(pool->data);
|
||||
static void *vec_push(vector_t *v) {
|
||||
if (v->count >= v->capacity) vec_grow(v, v->count + 1);
|
||||
return v->data + (v->count++) * v->stride;
|
||||
}
|
||||
|
||||
static const uint32_t pool_add(mem_pool_t *pool)
|
||||
{
|
||||
if(pool->free != UINT32_MAX)
|
||||
{
|
||||
const uint32_t index = pool->free;
|
||||
static void vec_pop(vector_t *v) {
|
||||
if (v->count > 0) v->count--;
|
||||
}
|
||||
|
||||
pool->free = (uint32_t) pool->data[index * pool->stripe];
|
||||
|
||||
return index;
|
||||
static void vec_remove(vector_t *v, int index) {
|
||||
if (index < 0 || index >= v->count) return;
|
||||
if (index < v->count - 1) {
|
||||
memcpy(v->data + index * v->stride,
|
||||
v->data + (v->count - 1) * v->stride,
|
||||
v->stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pool->size >= pool->capacity)
|
||||
{
|
||||
pool->capacity *= 2;
|
||||
|
||||
pool->data = (void**) realloc(pool->data, pool->capacity * pool->stripe);
|
||||
}
|
||||
|
||||
return pool->size++;
|
||||
}
|
||||
}
|
||||
static const void* pool_get(mem_pool_t *pool, uint32_t index)
|
||||
{
|
||||
assert(index > 0);
|
||||
assert(index < pool->capacity);
|
||||
|
||||
return pool->data[index * pool->stripe];
|
||||
}
|
||||
static void pool_remove(mem_pool_t *pool, uint32_t index)
|
||||
{
|
||||
const uint32_t pos = index * pool->stripe;
|
||||
|
||||
pool->data[pos] = (void*) pool->free;
|
||||
pool->free = index;
|
||||
v->count--;
|
||||
}
|
||||
|
||||
#endif
|
||||
static void *vec_get(vector_t *v, int index) {
|
||||
return v->data + index * v->stride;
|
||||
}
|
||||
|
||||
static void vec_free(vector_t *v) {
|
||||
if (v->data) FREE(v->data);
|
||||
v->data = NULL;
|
||||
v->count = 0;
|
||||
v->capacity = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user