From 7ff4794df7632bb4b293681e01867ba2d1a20d4c Mon Sep 17 00:00:00 2001 From: Milo Turner Date: Thu, 27 Feb 2020 10:40:37 -0500 Subject: [PATCH] [backend,sdl] backend uses pub/sub to push events to main thread --- src/backend.h | 1 + src/backend/sdl.c | 61 +++++++++++++++++++++++++--------------- src/concurrent/msg.enums | 9 +++--- src/concurrent/msg.h | 5 ++++ test/main.c | 38 ++++++++++++++++++------- 5 files changed, 77 insertions(+), 37 deletions(-) diff --git a/src/backend.h b/src/backend.h index 3921899..c0dd1ef 100644 --- a/src/backend.h +++ b/src/backend.h @@ -20,6 +20,7 @@ int ax__backend_new( const char** out_err); struct msgq* ax__backend_msgq(struct ax_backend*); +struct sub* ax__backend_sub_events(struct ax_backend*, struct rgn* dst_rgn); bool ax__backend_is_shutdown(struct ax_backend*); void ax__backend_wait_for_event(struct ax_backend*); diff --git a/src/backend/sdl.c b/src/backend/sdl.c index b720e99..9f74bd9 100644 --- a/src/backend/sdl.c +++ b/src/backend/sdl.c @@ -4,8 +4,9 @@ #include "../util.h" #include "../util/region.h" #include "../util/functions.h" -#include "../concurrent/msgq.h" #include "../concurrent/msg.h" +#include "../concurrent/msgq.h" +#include "../concurrent/pubsub.h" #include #include #include @@ -22,6 +23,7 @@ size_t ax__backend_desired_region_size = MEDIUM; struct ax_backend { struct rgn* rgn; struct msgq* inbox; + struct pubsub* events; bool shutdown; struct window_list* windows; }; @@ -52,6 +54,7 @@ int ax__backend_new( bac->rgn = init_rgn; bac->inbox = msgq_new(init_rgn); + bac->events = pubsub_new(init_rgn); bac->shutdown = false; bac->windows = NULL; @@ -80,6 +83,11 @@ struct msgq* ax__backend_msgq(struct ax_backend* bac) return bac->inbox; } +struct sub* ax__backend_sub_events(struct ax_backend* bac, struct rgn* dst_rgn) +{ + return sub_new(dst_rgn, bac->events); +} + bool ax__backend_is_shutdown(struct ax_backend* bac) { return bac->shutdown; @@ -110,7 +118,7 @@ struct window_args_list { static void load_fonts(struct ax_backend* bac, struct font_list* fl); static void make_windows(struct ax_backend* bac, struct window_args_list* wl); -static void handle_events(void); +static void handle_events(struct ax_backend* bac); static void render_windows(struct window_list* wl); void ax__backend_step(struct ax_backend* bac) @@ -169,32 +177,12 @@ void ax__backend_step(struct ax_backend* bac) load_fonts(bac, fonts); make_windows(bac, ax__reverse_list(windows)); render_windows(bac->windows); - handle_events(); + handle_events(bac); rgn_cleanup(&tmp_rgn); // printf("ping. %zu message(s)\n", nmsg); } -/* ----------------------------------------------------------------------------- - * Event handling - * -------------------------------------------------------------------------- */ - -static void handle_events(void) -{ - SDL_Event ev; - while (SDL_PollEvent(&ev)) { - switch (ev.type) { - case SDL_QUIT: - printf("pls quit...\n"); - break; - - default: - printf("some event of type: %d\n", ev.type); - break; - } - } -} - /* ----------------------------------------------------------------------------- * Fonts * -------------------------------------------------------------------------- */ @@ -320,3 +308,30 @@ static void render_windows(struct window_list* wl) SDL_RenderPresent(r); } } + +/* ----------------------------------------------------------------------------- + * Event handling + * -------------------------------------------------------------------------- */ + +static void handle_events(struct ax_backend* bac) +{ + SDL_Event ev; + while (SDL_PollEvent(&ev)) { + switch (ev.type) { + case SDL_QUIT: + for (struct window_list* wl = bac->windows; + wl != NULL; + wl = wl->next) + { + pubsub_begin_pub_typed(bac->events, ax_msg_window_closed) + ->win = wl->win; + pubsub_end_pub(bac->events); + } + break; + + default: + //printf("some event of type: %d\n", ev.type); + break; + } + } +} diff --git a/src/concurrent/msg.enums b/src/concurrent/msg.enums index 9b4c139..cd6e29b 100644 --- a/src/concurrent/msg.enums +++ b/src/concurrent/msg.enums @@ -1,4 +1,5 @@ -[msg (ax_msg_shutdown_TAG "shutdown") - (ax_msg_load_font_TAG "load_font") - (ax_msg_theme_loaded_TAG "theme_loaded") - (ax_msg_make_window_TAG "make_window")] +[msg (ax_msg_shutdown_TAG "shutdown") + (ax_msg_load_font_TAG "load_font") + (ax_msg_theme_loaded_TAG "theme_loaded") + (ax_msg_make_window_TAG "make_window") + (ax_msg_window_closed_TAG "window_closed")] diff --git a/src/concurrent/msg.h b/src/concurrent/msg.h index ef411ca..3e94fc4 100644 --- a/src/concurrent/msg.h +++ b/src/concurrent/msg.h @@ -11,6 +11,7 @@ enum { ax_msg_load_font_TAG, ax_msg_theme_loaded_TAG, ax_msg_make_window_TAG, + ax_msg_window_closed_TAG, }; struct ax_msg_shutdown { @@ -33,6 +34,10 @@ struct ax_msg_make_window { int flags; }; +struct ax_msg_window_closed { + struct ax_window* win; +}; + static inline const char* ax__msg_name(int val) { #ifdef IMPOSSIBLE diff --git a/test/main.c b/test/main.c index 7b8cc87..346d72b 100644 --- a/test/main.c +++ b/test/main.c @@ -6,10 +6,20 @@ #include "../src/ctxt.h" #include "../src/backend.h" +#include "../src/util/region.h" +#include "../src/concurrent/msg.h" +#include "../src/concurrent/pubsub.h" + +struct rgn* rgn = NULL; struct ax_ctxt* ax = NULL; static void cleanup() { + if (rgn != NULL) { + rgn_cleanup(rgn); + rgn = NULL; + } + ax_free(ax); ax = NULL; } @@ -45,6 +55,8 @@ int main(void) ax = ax_new(); ax_set_logger(ax, fileno(stdout), false); + rgn = rgn_bootstrap_new(SMALL); + int rv = 0; #define GUARD(f) if ((rv = f) != 0) goto ax_fail; @@ -56,20 +68,26 @@ int main(void) GUARD(ax_select_theme(ax, thm)); GUARD(ax_select_window(ax, win)); - usleep(1000 * 1000 * 2); - /* - struct ax_evt evt; + struct sub* ev_sub = ax__backend_sub_events(ax->bac, rgn); + for (bool quit = false; !quit; ) { + sub_begin_recv_and_wait(ev_sub); + SUB_RECV_ALL(ev_sub) { - for (;;) { - ax_wait_evt_avail(ax); - while (ax_poll_evt(ax, &evt)) { - if (evt.ty == AX_EVT_THEME_LOADED && evt.arg.theme == thm) { - printf("The font finished loading!\n"); - } + ON(ax_msg_window_closed, + { + if (m.win == win) { + quit = true; + } + break; + }); + + default: + printf("got a message: %s\n", ax__msg_name(m_type)); + break; } + sub_end_recv(ev_sub); } - */ cleanup(); return 0;