[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(
|
void ax_set_theme_iconset(
|
||||||
struct ax_ctxt* ax, const char* iconset_dir);
|
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);
|
int ax_select_theme(struct ax_ctxt* ax, struct ax_theme* thm);
|
||||||
|
|
||||||
#define AX_ERR_THEME_LOADING 1
|
#define AX_ERR_THEME_LOADING 1
|
||||||
|
|
|
@ -93,7 +93,6 @@ struct font_list {
|
||||||
struct font_list* next;
|
struct font_list* next;
|
||||||
struct ax_theme* thm;
|
struct ax_theme* thm;
|
||||||
size_t cat;
|
size_t cat;
|
||||||
struct msgq* cb_mq;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void load_fonts(
|
static void load_fonts(
|
||||||
|
@ -123,7 +122,6 @@ void ax__backend_step(struct ax_backend* bac)
|
||||||
l->next = fonts;
|
l->next = fonts;
|
||||||
l->thm = m.theme;
|
l->thm = m.theme;
|
||||||
l->cat = m.category;
|
l->cat = m.category;
|
||||||
l->cb_mq = m.callback_mq;
|
|
||||||
fonts = l;
|
fonts = l;
|
||||||
break;
|
break;
|
||||||
});
|
});
|
||||||
|
@ -150,6 +148,7 @@ static int load_font(
|
||||||
struct rgn* rgn, const char* path, size_t size,
|
struct rgn* rgn, const char* path, size_t size,
|
||||||
struct ax_font_h** out_fh, const char** out_err)
|
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);
|
struct ax_font_h* fh = ralloc_typed(rgn, struct ax_font_h, 1);
|
||||||
if ((fh->font = TTF_OpenFont(path, size)) == NULL) {
|
if ((fh->font = TTF_OpenFont(path, size)) == NULL) {
|
||||||
*out_err = TTF_GetError();
|
*out_err = TTF_GetError();
|
||||||
|
@ -173,13 +172,7 @@ static void load_fonts(struct ax_backend* bac, struct font_list* fl)
|
||||||
&fh, &err)) != 0) {
|
&fh, &err)) != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
bool is_loaded = ax__theme_set_font_handle(thm, fl->cat, fh);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
|
@ -12,7 +12,6 @@ struct ax_msg_shutdown {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ax_msg_load_font {
|
struct ax_msg_load_font {
|
||||||
struct msgq* callback_mq;
|
|
||||||
struct ax_theme* theme;
|
struct ax_theme* theme;
|
||||||
int category;
|
int category;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,11 @@ struct msgq {
|
||||||
pthread_cond_t cv;
|
pthread_cond_t cv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct msgq_list {
|
||||||
|
struct msgq* mq;
|
||||||
|
struct msgq_list* next;
|
||||||
|
};
|
||||||
|
|
||||||
struct msgq_msg_list {
|
struct msgq_msg_list {
|
||||||
struct msgq_msg_list* next;
|
struct msgq_msg_list* next;
|
||||||
int type;
|
int type;
|
||||||
|
|
|
@ -115,16 +115,11 @@ void ax_end_theme(struct ax_ctxt* ax, struct ax_theme** out_thm)
|
||||||
ax->thmb = NULL;
|
ax->thmb = NULL;
|
||||||
rgn_clear(ax->thmb_rgn);
|
rgn_clear(ax->thmb_rgn);
|
||||||
|
|
||||||
|
ax__theme_load(thm, ax__backend_msgq(ax->bac));
|
||||||
|
|
||||||
if (out_thm != NULL) {
|
if (out_thm != NULL) {
|
||||||
*out_thm = thm;
|
*out_thm = thm;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct msgq* callback;
|
|
||||||
UNIMPLEMENTED();
|
|
||||||
|
|
||||||
ax__theme_request_load(thm,
|
|
||||||
ax__backend_msgq(ax->bac),
|
|
||||||
callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ax_set_theme_color(
|
void ax_set_theme_color(
|
||||||
|
@ -160,6 +155,18 @@ void ax_set_theme_iconset(
|
||||||
UNIMPLEMENTED();
|
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)
|
int ax_select_theme(struct ax_ctxt* ax, struct ax_theme* thm)
|
||||||
{
|
{
|
||||||
ASSERT_NON_NULL(thm, "theme");
|
ASSERT_NON_NULL(thm, "theme");
|
||||||
|
|
|
@ -95,7 +95,9 @@ struct ax_theme* ax__theme_builder_finish(
|
||||||
dflt_font_path :
|
dflt_font_path :
|
||||||
rstrdup(dst_rgn, thm->font_path[i]);
|
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);
|
rgn_pin(dst_rgn, thm, (void*) pthread_mutex_destroy);
|
||||||
return thm;
|
return thm;
|
||||||
}
|
}
|
||||||
|
@ -114,50 +116,72 @@ static inline bool is_loaded(struct ax_theme* thm)
|
||||||
return true;
|
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_font_h* ax__theme_font_handle(
|
||||||
struct ax_theme* thm,
|
struct ax_theme* thm,
|
||||||
enum ax_font_cat i)
|
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];
|
struct ax_font_h* h = thm->font_handle[i];
|
||||||
pthread_mutex_unlock(&thm->handles_mx);
|
pthread_mutex_unlock(&thm->mx);
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ax__theme_is_loaded(struct ax_theme* thm)
|
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);
|
bool l = is_loaded(thm);
|
||||||
pthread_mutex_unlock(&thm->handles_mx);
|
pthread_mutex_unlock(&thm->mx);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ax__theme_set_font_handle(
|
void ax__theme_set_font_handle(
|
||||||
struct ax_theme* thm,
|
struct ax_theme* thm,
|
||||||
enum ax_font_cat i,
|
enum ax_font_cat i,
|
||||||
struct ax_font_h* h)
|
struct ax_font_h* h)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&thm->handles_mx);
|
pthread_mutex_lock(&thm->mx);
|
||||||
thm->font_handle[i] = h;
|
thm->font_handle[i] = h;
|
||||||
bool l = is_loaded(thm);
|
if (is_loaded(thm)) {
|
||||||
pthread_mutex_unlock(&thm->handles_mx);
|
while (thm->on_load != NULL) {
|
||||||
return l;
|
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(
|
void ax__theme_load(struct ax_theme* thm, struct msgq* req_mq)
|
||||||
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(req_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(req_mq);
|
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)
|
int ax__string_to_color_cat(const char* str, enum ax_color_cat* out_cat)
|
||||||
{
|
{
|
||||||
enum ax_color_cat val;
|
enum ax_color_cat val;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
struct rgn;
|
struct rgn;
|
||||||
struct msgq;
|
struct msgq;
|
||||||
|
struct msgq_list;
|
||||||
|
|
||||||
#define THEME_BUILDER_DESIRED_REGION_SIZE (16*1024)
|
#define THEME_BUILDER_DESIRED_REGION_SIZE (16*1024)
|
||||||
|
|
||||||
|
@ -43,7 +44,9 @@ struct ax_theme {
|
||||||
size_t font_size[AX_FONT__COUNT];
|
size_t font_size[AX_FONT__COUNT];
|
||||||
const char* font_path[AX_FONT__COUNT];
|
const char* font_path[AX_FONT__COUNT];
|
||||||
struct ax_font_h* font_handle[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 {
|
struct ax_theme_builder {
|
||||||
|
@ -99,14 +102,17 @@ struct ax_font_h* ax__theme_font_handle(
|
||||||
bool ax__theme_is_loaded(
|
bool ax__theme_is_loaded(
|
||||||
struct ax_theme* thm);
|
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,
|
struct ax_theme* thm,
|
||||||
enum ax_font_cat i,
|
enum ax_font_cat i,
|
||||||
struct ax_font_h* h);
|
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 ax_theme* thm,
|
||||||
struct msgq* req_mq,
|
|
||||||
struct msgq* res_mq);
|
struct msgq* res_mq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -40,7 +40,9 @@ int main(void)
|
||||||
ax_set_logger(ax, 0, false);
|
ax_set_logger(ax, 0, false);
|
||||||
|
|
||||||
struct ax_theme* thm = make_example_theme();
|
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;
|
struct ax_evt evt;
|
||||||
|
|
Loading…
Reference in New Issue