Inital context stuff and tests
Linking and building is successfull and inital tests pass
This commit is contained in:
1 parent
2296f68123
commit
363e9894e8
10 files changed
+410
-59
No files matched your search
+122
@@ -0,0 +1,122 @@
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void *default_alloc(size_t size, void *user) {
|
||||
(void)user;
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void *default_realloc(void *ptr, size_t old_size, size_t new_size,
|
||||
void *user) {
|
||||
(void)old_size;
|
||||
(void)user;
|
||||
return realloc(ptr, new_size);
|
||||
}
|
||||
|
||||
static void default_free(void *ptr, size_t size, void *user) {
|
||||
(void)size;
|
||||
(void)user;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void default_log(int32_t level, const char *message, void *user) {
|
||||
static const char *names[] = {"TRACE", "DEBUG", "INFO", "WARN", "ERROR"};
|
||||
(void)user;
|
||||
fprintf(stderr, "[regolith %s] %s\n", names[level], message);
|
||||
}
|
||||
|
||||
const char *rg_version(void) { return RG_VERSION_STRING; }
|
||||
|
||||
void rg_config_init(rg_config *config) {
|
||||
memset(config, 0, sizeof *config);
|
||||
config->struct_size = (uint32_t)sizeof *config;
|
||||
config->allocator.alloc = default_alloc;
|
||||
config->allocator.realloc = default_realloc;
|
||||
config->allocator.free = default_free;
|
||||
config->log = default_log;
|
||||
config->log_level = RG_LOG_TRACE;
|
||||
config->viewport_w = 1280;
|
||||
config->viewport_h = 720;
|
||||
config->display_scale = 1.0f;
|
||||
}
|
||||
|
||||
void rg__log(rg_context *ctx, int32_t level, const char *fmt, ...) {
|
||||
char buf[512];
|
||||
va_list ap;
|
||||
|
||||
if (level < ctx->log_level)
|
||||
return;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof buf, fmt, ap);
|
||||
va_end(ap);
|
||||
ctx->log(level, buf, ctx->log_user);
|
||||
}
|
||||
|
||||
int rg__fail(rg_context *ctx, int code, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(ctx->last_error, sizeof ctx->last_error, fmt, ap);
|
||||
va_end(ap);
|
||||
rg__log(ctx, RG_LOG_ERROR, "%s", ctx->last_error);
|
||||
return code;
|
||||
}
|
||||
|
||||
const char *rg_last_error(const rg_context *ctx) { return ctx->last_error; }
|
||||
|
||||
rg_context *rg_create(const rg_config *config) {
|
||||
rg_config cfg;
|
||||
rg_context *ctx;
|
||||
size_t n;
|
||||
|
||||
rg_config_init(&cfg);
|
||||
if (config) {
|
||||
n = config->struct_size < sizeof cfg ? config->struct_size : sizeof cfg;
|
||||
memcpy(&cfg, config, n);
|
||||
}
|
||||
|
||||
if (!cfg.allocator.alloc || !cfg.allocator.realloc || !cfg.allocator.free) {
|
||||
rg_config defaults;
|
||||
rg_config_init(&defaults);
|
||||
cfg.allocator = defaults.allocator;
|
||||
}
|
||||
if (!cfg.log)
|
||||
cfg.log = default_log;
|
||||
if (cfg.display_scale <= 0.0f)
|
||||
cfg.display_scale = 1.0f;
|
||||
|
||||
ctx = cfg.allocator.alloc(sizeof *ctx, cfg.allocator.user);
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
memset(ctx, 0, sizeof *ctx);
|
||||
|
||||
ctx->alloc = cfg.allocator;
|
||||
ctx->log = cfg.log;
|
||||
ctx->log_user = cfg.log_user;
|
||||
ctx->log_level = cfg.log_level;
|
||||
ctx->viewport_w = cfg.viewport_w;
|
||||
ctx->viewport_h = cfg.viewport_h;
|
||||
ctx->display_scale = cfg.display_scale;
|
||||
|
||||
rg__log(ctx, RG_LOG_DEBUG, "clay minimum memory: %zu bytes",
|
||||
rg__clay_min_memory());
|
||||
rg__log(ctx, RG_LOG_INFO, "context created (%dx%d @ %.2fx)",
|
||||
(int)ctx->viewport_w, (int)ctx->viewport_h,
|
||||
(double)ctx->display_scale);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void rg_destroy(rg_context *ctx) {
|
||||
rg_allocator a;
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
rg__lua_close(ctx);
|
||||
rg__log(ctx, RG_LOG_INFO, "context destroyed");
|
||||
a = ctx->alloc;
|
||||
a.free(ctx, sizeof *ctx, a.user);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef RG_INTERNAL_H
|
||||
#define RG_INTERNAL_H
|
||||
|
||||
|
||||
#include "../include/regolith.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define RG_PRINTF(f, a) __attribute__((format(printf, f, a)))
|
||||
#else
|
||||
#define RG_PRINTF(f, a)
|
||||
#endif
|
||||
|
||||
struct lua_State;
|
||||
|
||||
struct rg_context {
|
||||
rg_allocator alloc;
|
||||
rg_log_fn log;
|
||||
void* log_user;
|
||||
int32_t log_level;
|
||||
int32_t viewport_w;
|
||||
int32_t viewport_h;
|
||||
float display_scale;
|
||||
char last_error[256];
|
||||
struct lua_State* L;
|
||||
};
|
||||
|
||||
void rg__log(rg_context* ctx, int32_t level, const char* fmt, ...) RG_PRINTF(3, 4);
|
||||
int rg__fail(rg_context* ctx, int code, const char* fmt, ...) RG_PRINTF(3, 4);
|
||||
|
||||
size_t rg__clay_min_memory(void);
|
||||
void rg__lua_close(rg_context* ctx);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
#define CLAY_IMPLEMENTATION
|
||||
#include "../third_party/clay/clay.h"
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
size_t rg__clay_min_memory(void)
|
||||
{
|
||||
return Clay_MinMemorySize();
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "internal.h"
|
||||
#include "../include/regolith_lua.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <lauxlib.h>
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
|
||||
static void *lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
|
||||
{
|
||||
rg_context *ctx = ud;
|
||||
rg_allocator *a = &ctx->alloc;
|
||||
|
||||
if (nsize == 0) {
|
||||
if (ptr) a->free(ptr, osize, a->user);
|
||||
return NULL;
|
||||
}
|
||||
if (!ptr) return a->alloc(nsize, a->user);
|
||||
return a->realloc(ptr, osize, nsize, a->user);
|
||||
}
|
||||
|
||||
static int on_panic(lua_State *L)
|
||||
{
|
||||
void *ud;
|
||||
const char *msg = lua_tostring(L, -1);
|
||||
|
||||
lua_getallocf(L, &ud);
|
||||
rg__log(ud, RG_LOG_ERROR, "lua panic: %s", msg ? msg : "unknown");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rg_lua_open(rg_context *ctx)
|
||||
{
|
||||
lua_State *L;
|
||||
|
||||
if (ctx->L) return RG_OK;
|
||||
L = lua_newstate(lua_alloc, ctx);
|
||||
if (!L) return rg__fail(ctx, RG_ERR_NO_MEMORY, "could not create lua state");
|
||||
lua_atpanic(L, on_panic);
|
||||
luaL_openlibs(L);
|
||||
ctx->L = L;
|
||||
rg__log(ctx, RG_LOG_INFO, "lua opened (%s)", LUA_VERSION);
|
||||
return RG_OK;
|
||||
}
|
||||
|
||||
void rg__lua_close(rg_context *ctx)
|
||||
{
|
||||
if (!ctx->L) return;
|
||||
lua_close(ctx->L);
|
||||
ctx->L = NULL;
|
||||
}
|
||||
|
||||
int rg_lua_dostring(rg_context *ctx, const char *code, const char *chunk_name)
|
||||
{
|
||||
lua_State *L = ctx->L;
|
||||
|
||||
if (!L) return rg__fail(ctx, RG_ERR_STATE, "lua is not open");
|
||||
if (luaL_loadbuffer(L, code, strlen(code), chunk_name ? chunk_name : "=string") != LUA_OK ||
|
||||
lua_pcall(L, 0, 0, 0) != LUA_OK) {
|
||||
const char *msg = lua_tostring(L, -1);
|
||||
int rc = rg__fail(ctx, RG_ERR_LUA, "%s", msg ? msg : "unknown lua error");
|
||||
lua_pop(L, 1);
|
||||
return rc;
|
||||
}
|
||||
return RG_OK;
|
||||
}
|
||||
|
||||
struct lua_State *rg_lua_state(rg_context *ctx)
|
||||
{
|
||||
return ctx->L;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#include "../third_party/stb/stb_rect_pack.h"
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "../third_party/stb/stb_truetype.h"
|
||||
|
||||
#include "internal.h"
|
||||
Reference in new issue
Block a user