diff options
author | Danny Holman <dholman@gymli.org> | 2025-08-04 12:32:39 -0500 |
---|---|---|
committer | Danny Holman <dholman@gymli.org> | 2025-08-04 12:32:39 -0500 |
commit | 7a268ae92d44a9f27f4874e1e50413ee33b86dd3 (patch) | |
tree | 47574f2a1d6c6d469e19627aacbcae03ae615dee /core | |
parent | render: vulkan: add check for null pointer for debug (diff) | |
download | rune-engine-7a268ae92d44a9f27f4874e1e50413ee33b86dd3.tar.gz rune-engine-7a268ae92d44a9f27f4874e1e50413ee33b86dd3.tar.zst rune-engine-7a268ae92d44a9f27f4874e1e50413ee33b86dd3.zip |
root: restructuring
Restructure the root of the project such that the engine is siloed from
the rest of the toolchain. Add two new subdirectories that contain an
editor and an offline profiling data analyzer.
Signed-off-by: Danny Holman <dholman@gymli.org>
Diffstat (limited to 'core')
-rw-r--r-- | core/abort.c | 93 | ||||
-rw-r--r-- | core/alloc.c | 157 | ||||
-rw-r--r-- | core/callbacks.c | 27 | ||||
-rw-r--r-- | core/init.c | 37 | ||||
-rw-r--r-- | core/logging.c | 114 | ||||
-rw-r--r-- | core/mod.c | 90 | ||||
-rw-r--r-- | core/thread.c | 218 |
7 files changed, 0 insertions, 736 deletions
diff --git a/core/abort.c b/core/abort.c deleted file mode 100644 index 5ee42f6..0000000 --- a/core/abort.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/abort.h> -#include <rune/core/alloc.h> -#include <rune/core/init.h> -#include <rune/core/logging.h> -#include <rune/util/exits.h> -#include <stdlib.h> - -#define MAX_TRACE_ITEMS 30 - -#ifdef _WIN32 - -#include <windows.h> -#include <dbghelp.h> - -void _stack_trace(void) { - void* buffer[MAX_TRACE_ITEMS]; - HANDLE process = GetCurrentProcess(); - - SymInitialize(process, NULL, TRUE); - int num_links = CaptureStackBackTrace(0, MAX_TRACE_ITEMS, buffer, NULL); - SYMBOL_INFO *symbol = (SYMBOL_INFO*)rune_alloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char)); - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol->MaxNameLen = 255; - - for (int i = 0; i < num_links; i++) { - SymFromAddr(process, (DWORD64)(buffer[i]), 0, symbol); - log_output(LOG_INFO, "#%d: %s", i, symbol->Name, symbol->Address); - } - - rune_free(symbol); - SymCleanup(process); -} - -#else - -#include <execinfo.h> - -void _stack_trace(void) { - void* buffer[MAX_TRACE_ITEMS]; - int num_links = backtrace(buffer, MAX_TRACE_ITEMS); - char** symbuf = backtrace_symbols(buffer, num_links); - - for (int i = 0; i < num_links; i++) - log_output(LOG_INFO, "#%d: %s", i, symbuf[i]); - - free(symbuf); -} - -#endif - -NORET void rune_abort(void) { - log_output(LOG_INFO, "Abort called, printing stack trace"); - _stack_trace(); - rune_exit(); - exit(REXIT_FAIL); -} - -#ifdef MSVC - -NORET void __security_error_handler(void) { - log_output(LOG_FATAL, "Stack smashing detected in engine code"); - rune_abort(); -} - -#else - -NORET void __stack_chk_fail(void) { - log_output(LOG_FATAL, "Stack smashing detected in engine code"); - rune_abort(); -} - -#endif diff --git a/core/alloc.c b/core/alloc.c deleted file mode 100644 index 0ed705c..0000000 --- a/core/alloc.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/alloc.h> -#include <rune/core/logging.h> -#include <stdlib.h> -#include <string.h> - -// TODO: implement block coalescing so we can reuse freed blocks - -#define DEADBLOCK ((void*)0xDEADBEEF) - -static mem_block_t first_block; - -static mem_block_t* _find_free_block(size_t sz) { - list_head_t *temp = &first_block.list; - mem_block_t *block; - while (temp != NULL) { - block = (mem_block_t*)((void*)temp - offsetof(mem_block_t, list)); - if (block->sz == sz && block->free == 1) - return block; - temp = temp->next; - } - return NULL; -} - -static mem_block_t* _find_block(void *ptr) { - list_head_t *temp = &first_block.list; - mem_block_t *block; - while (temp != NULL) { - block = (mem_block_t*)((void*)temp - offsetof(mem_block_t, list)); - if (block->ptr == ptr) - return block; - temp = temp->next; - } - return NULL; -} - -static mem_block_t* _alloc_block(size_t sz) { - if (first_block.ptr == NULL) { - first_block.ptr == DEADBLOCK; - first_block.sz = 0; - } - - mem_block_t *ret = _find_free_block(sz); - if (ret != NULL) { - ret->free = 0; - return ret->ptr; - } - - ret = malloc(sizeof(mem_block_t)); - if (ret == NULL) { - log_output(LOG_ERROR, "Cannot allocate block of size %d", sz); - return NULL; - } - - ret->ptr = malloc(sz); - ret->sz = sz; - ret->free = 0; - list_add(&ret->list, &first_block.list); - log_output(LOG_DEBUG, "Alloc'd block of size %d", sz); - return ret; -} - -static void _free_block(mem_block_t *block, int hard) { - if (hard == 1) { - list_del(&block->list); - log_output(LOG_DEBUG, "Freed block of size %d", block->sz); - free(block); - return; - } - block->free = 1; -} - -void* rune_alloc(size_t sz) { - if (sz == 0) - return NULL; - - mem_block_t *block = _find_free_block(sz); - if (block != NULL) { - block->free = 0; - return block->ptr; - } - - block = _alloc_block(sz); - return block->ptr; -} - -void* rune_calloc(size_t nmemb, size_t sz) { - if (sz == 0) - return NULL; - - mem_block_t *block = _find_free_block(sz); - if (block != NULL) { - block->free = 0; - return block->ptr; - } - - block = _alloc_block(sz); - memset(block->ptr, 0, sz); - return block->ptr; -} - -void* rune_realloc(void *ptr, size_t sz) { - if (ptr == NULL || sz == 0) - return rune_alloc(sz); - - mem_block_t *old = _find_block(ptr); - mem_block_t *new = _alloc_block(sz); - memcpy(new->ptr, old->ptr, old->sz); - old->free = 1; - return new->ptr; -} - -void rune_free(void *ptr) { - if (ptr == NULL) - return; - - mem_block_t *block = _find_block(ptr); - if (block->free == 1) - return; - block->free = 1; -} - -void rune_free_all(void) { - list_head_t *temp = &first_block.list; - mem_block_t *block; - while (temp != NULL) { - block = (mem_block_t*)((void*)temp - offsetof(mem_block_t, list)); - if (block->ptr == DEADBLOCK) { - temp = temp->next; - continue; - } - - temp = temp->next; - if (block->ptr != NULL) - _free_block(block, 1); - } -} diff --git a/core/callbacks.c b/core/callbacks.c deleted file mode 100644 index ea7f50e..0000000 --- a/core/callbacks.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/callbacks.h> -#include <rune/core/logging.h> - -void error_callback(int error, const char *desc) { - log_output(LOG_ERROR, "%d: %s\n", error, desc); -} diff --git a/core/init.c b/core/init.c deleted file mode 100644 index 5df4d04..0000000 --- a/core/init.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/init.h> -#include <rune/core/abort.h> -#include <rune/core/logging.h> -#include <rune/core/thread.h> - -int rune_init(int argc, char* argv[]) { - log_output(LOG_INFO, "Started Rune Engine version %s", RUNE_VER); - _parse_args(argc, argv); - rune_init_thread_api(); - return 0; -} - -void rune_exit(void) { - log_output(LOG_INFO, "Engine shutdown requested"); - rune_free_all(); -} diff --git a/core/logging.c b/core/logging.c deleted file mode 100644 index b7f77bd..0000000 --- a/core/logging.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/logging.h> -#include <rune/core/config.h> -#include <stdio.h> -#include <string.h> -#include <stdarg.h> - -#define COLOR_NONE "" -#define COLOR_DEFAULT "\033[0m" -#define COLOR_RED "\033[31m" -#define COLOR_GREEN "\033[32m" -#define COLOR_YELLOW "\033[33m" -#define COLOR_BLUE "\033[34m" - -#define LSTR_FATAL "[FATAL]" -#define LSTR_ERROR "[ERROR]" -#define LSTR_WARN "[WARNING]" -#define LSTR_INFO "[INFO]" -#define LSTR_DEBUG "[DEBUG]" - -static int debug_enabled = 0; -static int color_enabled = 0; - -void log_output(int level, const char *fmt, ...) { - char out[4096]; - memset(out, 0, sizeof(out)); - - debug_enabled = rune_get_log_debug(); - color_enabled = rune_get_log_color(); - - va_list arg_ptr; - va_start(arg_ptr, fmt); - vsnprintf(out, 4096, fmt, arg_ptr); - va_end(arg_ptr); - - char *lvl_str; - char *color = COLOR_NONE; - switch (level) { - case LOG_FATAL: - if (color_enabled == 1) - color = COLOR_RED; - lvl_str = LSTR_FATAL; - break; - case LOG_ERROR: - if (color_enabled == 1) - color = COLOR_RED; - lvl_str = LSTR_ERROR; - break; - case LOG_WARN: - if (color_enabled == 1) - color = COLOR_YELLOW; - lvl_str = LSTR_WARN; - break; - case LOG_INFO: - lvl_str = LSTR_INFO; - break; - case LOG_DEBUG: - if (color_enabled == 1) - color = COLOR_GREEN; - if (debug_enabled == 0) - return; - lvl_str = LSTR_DEBUG; - break; - } - - if (color_enabled == 0) { - printf("%s %s\n", lvl_str, out); - } else { - printf("%s%s %s\n", color, lvl_str, out); - printf(COLOR_DEFAULT); - } -} - -//#ifdef _WIN32 -// -//#include <windows.h> -// -//void enable_log_color(void) { -// HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); -// SetConsoleMode(handle, ENABLE_VIRTUAL_TERMINAL_PROCESSING); -// color_enabled = 1; -//} -// -//#else -// -//void enable_log_color(void) { -// color_enabled = 1; -//} -// -//#endif -// -//void disable_log_color(void) { -// color_enabled = 0; -//} diff --git a/core/mod.c b/core/mod.c deleted file mode 100644 index 3d9e710..0000000 --- a/core/mod.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/mod.h> -#include <rune/core/logging.h> -#include <rune/core/alloc.h> -#include <stdio.h> -#include <string.h> -#include <dirent.h> -#include <dlfcn.h> - -list_head_t *mods = NULL; - -void _load_mod(const char *filename) { - char mod_path[4096]; - sprintf(mod_path, "mods/%s", filename); - void *handle = dlopen(mod_path, RTLD_LAZY); - if (handle == NULL) - log_output(LOG_ERROR, "Error loading mod %s: %s", filename, dlerror()); -} - -void rune_load_mods(void) { - DIR *dir = opendir("mods"); - if (dir == NULL) { - log_output(LOG_INFO, "No mods folder found, skipping mod loading"); - return; - } - - struct dirent *mods_de; - while ((mods_de = readdir(dir)) != NULL) { - if (strstr(mods_de->d_name, ".so")) - _load_mod(mods_de->d_name); - } -} - -void rune_init_mods(void) { - list_head_t *temp = mods; - struct mod *mod; - while (temp != NULL) { - mod = (struct mod*)((void*)temp - offsetof(struct mod, list)); - (*mod->init_func)(); - temp = temp->next; - } -} - -void rune_close_mods(void) { - if (mods == NULL) - return; - - list_head_t *temp = mods; - struct mod *mod; - while (temp != NULL) { - mod = (struct mod*)((void*)temp - offsetof(struct mod, list)); - (*mod->exit_func)(); - temp = temp->next; - rune_free(mod); - } -} - -void rune_register_mod(const char *name, mod_func init_func, mod_func exit_func, mod_func update_func) { - struct mod *new = rune_alloc(sizeof(struct mod)); - new->name = name; - new->init_func = init_func; - new->exit_func = exit_func; - new->update_func = update_func; - new->list.next = NULL; - new->list.prev = NULL; - if (mods == NULL) - mods = &new->list; - else - list_add(&new->list, mods); -} diff --git a/core/thread.c b/core/thread.c deleted file mode 100644 index 3c5db8c..0000000 --- a/core/thread.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Rune Game Engine - * Copyright 2024 Danny Holman <dholman@gymli.org> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ - -#include <rune/core/thread.h> -#include <rune/core/logging.h> -#include <rune/core/alloc.h> -#include <pthread.h> -#include <string.h> -#include <stdatomic.h> - -static list_head_t *threads = NULL; -static list_head_t *mutexes = NULL; -static int next_tid = 0; -static int next_mid = 0; - -struct start_args { - struct thread *thread; - void* (*thread_fn)(void*); - void *thread_args; -}; - -static struct thread* _find_thread_by_handle(void *handle) { - if (threads == NULL) - return NULL; - - list_head_t *temp = threads; - struct thread *ret; - while (temp != NULL) { - ret = (struct thread*)((void*)temp - offsetof(struct thread, list)); - if (pthread_equal(*(pthread_t*)ret->thread_handle, *(pthread_t*)handle) == 1) - return ret; - temp = temp->next; - } - return NULL; -} - -static struct thread* _find_thread_by_id(int ID) { - if (threads == NULL) - return NULL; - - list_head_t *temp = threads; - struct thread *ret; - while (temp != NULL) { - ret = (struct thread*)((void*)temp - offsetof(struct thread, list)); - if (ret->ID == ID) - return ret; - temp = temp->next; - } - return NULL; -} - -static struct mutex* _find_mutex_by_id(int ID) { - if (mutexes == NULL) - return NULL; - - list_head_t *temp = mutexes; - struct mutex *ret; - while (temp != NULL) { - ret = (struct mutex*)((void*)temp - offsetof(struct mutex, list)); - if (ret->ID == ID) - return ret; - temp = temp->next; - } - return NULL; -} - - -static void _cleanup_pthread(void *arg) { - struct thread *thread = (struct thread*)arg; - if (&thread->list != threads) - list_del(&thread->list); - rune_free(thread->thread_handle); - rune_free(thread); -} - -static void* _startup_pthread(void *arg) { - struct start_args *start_args = (struct start_args*)arg; - - void* (*thread_fn)(void *data) = start_args->thread_fn; - pthread_cleanup_push(_cleanup_pthread, start_args->thread); - if (thread_fn != NULL) - (*thread_fn)(start_args->thread_args); - pthread_cleanup_pop(1); - return NULL; -} - -void rune_init_thread_api(void) { - struct thread *start_thread = rune_alloc(sizeof(struct thread)); - start_thread->ID = next_tid++; - start_thread->detached = 0; - start_thread->thread_handle = rune_alloc(sizeof(pthread_t)); - *(pthread_t*)start_thread->thread_handle = pthread_self(); - pthread_cleanup_push(_cleanup_pthread, threads); - pthread_cleanup_pop(0); -} - -int rune_thread_init(void* (*thread_fn)(void *data), void *data, int detached) { - struct thread *thread = rune_alloc(sizeof(struct thread)); - thread->ID = next_tid++; - thread->detached = detached; - thread->thread_handle = rune_alloc(sizeof(pthread_t)); - if (threads == NULL) - threads = &thread->list; - else - list_add(&thread->list, threads); - - struct start_args *args = rune_alloc(sizeof(struct start_args)); - args->thread = thread; - args->thread_fn = thread_fn; - args->thread_args = data; - int retval = pthread_create(thread->thread_handle, NULL, _startup_pthread, args); - rune_free(args); - if (retval != 0) { - log_output(LOG_ERROR, "Thread creation failed: %s", strerror(retval)); - return -1; - } - log_output(LOG_DEBUG, "Initialized new thread with ID=%d", thread->ID); - if (detached == 1) { - log_output(LOG_DEBUG, "Thread %d has been detached, join no longer possible"); - pthread_detach(*(pthread_t*)thread->thread_handle); - } - return thread->ID; -} - -int rune_thread_cancel(int ID) { - log_output(LOG_DEBUG, "Received cancel request for thread %d", ID); - struct thread *thread = _find_thread_by_id(ID); - if (thread == NULL) { - log_output(LOG_ERROR, "Thread %d does not exist", ID); - return -1; - } - pthread_cancel(*((pthread_t*)thread->thread_handle)); - return 0; -} - -int rune_thread_join(int ID, void **retval) { - struct thread *thread = _find_thread_by_id(ID); - if (thread == NULL) - return 0; - - if (thread->detached == 1) { - log_output(LOG_ERROR, "Cannot join thread %d, detached", thread->ID); - return -1; - } - pthread_join(*((pthread_t*)thread->thread_handle), retval); - return 0; -} - -int rune_thread_self(void) { - pthread_t cur = pthread_self(); - struct thread *ret = _find_thread_by_handle((void*)&cur); - if (ret != NULL) - return ret->ID; - return -1; -} - -void rune_thread_exit(void *retval) { - pthread_t cur = pthread_self(); - struct thread *self = _find_thread_by_handle((void*)&cur); - log_output(LOG_DEBUG, "Thread %d called thread_exit", self->ID); - pthread_exit(retval); -} - -int rune_mutex_init(void) { - struct mutex *mutex = rune_alloc(sizeof(struct mutex)); - mutex->ID = next_mid++; - mutex->mutex_handle = rune_alloc(sizeof(pthread_mutex_t)); - pthread_mutex_init((pthread_mutex_t*)mutex->mutex_handle, NULL); - if (mutexes == NULL) - mutexes = &mutex->list; - else - list_add(&mutex->list, mutexes); - return mutex->ID; -} - -int rune_mutex_destroy(int ID) { - struct mutex *mutex = _find_mutex_by_id(ID); - rune_free(mutex->mutex_handle); - if (&mutex->list != mutexes) - list_del(&mutex->list); - rune_free(mutex); -} - -int rune_mutex_lock(int ID) { - struct mutex *mutex = _find_mutex_by_id(ID); - int retval = pthread_mutex_lock((pthread_mutex_t*)mutex->mutex_handle); - if (retval != 0) { - char *str = strerror(retval); - log_output(LOG_ERROR, "Cannot lock mutex %d: %s", mutex->ID, str); - } -} - -int rune_mutex_unlock(int ID) { - struct mutex *mutex = _find_mutex_by_id(ID); - int retval = pthread_mutex_unlock((pthread_mutex_t*)mutex->mutex_handle); - if (retval != 0) { - char *str = strerror(retval); - log_output(LOG_ERROR, "Cannot unlock mutex %d: %s", mutex->ID, str); - } -} |