[async] message queue abstractions

This commit is contained in:
Milo Turner 2020-02-19 19:48:15 -05:00
parent d61f9cc537
commit 47c0560b13
6 changed files with 58 additions and 40 deletions

View File

@ -16,20 +16,8 @@ int ax__backend_new(
struct ax_backend** out_bac, struct ax_backend** out_bac,
const char** out_err); const char** out_err);
enum {
ax_msg_shutdown_TAG,
ax_msg_load_font_TAG,
};
struct ax_msg_shutdown {};
struct ax_msg_load_font {
struct ax_theme* theme;
int category;
};
struct msgq* ax__backend_msgq(struct ax_backend*); struct msgq* ax__backend_msgq(struct ax_backend*);
bool ax__backend_is_shutdown(struct ax_backend*);
void ax__backend_wait_for_event(struct ax_backend*); void ax__backend_wait_for_event(struct ax_backend*);
void ax__backend_step(struct ax_backend*);
void ax__backend_step(struct ax_backend*, bool* out_shutdown);

View File

@ -1,7 +1,8 @@
#include "../backend.h" #include "../backend.h"
#include "../ctxt/theme.h"
#include "../util/region.h" #include "../util/region.h"
#include "../concurrent/msgq.h" #include "../concurrent/msgq.h"
#include "../ctxt/theme.h" #include "../concurrent/msg.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h> #include <SDL2/SDL_ttf.h>
@ -66,37 +67,39 @@ struct msgq* ax__backend_msgq(struct ax_backend* bac)
return bac->mq; return bac->mq;
} }
bool ax__backend_is_shutdown(struct ax_backend* bac)
{
return bac->shutdown;
}
void ax__backend_wait_for_event(struct ax_backend* bac) void ax__backend_wait_for_event(struct ax_backend* bac)
{ {
(void) bac; (void) bac;
} }
void ax__backend_step(struct ax_backend* bac, bool* out_shutdown) void ax__backend_step(struct ax_backend* bac)
{ {
int type;
void* data;
msgq_begin_recv(bac->mq); msgq_begin_recv(bac->mq);
while ((data = msgq_recv1(bac->mq, &type)) != NULL) {
switch (type) {
case ax_msg_shutdown_TAG: MSGQ_RECV_ALL(bac->mq) {
ON(ax_msg_shutdown,
{
(void) m;
bac->shutdown = true; bac->shutdown = true;
break; break;
});
case ax_msg_load_font_TAG: { ON(ax_msg_load_font,
struct ax_msg_load_font* m = data; {
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]);
break; break;
} });
default: break; default: break;
} }
}
msgq_end_recv(bac->mq);
if (out_shutdown != NULL) { msgq_end_recv(bac->mq);
*out_shutdown = bac->shutdown;
}
} }

14
src/concurrent/msg.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
enum {
ax_msg_shutdown_TAG,
ax_msg_load_font_TAG,
};
struct ax_msg_shutdown {
};
struct ax_msg_load_font {
struct ax_theme* theme;
int category;
};

View File

@ -21,9 +21,22 @@ struct msgq* msgq_new(struct rgn* init_rgn);
void* msgq_begin_send(struct msgq* mq, int type, size_t payload_size); void* msgq_begin_send(struct msgq* mq, int type, size_t payload_size);
void msgq_end_send(struct msgq* mq); void msgq_end_send(struct msgq* mq);
#define msgq_begin_send_typed(_mq, _ty) \
((struct _ty*) msgq_begin_send(_mq, _ty ## _TAG, sizeof(struct _ty)))
void msgq_begin_recv(struct msgq* mq); void msgq_begin_recv(struct msgq* mq);
void* msgq_recv1(struct msgq* mq, int* out_type); void* msgq_recv1(struct msgq* mq, int* out_type);
void msgq_end_recv(struct msgq* mq); void msgq_end_recv(struct msgq* mq);
// helper macros
#define msgq_begin_send_typed(_mq, ty) \
((struct ty*) msgq_begin_send(_mq, ty ## _TAG, sizeof(struct ty)))
#define MSGQ_RECV_ALL(_mq) \
int mqr__type; void* mqr__data; \
while ((mqr__data = msgq_recv1(_mq, &mqr__type)) != NULL) \
switch (mqr__type)
#define ON(ty, _body) \
case ty ## _TAG: { \
const struct ty* m = mqr__data; \
_body; \
}

View File

@ -3,6 +3,7 @@
#include "../util/region.h" #include "../util/region.h"
#include "../backend.h" #include "../backend.h"
#include "../concurrent/msgq.h" #include "../concurrent/msgq.h"
#include "../concurrent/msg.h"
#include <inttypes.h> #include <inttypes.h>
static const char* default_font_path(struct rgn* rgn) static const char* default_font_path(struct rgn* rgn)

View File

@ -22,9 +22,8 @@ int main(void)
ax_log(ax, "Got here\n"); ax_log(ax, "Got here\n");
bool shutdown = false;
ax__backend_wait_for_event(ax->bac); ax__backend_wait_for_event(ax->bac);
ax__backend_step(ax->bac, &shutdown); ax__backend_step(ax->bac);
//cleanup: //cleanup:
if (rv != 0) { if (rv != 0) {