aboutsummaryrefslogtreecommitdiff
path: root/src/log.c
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2019-06-15 14:28:29 +0100
committerHarry Jeffery <harry@exec64.co.uk>2019-07-03 20:50:19 +0100
commit7c7dc660e587eac1aa3c8b3405eba95ba558e682 (patch)
tree81d12d560b60d397be23c7d132e32a5de30e409a /src/log.c
parent20e9d23b82f55a751c3cf1166cb59ef26775ee00 (diff)
downloadimv-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.c59
1 files changed, 52 insertions, 7 deletions
diff --git a/src/log.c b/src/log.c
index 4ce6ae8..c56e510 100644
--- a/src/log.c
+++ b/src/log.c
@@ -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;
+ }
+ }
}