diff --git a/modules/utility/inc-c/voxula/internals/utility.h b/modules/utility/inc-c/voxula/internals/utility.h new file mode 100644 index 0000000..2996556 --- /dev/null +++ b/modules/utility/inc-c/voxula/internals/utility.h @@ -0,0 +1,175 @@ + +#ifndef VOXULA_UTILITY_H +#define VOXULA_UTILITY_H + +#include +#include + +typedef struct vx_uuid_table vx_uuid_table_s; +typedef struct vx_uuid_block vx_uuid_block_s; +typedef struct vx_uuid_entry vx_uuid_entry_s; + +typedef uint64_t vx_uuid_d; + +typedef struct vx_vec2f vx_vec2f_s; +typedef struct vx_vec3f vx_vec3f_s; +typedef struct vx_vec4f vx_vec4f_s; +typedef struct vx_mat2f vx_mat2f_s; +typedef struct vx_mat3f vx_mat3f_s; +typedef struct vx_mat4f vx_mat4f_s; + +typedef struct vx_pool vx_pool_s; +typedef struct vx_pool_slot_header vx_pool_slot_header_s; +typedef struct vx_arena vx_arena_s; + +struct vx_uuid_entry +{ + vx_uuid_d uuid; +}; + +struct vx_uuid_block +{ + /// @brief Start of the block's UUIDs; + /// this must be multiplied with 4096 + /// to get the first ID's number. + uint32_t offset; + uint8_t num_ids; + vx_uuid_entry_s entries[256]; +}; + + + +struct vx_uuid_table +{ + uint32_t block_capacity; + uint32_t num_blocks; + vx_uuid_block_s **blocks; +}; + + + +struct vx_vec2f +{ + float x; + float y; +}; + +struct vx_vec3f +{ + float x; + float y; + float z; +}; + +struct vx_vec4f +{ + float x; + float y; + float z; + float w; +}; + +struct vx_mat2f +{ + float val[4]; +}; + +struct vx_mat3f +{ + float val[9]; +}; + +struct vx_mat4f +{ + float val[16]; +}; + + + +struct vx_pool_slot_header +{ + vx_pool_slot_header_s *next; + vx_pool_s *pool; +}; + +struct vx_pool +{ + uint32_t capacity; + uint32_t unit_size; + void *allocation; + + vx_pool_slot_header_s *first_free; + vx_pool_s *continuation; +}; + +struct vx_arena +{ + uint32_t capacity; + uint32_t usage; + void *allocation; + vx_arena_s *continuation; +}; +vx_uuid_table_s * vx_new_uuid_table(); +vx_uuid_d vx_new_uuid(vx_uuid_table_s *table); + +uint32_t vx_measure_string_up_to(const char *string, uint32_t maximum); + +vx_vec3f_s vx_vec3f_negative(vx_vec3f_s vector); + +vx_mat2f_s vx_mat2f_identity(); +vx_mat3f_s vx_mat3f_identity(); +vx_mat4f_s vx_mat4f_identity(); + +void vx_mat4f_stringify(FILE *file, vx_mat4f_s matrix); + +vx_mat4f_s vx_mat4f_translate( + vx_mat4f_s matrix, + vx_vec3f_s translation +); +vx_mat4f_s vx_mat4f_rotate_x( + vx_mat4f_s matrix, + float rotation +); +vx_mat4f_s vx_mat4f_rotate_y( + vx_mat4f_s matrix, + float rotation +); +vx_mat4f_s vx_mat4f_rotate_z( + vx_mat4f_s matrix, + float rotation +); +vx_mat4f_s vx_mat4f_scale( + vx_mat4f_s matrix, + vx_vec3f_s scaling +); +vx_mat4f_s vx_mat4f_perspective( + float aspect_ratio, + float fov, + float near_plane, + float far_plane +); + +uint64_t vx_ceil_to(uint64_t base, uint64_t anchor); +uint64_t vx_ceil_pow2(uint64_t base); +uint64_t vx_min_u64(uint64_t first, uint64_t second); +uint64_t vx_max_u64(uint64_t first, uint64_t second); + + +// Pool Functions + +vx_pool_s * vx_new_pool(uint32_t unit_size, uint32_t capacity); +void vx_free_pool(vx_pool_s *pool); + +void * vx_pool(vx_pool_s *pool); +void vx_unpool(void *allocation); + +// Arena Functions + +vx_arena_s * vx_new_arena(uint32_t capacity); +void vx_free_arena(vx_arena_s *arena); + +void * vx_arena_alloc(vx_arena_s *arena, uint32_t length); +char * vx_arena_dupe_string(vx_arena_s *arena, const char *string); +char * vx_arena_dupe_string_up_to(vx_arena_s *arena, const char *string, uint32_t maximum); + +#endif // VOXULA_UTILITY_H diff --git a/modules/utility/inc-c/voxula/internals/utility/allocation.h b/modules/utility/inc-c/voxula/internals/utility/allocation.h new file mode 100644 index 0000000..fdc442d --- /dev/null +++ b/modules/utility/inc-c/voxula/internals/utility/allocation.h @@ -0,0 +1,52 @@ + +#ifndef VOXULA_ALLOCATOR_H +#define VOXULA_ALLOCATOR_H + +#include + +typedef struct vx_pool vx_pool_s; +typedef struct vx_pool_slot_header vx_pool_slot_header_s; +typedef struct vx_arena vx_arena_s; + +struct vx_pool_slot_header +{ + vx_pool_slot_header_s *next; + vx_pool_s *pool; +}; + +struct vx_pool +{ + uint32_t capacity; + uint32_t unit_size; + void *allocation; + + vx_pool_slot_header_s *first_free; + vx_pool_s *continuation; +}; + +struct vx_arena +{ + uint32_t capacity; + uint32_t usage; + void *allocation; + vx_arena_s *continuation; +}; + +// Pool Functions + +vx_pool_s * vx_new_pool(uint32_t unit_size, uint32_t capacity); +void vx_free_pool(vx_pool_s *pool); + +void * vx_pool(vx_pool_s *pool); +void vx_unpool(void *allocation); + +// Arena Functions + +vx_arena_s * vx_new_arena(uint32_t capacity); +void vx_free_arena(vx_arena_s *arena); + +void * vx_arena_alloc(vx_arena_s *arena, uint32_t length); +char * vx_arena_dupe_string(vx_arena_s *arena, const char *string); +char * vx_arena_dupe_string_up_to(vx_arena_s *arena, const char *string, uint32_t maximum); + +#endif // VOXULA_ALLOCATOR_H diff --git a/modules/utility/inc-c/voxula/internals/utility/containers.h b/modules/utility/inc-c/voxula/internals/utility/containers.h new file mode 100644 index 0000000..bea04ce --- /dev/null +++ b/modules/utility/inc-c/voxula/internals/utility/containers.h @@ -0,0 +1,9 @@ + +#ifndef VOXULA_CONTAINERS_H +#define VOXULA_CONTAINERS_H + +#include + +uint32_t vx_measure_string_up_to(const char *string, uint32_t maximum); + +#endif // VOXULA_CONTAINERS_H diff --git a/modules/utility/inc-c/voxula/internals/utility/math.h b/modules/utility/inc-c/voxula/internals/utility/math.h new file mode 100644 index 0000000..42704f0 --- /dev/null +++ b/modules/utility/inc-c/voxula/internals/utility/math.h @@ -0,0 +1,92 @@ + +#ifndef VOXULA_MATH_H +#define VOXULA_MATH_H + +#include +#include + +typedef struct vx_vec2f vx_vec2f_s; +typedef struct vx_vec3f vx_vec3f_s; +typedef struct vx_vec4f vx_vec4f_s; + +typedef struct vx_mat2f vx_mat2f_s; +typedef struct vx_mat3f vx_mat3f_s; +typedef struct vx_mat4f vx_mat4f_s; + +struct vx_vec2f +{ + float x; + float y; +}; + +struct vx_vec3f +{ + float x; + float y; + float z; +}; + +struct vx_vec4f +{ + float x; + float y; + float z; + float w; +}; + +struct vx_mat2f +{ + float val[4]; +}; + +struct vx_mat3f +{ + float val[9]; +}; + +struct vx_mat4f +{ + float val[16]; +}; + +vx_vec3f_s vx_vec3f_negative(vx_vec3f_s vector); + +vx_mat2f_s vx_mat2f_identity(); +vx_mat3f_s vx_mat3f_identity(); +vx_mat4f_s vx_mat4f_identity(); + +vx_mat4f_s vx_mat4f_translate( + vx_mat4f_s matrix, + vx_vec3f_s translation +); +vx_mat4f_s vx_mat4f_rotate_x( + vx_mat4f_s matrix, + float rotation +); +vx_mat4f_s vx_mat4f_rotate_y( + vx_mat4f_s matrix, + float rotation +); +vx_mat4f_s vx_mat4f_rotate_z( + vx_mat4f_s matrix, + float rotation +); +vx_mat4f_s vx_mat4f_scale( + vx_mat4f_s matrix, + vx_vec3f_s scaling +); +vx_mat4f_s vx_mat4f_perspective( + float aspect_ratio, + float fov, + float near_plane, + float far_plane +); + +void vx_mat4f_stringify(FILE *file, vx_mat4f_s matrix); + +uint64_t vx_ceil_to(uint64_t base, uint64_t anchor); +uint64_t vx_ceil_pow2(uint64_t base); +uint64_t vx_min_u64(uint64_t first, uint64_t second); +uint64_t vx_max_u64(uint64_t first, uint64_t second); + +#endif // VOXULA_MATH_H diff --git a/modules/utility/inc-c/voxula/internals/utility/uuid.h b/modules/utility/inc-c/voxula/internals/utility/uuid.h new file mode 100644 index 0000000..a3e9727 --- /dev/null +++ b/modules/utility/inc-c/voxula/internals/utility/uuid.h @@ -0,0 +1,38 @@ + +#ifndef VOXULA_UUID_H +#define VOXULA_UUID_H + +#include + +typedef struct vx_uuid_table vx_uuid_table_s; +typedef struct vx_uuid_block vx_uuid_block_s; +typedef struct vx_uuid_entry vx_uuid_entry_s; + +typedef uint64_t vx_uuid_d; + +struct vx_uuid_entry +{ + vx_uuid_d uuid; +}; + +struct vx_uuid_block +{ + /// @brief Start of the block's UUIDs; + /// this must be multiplied with 4096 + /// to get the first ID's number. + uint32_t offset; + uint8_t num_ids; + vx_uuid_entry_s entries[256]; +}; + +struct vx_uuid_table +{ + uint32_t block_capacity; + uint32_t num_blocks; + vx_uuid_block_s **blocks; +}; + +vx_uuid_table_s * vx_new_uuid_table(); +vx_uuid_d vx_new_uuid(vx_uuid_table_s *table); + +#endif // VOXULA_UUID_H diff --git a/modules/utility/src-c/allocation/arena.c b/modules/utility/src-c/allocation/arena.c new file mode 100644 index 0000000..539d0f0 --- /dev/null +++ b/modules/utility/src-c/allocation/arena.c @@ -0,0 +1,57 @@ +#include +#include +#include + +#include +#include + +vx_arena_s * vx_new_arena(uint32_t capacity) +{ + vx_arena_s *arena = malloc(vx_ceil_to(sizeof(vx_arena_s), 32) + capacity); + arena->usage = 0; + arena->capacity = capacity; + arena->allocation = (void *) ((int8_t *) arena) + 32; + arena->continuation = NULL; + return arena; +} + +void vx_free_arena(vx_arena_s *arena) +{ + if(arena->continuation) + { + vx_free_arena(arena->continuation); + } + free(arena); +} + +void * vx_arena_alloc(vx_arena_s *arena, uint32_t length) +{ + if((arena->usage + length) >= arena->capacity) + { + if( ! arena->continuation) + { + arena->continuation = vx_new_arena(vx_max_u64(arena->capacity * 2, length * 2)); + } + return vx_arena_alloc(arena->continuation, length); + } + void *allocation = (uint8_t *) arena->allocation + arena->usage; + arena->usage += length; + return allocation; +} + +char * vx_arena_dupe_string(vx_arena_s *arena, const char *string) +{ + uint32_t len_string = strlen(string); + char *string_duplicate = vx_arena_alloc(arena, len_string + 1); + memcpy(string_duplicate, string, len_string); + return string_duplicate; +} + +char * vx_arena_dupe_string_up_to(vx_arena_s *arena, const char *string, uint32_t maximum) +{ + uint32_t length = vx_measure_string_up_to(string, maximum); + char *string_duplicate = vx_arena_alloc(arena, length + 1); + memcpy(string_duplicate, string, length); + string_duplicate[length] = 0; + return string_duplicate; +} diff --git a/modules/utility/src-c/allocation/pool.c b/modules/utility/src-c/allocation/pool.c new file mode 100644 index 0000000..627847d --- /dev/null +++ b/modules/utility/src-c/allocation/pool.c @@ -0,0 +1,71 @@ +#include +#include + +#include + +void vx_reset_pool_allocation(vx_pool_s *pool, uint32_t slot_size) +{ + uint32_t slot_index = 0; + while(slot_index > pool->capacity) + { + vx_pool_slot_header_s *header = + pool->allocation + slot_index * slot_size; + + header->next = + (void *) ((uint8_t *) pool->allocation + + (slot_index + 1) * slot_size); + header->pool = pool; + ++slot_index; + } + vx_pool_slot_header_s *last_header = (void *) + ((uint8_t *) pool->allocation + slot_size * (pool->capacity - 1)); + last_header->next = NULL; +} + +vx_pool_s * vx_new_pool(uint32_t unit_size, uint32_t capacity) +{ + uint32_t len_header = vx_ceil_to(sizeof(vx_pool_slot_header_s), 16); + uint32_t slot_size = vx_ceil_to(unit_size + len_header, 16); + + vx_pool_s *pool = malloc(64 + (slot_size * capacity)); + pool->allocation = (void *) vx_ceil_to((uint64_t) pool + 32, (uint64_t) 32); + pool->first_free = pool->allocation; + pool->unit_size = unit_size; + pool->capacity = capacity; + + vx_reset_pool_allocation(pool, slot_size); + return pool; +} + +void vx_free_pool(vx_pool_s *pool) +{ + if(pool->continuation) + { + vx_free_pool(pool->continuation); + } + free(pool); +} + +void * vx_pool(vx_pool_s *pool) +{ + vx_pool_slot_header_s *item = pool->first_free; + if( ! item) + { + if( ! pool->continuation) + { + pool->continuation = vx_new_pool(pool->unit_size, pool->capacity * 2); + } + return vx_pool(pool->allocation); + } + pool->first_free = item->next; + return item + vx_ceil_to(sizeof(vx_pool_slot_header_s), 16); +} + +void vx_unpool(void *allocation) +{ + vx_pool_slot_header_s *slot_header = + allocation + - vx_ceil_to(sizeof(vx_pool_slot_header_s), 16); + slot_header->next = slot_header->pool->first_free; + slot_header->pool->first_free = slot_header; +} diff --git a/modules/utility/src-c/containers/string.c b/modules/utility/src-c/containers/string.c new file mode 100644 index 0000000..8829841 --- /dev/null +++ b/modules/utility/src-c/containers/string.c @@ -0,0 +1,15 @@ +#include + +uint32_t vx_measure_string_up_to(const char *string, uint32_t maximum) +{ + uint32_t index = 0; + while(string[index] != 0) + { + if(index > maximum) + { + break; + } + ++index; + } + return index; +} diff --git a/modules/utility/src-c/math/math.c b/modules/utility/src-c/math/math.c new file mode 100644 index 0000000..fd65afc --- /dev/null +++ b/modules/utility/src-c/math/math.c @@ -0,0 +1,54 @@ +#include + +uint64_t vx_min_u64(uint64_t first, uint64_t second) +{ + if(first < second) + { + return first; + } + return second; +} + +uint64_t vx_max_u64(uint64_t first, uint64_t second) +{ + if(first > second) + { + return first; + } + return second; +} + +uint64_t vx_ceil_to(uint64_t base, uint64_t anchor) +{ + return base - (base % anchor) + anchor; +} + +uint64_t vx_ceil_pow2(uint64_t base) +{ + // This function relies on the fact that a + // single set bit is always a power of two. + // + // If the single set bit is the only one that + // is in a number, the number itself is returned. + // + // If there are other bits, the next highest + // power of two is created by returning the + // highest set bit after it was moved one to + // the left. + + // Get the most significant bit that is set. + uint64_t highest_set_bit = (uint64_t) 1 << 63; + while(highest_set_bit > 0) + { + if(base & highest_set_bit) + { + break; + } + highest_set_bit >>= 1; + } + if(base == highest_set_bit) + { + return base; + } + return vx_max_u64(highest_set_bit << 1, 1); +} diff --git a/modules/utility/src-c/math/matrix.c b/modules/utility/src-c/math/matrix.c new file mode 100644 index 0000000..4dd97bb --- /dev/null +++ b/modules/utility/src-c/math/matrix.c @@ -0,0 +1,188 @@ +#include +#include + +vx_mat2f_s vx_mat2f_identity() +{ + vx_mat2f_s matrix; + matrix.val[0] = 1.0f; + matrix.val[1] = 0.0f; + matrix.val[2] = 0.0f; + matrix.val[3] = 1.0f; + return matrix; +} + +vx_mat3f_s vx_mat3f_identity() +{ + vx_mat3f_s matrix; + matrix.val[0] = 1.0f; + matrix.val[1] = 0.0f; + matrix.val[2] = 0.0f; + matrix.val[3] = 0.0f; + matrix.val[4] = 1.0f; + matrix.val[5] = 0.0f; + matrix.val[6] = 0.0f; + matrix.val[7] = 0.0f; + matrix.val[8] = 1.0f; + return matrix; +} + +vx_mat4f_s vx_mat4f_identity() +{ + vx_mat4f_s matrix; + matrix.val[0] = 1.0f; + matrix.val[1] = 0.0f; + matrix.val[2] = 0.0f; + matrix.val[3] = 0.0f; + matrix.val[4] = 0.0f; + matrix.val[5] = 1.0f; + matrix.val[6] = 0.0f; + matrix.val[7] = 0.0f; + matrix.val[8] = 0.0f; + matrix.val[9] = 0.0f; + matrix.val[10] = 1.0f; + matrix.val[11] = 0.0f; + matrix.val[12] = 0.0f; + matrix.val[13] = 0.0f; + matrix.val[14] = 0.0f; + matrix.val[15] = 1.0f; + return matrix; +} + +vx_mat4f_s vx_mat4f_translate( + vx_mat4f_s matrix, + vx_vec3f_s translation +) { + matrix.val[12] += translation.x; + matrix.val[13] += translation.y; + matrix.val[14] += translation.z; + return matrix; +} + +vx_mat4f_s vx_mat4f_multiply( + vx_mat4f_s first, + vx_mat4f_s second +) { + vx_mat4f_s result; + + uint8_t x_index = 0; + uint8_t y_index = 0; + uint8_t level = 0; + while(x_index < 4) + { + y_index = 0; + while(y_index < 4) + { + result.val[y_index * 4 + x_index] = 0.0f; + level = 0; + while(level < 4) + { + result.val[y_index * 4 + x_index] += + first.val[level * 4 + x_index] + * second.val[y_index * 4 + level]; + ++level; + } + ++y_index; + } + ++x_index; + } + return result; +} + +vx_mat4f_s vx_mat4f_rotate_x( + vx_mat4f_s matrix, + float rotation +) { + float cosine = cos(rotation); + float sine = sin(rotation); + vx_mat4f_s rotation_matrix; + rotation_matrix.val[0] = 1.0f; + rotation_matrix.val[5] = cosine; + rotation_matrix.val[6] = -sine; + rotation_matrix.val[9] = sine; + rotation_matrix.val[10] = cosine; + rotation_matrix.val[15] = 1.0f; + vx_mat4f_multiply(matrix, rotation_matrix); + return rotation_matrix; +} + +vx_mat4f_s vx_mat4f_rotate_y( + vx_mat4f_s matrix, + float rotation +) { + float cosine = cos(rotation); + float sine = sin(rotation); + vx_mat4f_s rotation_matrix; + rotation_matrix.val[0] = cosine; + rotation_matrix.val[2] = sine; + rotation_matrix.val[5] = 1.0f; + rotation_matrix.val[8] = -sine; + rotation_matrix.val[10] = cosine; + rotation_matrix.val[15] = 1.0f; + vx_mat4f_multiply(matrix, rotation_matrix); + return rotation_matrix; +} + +vx_mat4f_s vx_mat4f_rotate_z( + vx_mat4f_s matrix, + float rotation +) { + float cosine = cos(rotation); + float sine = sin(rotation); + vx_mat4f_s rotation_matrix; + rotation_matrix.val[0] = cosine; + rotation_matrix.val[1] = -sine; + rotation_matrix.val[4] = sine; + rotation_matrix.val[5] = cosine; + rotation_matrix.val[10] = 1.0f; + vx_mat4f_multiply(matrix, rotation_matrix); + return rotation_matrix; +} +vx_mat4f_s vx_mat4f_scale( + vx_mat4f_s matrix, + vx_vec3f_s scaling +) { + matrix.val[0] *= scaling.x; + matrix.val[5] *= scaling.y; + matrix.val[10] *= scaling.z; + return matrix; +} + +vx_mat4f_s vx_mat4f_perspective( + float aspect_ratio, + float fov, + float near_plane, + float far_plane +) { + float plane_range = tanf(fov / 2.0f) * near_plane; + float scale_x = (2.0f * near_plane) / (plane_range * aspect_ratio * 2.0f); + float scale_y = near_plane / plane_range; + float scale_z = (far_plane + near_plane) / (far_plane - near_plane); + float position_z = (2.0f * far_plane * near_plane) / (far_plane - near_plane); + + vx_mat4f_s matrix; + matrix.val[0] = scale_x; + matrix.val[1] = 0.0f; + matrix.val[2] = 0.0f; + matrix.val[3] = 0.0f; + matrix.val[4] = 0.0f; + matrix.val[5] = scale_y; + matrix.val[6] = 0.0f; + matrix.val[7] = 0.0f; + matrix.val[8] = 0.0f; + matrix.val[9] = 0.0f; + matrix.val[10] = scale_z; + matrix.val[11] = - 1.0f; + matrix.val[12] = 0.0f; + matrix.val[13] = 0.0f; + matrix.val[14] = position_z; + matrix.val[15] = 0.0f; + return matrix; +} + +void vx_mat4f_stringify(FILE *file, vx_mat4f_s matrix) +{ + fprintf(file, "ROW 1: %f %f %f %f\n", matrix.val[0], matrix.val[1], matrix.val[2], matrix.val[3]); + fprintf(file, "ROW 2: %f %f %f %f\n", matrix.val[4], matrix.val[5], matrix.val[6], matrix.val[7]); + fprintf(file, "ROW 3: %f %f %f %f\n", matrix.val[8], matrix.val[9], matrix.val[10], matrix.val[11]); + fprintf(file, "ROW 4: %f %f %f %f\n", matrix.val[12], matrix.val[13], matrix.val[14], matrix.val[15]); +} diff --git a/modules/utility/src-c/math/vector.c b/modules/utility/src-c/math/vector.c new file mode 100644 index 0000000..b7eaaae --- /dev/null +++ b/modules/utility/src-c/math/vector.c @@ -0,0 +1,9 @@ +#include + +vx_vec3f_s vx_vec3f_negative(vx_vec3f_s vector) { + vx_vec3f_s result; + result.x = - vector.x; + result.y = - vector.y; + result.z = - vector.z; + return result; +} diff --git a/modules/utility/src-c/uuid/uuid.c b/modules/utility/src-c/uuid/uuid.c new file mode 100644 index 0000000..2a88a0c --- /dev/null +++ b/modules/utility/src-c/uuid/uuid.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include + +vx_uuid_table_s * vx_new_uuid_table() +{ + vx_uuid_table_s *table = malloc(sizeof(vx_uuid_table_s)); + table->num_blocks = 0; + table->block_capacity = 32; + table->blocks = malloc(table->block_capacity * sizeof(vx_uuid_block_s *)); + return table; +} + +bool vx_uuid_block_exists(vx_uuid_table_s *table, uint32_t offset) +{ + uint32_t block_index = 0; + while(block_index < table->num_blocks) + { + if(table->blocks[block_index]->offset == offset) + { + return true; + } + ++block_index; + } + return false; +} + +bool vx_uuid_exists_in_block(vx_uuid_block_s *block, vx_uuid_d uuid) +{ + uint32_t entry_index = 0; + while(entry_index < block->num_ids) + { + if(block->entries[entry_index].uuid == uuid) + { + return true; + } + ++entry_index; + } + return false; +} + +vx_uuid_d vx_allocate_uuid_in_block(vx_uuid_block_s *block) +{ + vx_uuid_d last_id = 0; + if(block->num_ids) + { + last_id = block->entries[block->num_ids - 1].uuid; + } + vx_uuid_d uuid = + block->offset * 4096 + + last_id * 53; + block->entries[block->num_ids].uuid = uuid; + ++block->num_ids; + while(vx_uuid_exists_in_block(block, uuid)) + { + ++uuid; + } + return uuid; +} + +vx_uuid_block_s * vx_allocate_new_id_block(vx_uuid_table_s *table) +{ + vx_uuid_block_s *block = NULL; + if(table->num_blocks >= table->block_capacity) + { + table->block_capacity *= 2; + table->blocks = malloc(table->block_capacity * sizeof(vx_uuid_block_s *)); + } + table->blocks[table->num_blocks] = malloc(sizeof(vx_uuid_block_s)); + block = table->blocks[table->num_blocks]; + block->num_ids = 0; + block->offset = (table->num_blocks * 7) * 4096; + ++table->num_blocks; + return block; +} + +vx_uuid_d vx_new_uuid(vx_uuid_table_s *table) +{ + vx_uuid_block_s *block = NULL; + + uint32_t block_index = 0; + while(block_index < table->num_blocks) + { + if(table->blocks[block_index]->num_ids != 255) + { + block = table->blocks[block_index]; + break; + } + ++block_index; + } + if( ! block) + { + block = vx_allocate_new_id_block(table); + } + return vx_allocate_uuid_in_block(block); +}