A small OpenGL 3+ renderer and game engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

194 lines
3.7 KiB

#ifndef UTIL_H
#define UTIL_H
#include <cassert>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include "dumbLog.h"
#include "types.h"
//-----------------
// Hashing
// NOTE: FNV1a hashing algorithm http://www.isthe.com/chongo/tech/comp/fnv/
#define FNV1_64_INIT ((u64) 0xcbf29ce484222325ULL)
#define FNV_64_PRIME ((u64) 0x100000001b3ULL)
u64 utilFNV64a_str(const char* str, u64 hval = FNV1_64_INIT);
//-----------------
// Memory allocation
struct MemoryArena
{
size_t max_size;
size_t free_size;
void* head;
void* next_free;
};
#define DEFAULT_ARENA_SIZE 10 * 1024 * 1024 // 10MB
MemoryArena* arenaInit(size_t initial_size = DEFAULT_ARENA_SIZE);
void arenaFree(MemoryArena*& arena);
u32 arenaGetFreeSize(MemoryArena* arena);
#define ARENA_ALLOC(arena, type, count) \
(type*) arenaAllocateBlock(arena, sizeof(type) * count)
void* arenaAllocateBlock(MemoryArena* arena, size_t block_size);
void* arenaGetAddressOffset(void* address, u32 offset);
#define MAX_NAME_LENGTH 256
char* arenaCopyCStr(MemoryArena* arena,
const char* input,
u32 max_len = MAX_NAME_LENGTH);
#define UTIL_ALLOC(count, type) (type*) utilAllocate(count, sizeof(type))
void* utilAllocate(u32 count, u32 type_size);
char* utilAllocateCStr(const char* str, u32 max_len = 256);
void utilSafeFree(void* p);
//---------------
// C string utils
bool utilCStrMatch(const char* str1, const char* str2);
#endif // UTIL_H
#ifdef UTIL_IMPLEMENTATION
//-----------------
// Hashing
u64
utilFNV64a_str(const char* str, u64 hval)
{
unsigned char* s = (unsigned char *)str; // unsigned string
// FNV-1a hash each octet of the string
while (*s) {
// xor the bottom with the current octet
hval ^= (uint64_t)*s++;
// multiply by the 64 bit FNV magic prime mod 2^64
hval *= FNV_64_PRIME;
}
return hval;
}
//-----------------
// Memory allocation
MemoryArena*
arenaInit(size_t initial_size)
{
u32 sz = sizeof(MemoryArena);
MemoryArena* arena =
(MemoryArena*) std::calloc(initial_size + sz, sizeof(u8));
arena->head = arena->next_free = (uint8_t*) arena + sz;
arena->max_size = initial_size;
return arena;
}
void
arenaFree(MemoryArena*& arena)
{
if (arena != nullptr) {
std::free(arena);
arena = nullptr;
}
}
uint
arenaGetFreeSize(MemoryArena* arena)
{
return (uint8_t*) arena->head
+ arena->max_size
- (uint8_t*) arena->next_free;
}
void*
arenaAllocateBlock(MemoryArena* arena, size_t block_size)
{
// TODO: resizable memory arena
assert(arenaGetFreeSize(arena) >= block_size);
assert(block_size > 0);
void* ret = arena->next_free;
arena->next_free = (uint8_t*) arena->next_free + block_size;
arena->free_size = arenaGetFreeSize(arena);
return ret;
}
void*
arenaGetAddressOffset(void* address, u32 offset)
{
return (void*) ((u8*) address + offset);
}
char*
arenaCopyCStr(MemoryArena* arena, const char* input, u32 max_len)
{
u32 name_len = std::strlen(input) + 1;
assert(name_len > 1 && name_len < max_len);
char* out = ARENA_ALLOC(arena, char, name_len);
std::strncpy(out, input, name_len);
return out;
}
void*
utilAllocate(u32 count, u32 type_size)
{
void* out = std::calloc(count, type_size);
assert(out != nullptr);
return out;
}
char*
utilAllocateCStr(const char* str, u32 max_len)
{
u32 len = strlen(str) + 1;
if (len > max_len) {
LOGF(Error, "%s , longer than %i\n", str, max_len);
return nullptr;
}
char* out = (char*) std::calloc(len, sizeof(u8));
strncpy(out, str, len - 1);
return out;
}
void
utilSafeFree(void* p)
{
if (p)
free(p);
else
LOGF(Error, "free called on nullptr\n");
}
//---------------
// C string utils
bool
utilCStrMatch(const char* str1, const char* str2)
{
if (!str1 || !str2)
return false;
u32 l1 = strlen(str1);
u32 l2 = strlen(str2);
return (l1 == l2 && strncmp(str1, str2, l1) == 0);
}
#endif