diff options
author | Harry Jeffery <harry@exec64.co.uk> | 2019-06-15 14:28:29 +0100 |
---|---|---|
committer | Harry Jeffery <harry@exec64.co.uk> | 2019-07-03 20:50:19 +0100 |
commit | 7c7dc660e587eac1aa3c8b3405eba95ba558e682 (patch) | |
tree | 81d12d560b60d397be23c7d132e32a5de30e409a /src/log.c | |
parent | 20e9d23b82f55a751c3cf1166cb59ef26775ee00 (diff) | |
download | imv-7c7dc660e587eac1aa3c8b3405eba95ba558e682.tar.gz |
Big glfw refactor
I did a lot of this in a very ad-hoc fashion with no proper commit
history. As such, the kindest thing to do seemed to be to just squash it
into this one commit.
Diffstat (limited to 'src/log.c')
-rw-r--r-- | src/log.c | 59 |
1 files changed, 52 insertions, 7 deletions
@@ -1,24 +1,69 @@ #include "log.h" +#include "list.h" + +#include <assert.h> #include <stdio.h> #include <stdarg.h> #include <stdlib.h> -static enum imv_log_level g_log_level = IMV_WARNING; +static struct list *g_log_clients = NULL; +static char g_log_buffer[16384]; -void imv_log_set_level(enum imv_log_level level) -{ - g_log_level = level; -} +struct log_client { + imv_log_callback callback; + void *data; +}; void imv_log(enum imv_log_level level, const char *fmt, ...) { - if (level > g_log_level) { + assert(fmt); + + /* Exit early if no one's listening */ + if (!g_log_clients || !g_log_clients->len) { return; } va_list args; va_start(args, fmt); - vfprintf(stderr, fmt, args); + vsnprintf(g_log_buffer, sizeof g_log_buffer, fmt, args); va_end(args); + + for (size_t i = 0; i < g_log_clients->len; ++i) { + struct log_client *client = g_log_clients->items[i]; + client->callback(level, g_log_buffer, client->data); + } +} + +void imv_log_add_log_callback(imv_log_callback callback, void *data) +{ + assert(callback); + + struct log_client *client = calloc(1, sizeof *client); + client->callback = callback; + client->data = data; + + if (!g_log_clients) { + g_log_clients = list_create(); + } + + list_append(g_log_clients, client); +} + +void imv_log_remove_log_callback(imv_log_callback callback) +{ + assert(callback); + + if (!callback || !g_log_clients) { + return; + } + + for (size_t i = 0; i < g_log_clients->len; ++i) { + struct log_client *client = g_log_clients->items[i]; + if (client->callback == callback) { + free(client); + list_remove(g_log_clients, i); + return; + } + } } |