[core] backend sends an event when it finishes loading a theme

This commit is contained in:
Milo Turner 2020-02-20 12:28:15 -05:00
parent 12fab7029a
commit 7df0ee7527
7 changed files with 112 additions and 19 deletions

View File

@ -98,8 +98,16 @@ void ax__backend_step(struct ax_backend* bac)
ON(ax_msg_load_font, ON(ax_msg_load_font,
{ {
printf("TODO: load font `%s' (size %zu)\n", printf("TODO: load font `%s' (size %zu)\n",
m->theme->font_path[m->category], m.theme->font_path[m.category],
m->theme->font_size[m->category]); m.theme->font_size[m.category]);
m.theme->font_loaded[m.category] = true;
if (ax__theme_is_loaded(m.theme)) {
struct ax_msg_theme_loaded* res =
msgq_begin_send_typed(m.callback_mq, ax_msg_theme_loaded);
res->theme = m.theme;
msgq_end_send(m.callback_mq);
}
break; break;
}); });

View File

@ -41,6 +41,6 @@ void msgq_end_recv(struct msgq* mq);
#define ON(ty, _body) \ #define ON(ty, _body) \
case ty ## _TAG: { \ case ty ## _TAG: { \
const struct ty* m = mqr__data; \ struct ty m = *(struct ty*) mqr__data; \
_body; \ _body; \
} }

View File

@ -8,6 +8,7 @@
struct ax_theme; struct ax_theme;
struct ax_theme_builder; struct ax_theme_builder;
struct ax_backend; struct ax_backend;
struct ax_evt_list;
struct ax_ctxt { struct ax_ctxt {
struct rgn* init_rgn; struct rgn* init_rgn;
@ -20,6 +21,11 @@ struct ax_ctxt {
struct rgn err_rgn; struct rgn err_rgn;
const char* err; const char* err;
// events
struct rgn evts_rgn;
struct ax_evt_list* evts;
struct msgq* inbox;
// backend // backend
pthread_t bac_thid; pthread_t bac_thid;
struct ax_backend* bac; struct ax_backend* bac;

View File

@ -55,9 +55,16 @@ void ax__ctxt_init(struct ax_ctxt* ax, struct rgn* init_rgn)
ax->log_auto_close = false; ax->log_auto_close = false;
rgn_init(&ax->err_rgn, SMALL); rgn_init(&ax->err_rgn, SMALL);
rgn_pin(init_rgn, &ax->err_rgn, (void*) rgn_cleanup);
ax->err = ""; ax->err = "";
rgn_init(&ax->evts_rgn, SMALL);
rgn_pin(init_rgn, &ax->evts_rgn, (void*) rgn_cleanup);
ax->evts = NULL;
ax->inbox = msgq_new(init_rgn);
rgn_init(&ax->thmb_rgn, THEME_BUILDER_DESIRED_REGION_SIZE); rgn_init(&ax->thmb_rgn, THEME_BUILDER_DESIRED_REGION_SIZE);
rgn_pin(init_rgn, &ax->thmb_rgn, (void*) rgn_cleanup);
ax->thmb = NULL; ax->thmb = NULL;
ax->sel_theme = NULL; ax->sel_theme = NULL;
@ -74,9 +81,6 @@ void ax__ctxt_cleanup(struct ax_ctxt* ax)
ax_log(ax, "waiting for backend shutdown."); ax_log(ax, "waiting for backend shutdown.");
pthread_join(ax->bac_thid, NULL); pthread_join(ax->bac_thid, NULL);
ax_log(ax, "backend shutdown"); ax_log(ax, "backend shutdown");
rgn_cleanup(&ax->thmb_rgn);
rgn_cleanup(&ax->err_rgn);
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
@ -115,7 +119,9 @@ void ax_end_theme(struct ax_ctxt* ax, struct ax_theme** out_thm)
ASSERT(ax->thmb != NULL, "`ax_end_theme' called while not building a theme"); ASSERT(ax->thmb != NULL, "`ax_end_theme' called while not building a theme");
struct ax_theme* thm; struct ax_theme* thm;
ax__theme_builder_finish(ax->thmb, ax->init_rgn, &thm); ax__theme_builder_finish(ax->thmb, ax->init_rgn, &thm);
ax__theme_request_load(thm, ax__backend_msgq(ax->bac)); ax__theme_request_load(thm,
ax__backend_msgq(ax->bac),
ax->inbox);
rgn_clear(&ax->thmb_rgn); rgn_clear(&ax->thmb_rgn);
if (out_thm != NULL) { if (out_thm != NULL) {
*out_thm = thm; *out_thm = thm;
@ -162,7 +168,10 @@ int ax_select_theme(struct ax_ctxt* ax, struct ax_theme* thm)
ax->err = thm->fatal_err; ax->err = thm->fatal_err;
return AX_ERR_THEME_INVALID; return AX_ERR_THEME_INVALID;
} }
// TODO: see if font is loaded if (!ax__theme_is_loaded(thm)) {
ax->err = "theme hasn't finished loading";
return AX_ERR_THEME_LOADING;
}
ax->sel_theme = thm; ax->sel_theme = thm;
ax_log(ax, "theme selected"); ax_log(ax, "theme selected");
return 0; return 0;
@ -172,15 +181,63 @@ int ax_select_theme(struct ax_ctxt* ax, struct ax_theme* thm)
* API functions :: events * API functions :: events
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
struct ax_evt_list {
struct ax_evt_list* next;
struct ax_evt e;
};
static struct ax_evt* push_evt(struct ax_ctxt* ax)
{
struct ax_evt_list* l =
ralloc_typed(&ax->evts_rgn, struct ax_evt_list, 1);
l->next = ax->evts;
ax->evts = l;
return &l->e;
}
static struct ax_evt* pop_evt(struct ax_ctxt* ax)
{
struct ax_evt_list* l = ax->evts;
if (l == NULL) {
rgn_clear(&ax->evts_rgn);
return NULL;
} else {
ax->evts = l->next;
return &l->e;
}
}
void ax_wait_evt_avail(struct ax_ctxt* ax) void ax_wait_evt_avail(struct ax_ctxt* ax)
{ {
usleep(1000 * 1000); msgq_begin_recv_and_wait(ax->inbox);
MSGQ_RECV_ALL(ax->inbox) {
ON(ax_msg_theme_loaded,
{
struct ax_evt* e = push_evt(ax);
e->ty = AX_EVT_THEME_LOADED;
e->arg.theme = m.theme;
break;
});
default:
ax_log(ax, "Got some weird message");
break;
}
msgq_end_recv(ax->inbox);
} }
bool ax_poll_evt(struct ax_ctxt* ax, struct ax_evt* out_evt) bool ax_poll_evt(struct ax_ctxt* ax, struct ax_evt* out_evt)
{ {
ax_log(ax, "nuffin."); struct ax_evt* e = pop_evt(ax);
if (e == NULL) {
ax_log(ax, "event queue now empty");
return false; return false;
}
if (out_evt != NULL) {
*out_evt = *e;
}
return true;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------

View File

@ -29,6 +29,7 @@ static void theme_init(struct ax_theme* thm)
for (size_t i = 0; i < AX_FONT__COUNT; i++) { for (size_t i = 0; i < AX_FONT__COUNT; i++) {
thm->font_path[i] = NULL; thm->font_path[i] = NULL;
thm->font_loaded[i] = false;
} }
thm->font_size[AX_FONT_H1] = 96; thm->font_size[AX_FONT_H1] = 96;
@ -118,13 +119,17 @@ void ax__theme_builder_finish(
} }
} }
void ax__theme_request_load(struct ax_theme* thm, struct msgq* mq) void ax__theme_request_load(
struct ax_theme* thm,
struct msgq* req_mq,
struct msgq* res_mq)
{ {
for (size_t i = 0; i < AX_FONT__COUNT; i++) { for (size_t i = 0; i < AX_FONT__COUNT; i++) {
struct ax_msg_load_font* m = msgq_begin_send_typed(mq, ax_msg_load_font); struct ax_msg_load_font* m = msgq_begin_send_typed(req_mq, ax_msg_load_font);
m->callback_mq = res_mq;
m->theme = thm; m->theme = thm;
m->category = i; m->category = i;
msgq_end_send(mq); msgq_end_send(req_mq);
} }
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
struct rgn; struct rgn;
@ -38,6 +39,7 @@ struct ax_theme {
int64_t colors[AX_COLOR__COUNT]; int64_t colors[AX_COLOR__COUNT];
const char* font_path[AX_FONT__COUNT]; const char* font_path[AX_FONT__COUNT];
size_t font_size[AX_FONT__COUNT]; size_t font_size[AX_FONT__COUNT];
bool font_loaded[AX_FONT__COUNT];
}; };
struct ax_theme_builder { struct ax_theme_builder {
@ -73,7 +75,19 @@ void ax__theme_builder_finish(
void ax__theme_request_load( void ax__theme_request_load(
struct ax_theme* thm, struct ax_theme* thm,
struct msgq* mq); struct msgq* req_mq,
struct msgq* res_mq);
static inline bool ax__theme_is_loaded(
struct ax_theme* thm)
{
for (size_t i = 0; i < AX_FONT__COUNT; i++) {
if (!thm->font_loaded[i]) {
return false;
}
}
return true;
}
static inline int64_t ax__theme_color( static inline int64_t ax__theme_color(
struct ax_theme* thm, struct ax_theme* thm,

View File

@ -17,7 +17,7 @@ static void cleanup()
static void sigint_handler(int signum) static void sigint_handler(int signum)
{ {
printf("\nCaught interrupt.\n"); printf("\nCaught interrupt.\n");
cleanup(); // cleanup();
exit(0); exit(0);
} }
@ -39,12 +39,15 @@ int main(void)
ax = ax_new(); ax = ax_new();
ax_set_logger(ax, 0, false); ax_set_logger(ax, 0, false);
(void) make_example_theme(); struct ax_theme* thm = make_example_theme();
struct ax_evt evt;
for (;;) { for (;;) {
ax_wait_evt_avail(ax); ax_wait_evt_avail(ax);
while (ax_poll_evt(ax, NULL)) { while (ax_poll_evt(ax, &evt)) {
printf("Got an event, assuredly.\n"); if (evt.ty == AX_EVT_THEME_LOADED && evt.arg.theme == thm) {
printf("The font finished loading!\n");
}
} }
} }