[theme] callback-style waiting for a theme to load
This commit is contained in:
parent
940d4231d5
commit
153c084419
1
src/ax.h
1
src/ax.h
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -12,7 +12,6 @@ struct ax_msg_shutdown {
|
|||
};
|
||||
|
||||
struct ax_msg_load_font {
|
||||
struct msgq* callback_mq;
|
||||
struct ax_theme* theme;
|
||||
int category;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue