[theme] callback-style waiting for a theme to load

This commit is contained in:
Milo Turner 2020-02-21 15:53:09 -05:00
parent 940d4231d5
commit 153c084419
8 changed files with 74 additions and 37 deletions

View File

@ -35,6 +35,7 @@ void ax_set_theme_font(
void ax_set_theme_iconset(
struct ax_ctxt* ax, const char* iconset_dir);
void ax_theme_wait_until_loaded(struct ax_ctxt* ax, struct ax_theme* thm);
int ax_select_theme(struct ax_ctxt* ax, struct ax_theme* thm);
#define AX_ERR_THEME_LOADING 1

View File

@ -93,7 +93,6 @@ struct font_list {
struct font_list* next;
struct ax_theme* thm;
size_t cat;
struct msgq* cb_mq;
};
static void load_fonts(
@ -123,7 +122,6 @@ void ax__backend_step(struct ax_backend* bac)
l->next = fonts;
l->thm = m.theme;
l->cat = m.category;
l->cb_mq = m.callback_mq;
fonts = l;
break;
});
@ -150,6 +148,7 @@ static int load_font(
struct rgn* rgn, const char* path, size_t size,
struct ax_font_h** out_fh, const char** out_err)
{
printf("loading `%s' (size %zu)\n", path, size);
struct ax_font_h* fh = ralloc_typed(rgn, struct ax_font_h, 1);
if ((fh->font = TTF_OpenFont(path, size)) == NULL) {
*out_err = TTF_GetError();
@ -173,13 +172,7 @@ static void load_fonts(struct ax_backend* bac, struct font_list* fl)
&fh, &err)) != 0) {
goto fail;
}
bool is_loaded = ax__theme_set_font_handle(thm, fl->cat, fh);
if (is_loaded) {
struct ax_msg_theme_loaded* m =
msgq_begin_send_typed(fl->cb_mq, ax_msg_theme_loaded);
m->theme = thm;
msgq_end_send(fl->cb_mq);
}
ax__theme_set_font_handle(thm, fl->cat, fh);
}
fail:

View File

@ -12,7 +12,6 @@ struct ax_msg_shutdown {
};
struct ax_msg_load_font {
struct msgq* callback_mq;
struct ax_theme* theme;
int category;
};

View File

@ -13,6 +13,11 @@ struct msgq {
pthread_cond_t cv;
};
struct msgq_list {
struct msgq* mq;
struct msgq_list* next;
};
struct msgq_msg_list {
struct msgq_msg_list* next;
int type;

View File

@ -115,16 +115,11 @@ void ax_end_theme(struct ax_ctxt* ax, struct ax_theme** out_thm)
ax->thmb = NULL;
rgn_clear(ax->thmb_rgn);
ax__theme_load(thm, ax__backend_msgq(ax->bac));
if (out_thm != NULL) {
*out_thm = thm;
}
struct msgq* callback;
UNIMPLEMENTED();
ax__theme_request_load(thm,
ax__backend_msgq(ax->bac),
callback);
}
void ax_set_theme_color(
@ -160,6 +155,18 @@ void ax_set_theme_iconset(
UNIMPLEMENTED();
}
void ax_theme_wait_until_loaded(struct ax_ctxt* ax, struct ax_theme* thm)
{
struct rgn rgn[1];
rgn_init(rgn, SMALL);
struct msgq* mq = msgq_new(rgn);
ax__theme_on_load(thm, mq);
msgq_begin_recv_and_wait(mq);
MSGQ_RECV_ALL(mq) {}
msgq_end_recv(mq);
rgn_cleanup(rgn);
}
int ax_select_theme(struct ax_ctxt* ax, struct ax_theme* thm)
{
ASSERT_NON_NULL(thm, "theme");

View File

@ -95,7 +95,9 @@ struct ax_theme* ax__theme_builder_finish(
dflt_font_path :
rstrdup(dst_rgn, thm->font_path[i]);
}
pthread_mutex_init(&thm->handles_mx, NULL);
thm->on_load_rgn = rgn_new(dst_rgn, SMALL);
thm->on_load = NULL;
pthread_mutex_init(&thm->mx, NULL);
rgn_pin(dst_rgn, thm, (void*) pthread_mutex_destroy);
return thm;
}
@ -114,50 +116,72 @@ static inline bool is_loaded(struct ax_theme* thm)
return true;
}
static inline void msgq_send_theme_loaded(struct msgq* mq, struct ax_theme* thm)
{
msgq_begin_send_typed(mq, ax_msg_theme_loaded)
->theme = thm;
msgq_end_send(mq);
}
struct ax_font_h* ax__theme_font_handle(
struct ax_theme* thm,
enum ax_font_cat i)
{
pthread_mutex_lock(&thm->handles_mx);
pthread_mutex_lock(&thm->mx);
struct ax_font_h* h = thm->font_handle[i];
pthread_mutex_unlock(&thm->handles_mx);
pthread_mutex_unlock(&thm->mx);
return h;
}
bool ax__theme_is_loaded(struct ax_theme* thm)
{
pthread_mutex_lock(&thm->handles_mx);
pthread_mutex_lock(&thm->mx);
bool l = is_loaded(thm);
pthread_mutex_unlock(&thm->handles_mx);
pthread_mutex_unlock(&thm->mx);
return l;
}
bool ax__theme_set_font_handle(
void ax__theme_set_font_handle(
struct ax_theme* thm,
enum ax_font_cat i,
struct ax_font_h* h)
{
pthread_mutex_lock(&thm->handles_mx);
pthread_mutex_lock(&thm->mx);
thm->font_handle[i] = h;
bool l = is_loaded(thm);
pthread_mutex_unlock(&thm->handles_mx);
return l;
if (is_loaded(thm)) {
while (thm->on_load != NULL) {
msgq_send_theme_loaded(thm->on_load->mq, thm);
thm->on_load = thm->on_load->next;
}
}
pthread_mutex_unlock(&thm->mx);
}
void ax__theme_request_load(
struct ax_theme* thm,
struct msgq* req_mq,
struct msgq* res_mq)
void ax__theme_load(struct ax_theme* thm, struct msgq* req_mq)
{
for (size_t i = 0; i < AX_FONT__COUNT; i++) {
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->category = i;
msgq_end_send(req_mq);
}
}
void ax__theme_on_load(struct ax_theme* thm, struct msgq* res_mq)
{
pthread_mutex_lock(&thm->mx);
if (is_loaded(thm)) {
msgq_send_theme_loaded(res_mq, thm);
} else {
struct msgq_list* l =
ralloc_typed(thm->on_load_rgn, struct msgq_list, 1);
l->mq = res_mq;
l->next = thm->on_load;
thm->on_load = l;
}
pthread_mutex_unlock(&thm->mx);
}
int ax__string_to_color_cat(const char* str, enum ax_color_cat* out_cat)
{
enum ax_color_cat val;

View File

@ -7,6 +7,7 @@
struct rgn;
struct msgq;
struct msgq_list;
#define THEME_BUILDER_DESIRED_REGION_SIZE (16*1024)
@ -43,7 +44,9 @@ struct ax_theme {
size_t font_size[AX_FONT__COUNT];
const char* font_path[AX_FONT__COUNT];
struct ax_font_h* font_handle[AX_FONT__COUNT];
pthread_mutex_t handles_mx;
struct rgn* on_load_rgn;
struct msgq_list* on_load;
pthread_mutex_t mx;
};
struct ax_theme_builder {
@ -99,14 +102,17 @@ struct ax_font_h* ax__theme_font_handle(
bool ax__theme_is_loaded(
struct ax_theme* thm);
bool ax__theme_set_font_handle( // returns `true` if the font is now loaded
void ax__theme_set_font_handle(
struct ax_theme* thm,
enum ax_font_cat i,
struct ax_font_h* h);
void ax__theme_request_load(
void ax__theme_load(
struct ax_theme* thm,
struct msgq* req_mq);
void ax__theme_on_load(
struct ax_theme* thm,
struct msgq* req_mq,
struct msgq* res_mq);
/*

View File

@ -40,7 +40,9 @@ int main(void)
ax_set_logger(ax, 0, false);
struct ax_theme* thm = make_example_theme();
(void) thm;
ax_theme_wait_until_loaded(ax, thm);
printf("it loaded!\n");
usleep(1000 * 1000 * 2);
/*
struct ax_evt evt;