feat: config variables, mutex abstraction
- Mutex abstraction (create, destroy, lock, unlock) - Config variables (cvars)
This commit is contained in:
parent
1dba3d2d63
commit
63e3f973b2
43
include/config.h
Normal file
43
include/config.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef VY_CONFIG_H
|
||||
#define VY_CONFIG_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VY_CVAR_TYPE_INT,
|
||||
VY_CVAR_TYPE_FLOAT,
|
||||
VY_CVAR_TYPE_STRING,
|
||||
} vy_cvar_type;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
const char *description;
|
||||
union {
|
||||
int i;
|
||||
float f;
|
||||
const char *s;
|
||||
};
|
||||
vy_cvar_type type;
|
||||
} vy_cvar;
|
||||
|
||||
#define VY_CVAR_I(n, d, v) \
|
||||
vy_cvar n = {.name = #n, \
|
||||
.description = d, \
|
||||
.i = (v), \
|
||||
.type = VY_CVAR_TYPE_INT}
|
||||
#define VY_CVAR_F(n, d, v) \
|
||||
vy_cvar n = {.name = #n, \
|
||||
.description = d, \
|
||||
.f = (v), \
|
||||
.type = VY_CVAR_TYPE_FLOAT}
|
||||
#define VY_CVAR_S(n, d, v) \
|
||||
vy_cvar n = {.name = #n, \
|
||||
.description = d, \
|
||||
.s = (v), \
|
||||
.type = VY_CVAR_TYPE_STRING}
|
||||
|
||||
void vyRegisterCVAR(vy_cvar *cvar);
|
||||
|
||||
vy_cvar *vyGetCVAR(const char *name);
|
||||
|
||||
#endif
|
18
include/threading.h
Normal file
18
include/threading.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef VY_THREADING_H
|
||||
#define VY_THREADING_H
|
||||
|
||||
/* platform independent threading */
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct vy_mutex_s vy_mutex;
|
||||
|
||||
vy_mutex *vyCreateMutex(void);
|
||||
|
||||
void vyDestroyMutex(vy_mutex *mutex);
|
||||
|
||||
bool vyLockMutex(vy_mutex *mutex);
|
||||
|
||||
bool vyUnlockMutex(vy_mutex *mutex);
|
||||
|
||||
#endif
|
@ -6,6 +6,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#define VY_UNUSED(x) ((void)sizeof((x)))
|
||||
#define VY_ARRAY_COUNT(x) (sizeof((x)) / sizeof((x)[0]))
|
||||
|
||||
typedef struct {
|
||||
const char *start;
|
||||
|
@ -13,9 +13,12 @@ if compiler.get_argument_syntax() == 'gcc'
|
||||
)
|
||||
elif compiler.get_argument_syntax() == 'msvc'
|
||||
add_project_arguments(
|
||||
['/wd4146', '/wd4245', '/wd4100', '/D_CRT_SECURE_NO_WARNINGS', '/RTCsu'],
|
||||
['/wd4146', '/wd4245', '/wd4100', '/D_CRT_SECURE_NO_WARNINGS'],
|
||||
language: 'c'
|
||||
)
|
||||
if buildtype == 'debug'
|
||||
add_project_arguments(['/RTCsu'], language : 'c')
|
||||
endif
|
||||
endif
|
||||
|
||||
# Debug specific flags
|
||||
@ -41,6 +44,8 @@ executable('voyage',
|
||||
'include/gfx.h',
|
||||
'include/gfx_backend.h',
|
||||
'include/fio.h',
|
||||
'include/config.h',
|
||||
'include/threading.h',
|
||||
|
||||
'src/voyage.c',
|
||||
'src/fio.c',
|
||||
@ -48,6 +53,8 @@ executable('voyage',
|
||||
'src/gfx_main.c',
|
||||
'src/gfx_shader_loading.c',
|
||||
'src/gfx_pipelines.c',
|
||||
'src/config.c',
|
||||
'src/threading.c',
|
||||
|
||||
# Contrib Sources
|
||||
'contrib/glad/glad.c',
|
||||
|
39
src/config.c
Normal file
39
src/config.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include "config.h"
|
||||
#include "threading.h"
|
||||
#include "voyage.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#define VY_MAX_CVARS 1024
|
||||
|
||||
static vy_cvar *_vars[VY_MAX_CVARS];
|
||||
static unsigned int _next = 0;
|
||||
static vy_mutex *_mutex = NULL;
|
||||
|
||||
void vyRegisterCVAR(vy_cvar *cvar) {
|
||||
if (!_mutex)
|
||||
_mutex = vyCreateMutex();
|
||||
vyLockMutex(_mutex);
|
||||
if (_next < VY_MAX_CVARS) {
|
||||
_vars[_next++] = cvar;
|
||||
} else {
|
||||
vyReportError("cvar", "Ran out of space for CVars");
|
||||
}
|
||||
vyUnlockMutex(_mutex);
|
||||
}
|
||||
|
||||
vy_cvar *vyGetCVAR(const char *name) {
|
||||
if (!_mutex)
|
||||
_mutex = vyCreateMutex();
|
||||
vy_cvar *var = NULL;
|
||||
vyLockMutex(_mutex);
|
||||
for (unsigned int i = 0; i < _next; ++i) {
|
||||
if (strcmp(name, _vars[i]->name) == 0) {
|
||||
var = _vars[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
vyUnlockMutex(_mutex);
|
||||
return var;
|
||||
}
|
@ -3,22 +3,66 @@
|
||||
|
||||
#include "voyage.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
/* TODO(Kevin): Log to file, show error message box, ... */
|
||||
|
||||
static void DisplayErrorBox(const char *text)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WCHAR msg[256];
|
||||
MultiByteToWideChar(CP_UTF8,
|
||||
MB_PRECOMPOSED,
|
||||
text,
|
||||
-1,
|
||||
msg,
|
||||
VY_ARRAY_COUNT(msg));
|
||||
MessageBoxW(NULL, msg, L"Error", MB_ICONERROR);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void LogOut(const char *text)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WCHAR msg[256];
|
||||
MultiByteToWideChar(CP_UTF8,
|
||||
MB_PRECOMPOSED,
|
||||
text,
|
||||
-1,
|
||||
msg,
|
||||
VY_ARRAY_COUNT(msg));
|
||||
OutputDebugStringW(msg);
|
||||
#elif defined(__linux__)
|
||||
fprintf(stderr, "%s", text);
|
||||
#endif
|
||||
}
|
||||
|
||||
void vyReportError(const char *subsystem, const char *fmt, ...) {
|
||||
char buf[256];
|
||||
|
||||
int at = snprintf(buf, VY_ARRAY_COUNT(buf) - 1, "[%s] ", subsystem);
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
fprintf(stderr, "[%s] ", subsystem);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
at += vsnprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
at += snprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, "\n");
|
||||
|
||||
LogOut(buf);
|
||||
DisplayErrorBox(buf);
|
||||
}
|
||||
|
||||
void vyLog(const char *subsystem, const char *fmt, ...) {
|
||||
char buf[256];
|
||||
|
||||
int at = snprintf(buf, VY_ARRAY_COUNT(buf) - 1, "[%s] ", subsystem);
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
fprintf(stderr, "[%s] ", subsystem);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
at += vsnprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
at += snprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, "\n");
|
||||
|
||||
LogOut(buf);
|
||||
}
|
@ -233,7 +233,7 @@ static void DbgPrintShaderFile(const vy_parse_state *state,
|
||||
}
|
||||
stmt_index = stmt->next;
|
||||
}
|
||||
assert(stmt_index == UINT_MAX);
|
||||
assert(stmt_index == UINT_MAX || stmt_index == 0);
|
||||
}
|
||||
|
||||
static bool CompareSpanToString(vy_text_span span, const char *cmp) {
|
||||
|
98
src/threading.c
Normal file
98
src/threading.c
Normal file
@ -0,0 +1,98 @@
|
||||
#include "threading.h"
|
||||
#include "voyage.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
struct vy_mutex_s {
|
||||
HANDLE handle;
|
||||
ptrdiff_t next_reusable;
|
||||
};
|
||||
|
||||
#define MAX_MUTEX 1024
|
||||
static vy_mutex _mutex[MAX_MUTEX];
|
||||
static ptrdiff_t _first_reusable = MAX_MUTEX;
|
||||
static ptrdiff_t _next = 0;
|
||||
|
||||
vy_mutex *vyCreateMutex(void) {
|
||||
if (_first_reusable < MAX_MUTEX) {
|
||||
vy_mutex *mtx = &_mutex[_first_reusable];
|
||||
_first_reusable = mtx->next_reusable;
|
||||
return mtx;
|
||||
} else if (_next < MAX_MUTEX) {
|
||||
vy_mutex *mtx = &_mutex[_next];
|
||||
mtx->handle = CreateMutexW(NULL, FALSE, NULL);
|
||||
if (!mtx->handle) {
|
||||
vyLog("core", "Mutex creation failed: %u", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
mtx->next_reusable = MAX_MUTEX;
|
||||
++_next;
|
||||
return mtx;
|
||||
}
|
||||
vyReportError("core", "Ran out of mutex objects");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vyDestroyMutex(vy_mutex *mutex) {
|
||||
ptrdiff_t index = mutex - &_mutex[0];
|
||||
mutex->next_reusable = _first_reusable;
|
||||
_first_reusable = index;
|
||||
}
|
||||
|
||||
bool vyLockMutex(vy_mutex *mutex) {
|
||||
return WaitForSingleObject(mutex->handle, INFINITE) == WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
bool vyUnlockMutex(vy_mutex *mutex) {
|
||||
return ReleaseMutex(mutex) != 0;
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
#include <pthread.h>
|
||||
struct vy_mutex_s {
|
||||
pthread_mutex_t handle;
|
||||
ptrdiff_t next_reusable;
|
||||
};
|
||||
|
||||
#define MAX_MUTEX 1024
|
||||
static vy_mutex _mutex[MAX_MUTEX];
|
||||
static ptrdiff_t _first_reusable = MAX_MUTEX;
|
||||
static ptrdiff_t _next = 0;
|
||||
|
||||
vy_mutex *vyCreateMutex(void) {
|
||||
if (_first_reusable < MAX_MUTEX) {
|
||||
vy_mutex *mtx = &_mutex[_first_reusable];
|
||||
_first_reusable = mtx->next_reusable;
|
||||
return mtx;
|
||||
} else if (_next < MAX_MUTEX) {
|
||||
vy_mutex *mtx = &_mutex[_next];
|
||||
if (pthread_mutex_init(&mtx->handle, NULL) != 0) {
|
||||
vyLog("core", "Mutex creation failed: %u", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
mtx->next_reusable = MAX_MUTEX;
|
||||
++_next;
|
||||
return mtx;
|
||||
}
|
||||
vyReportError("core", "Ran out of mutex objects");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vyDestroyMutex(vy_mutex *mutex) {
|
||||
ptrdiff_t index = mutex - &_mutex[0];
|
||||
mutex->next_reusable = _first_reusable;
|
||||
_first_reusable = index;
|
||||
}
|
||||
|
||||
bool vyLockMutex(vy_mutex *mutex) {
|
||||
return pthread_mutex_lock(&mutex->handle) == 0;
|
||||
}
|
||||
|
||||
bool vyUnlockMutex(vy_mutex *mutex) {
|
||||
return pthread_mutex_unlock(&mutex->handle) == 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "fio.h"
|
||||
#include "gfx.h"
|
||||
#include "threading.h"
|
||||
|
||||
static void glfw_error_cb(int err, const char *description) {
|
||||
fprintf(stderr, "[GLFW] %u: %s\n", err, description);
|
||||
|
Loading…
Reference in New Issue
Block a user