diff --git a/src/doompanning.cc b/src/doompanning.cc index 0ce2ef6..43d7bc0 100644 --- a/src/doompanning.cc +++ b/src/doompanning.cc @@ -48,6 +48,7 @@ struct ControllerContext struct ControllerActions { int doomsToSpawn = 0; + bool quitAllDooms = false; }; void spawn_doom(ControllerContext &ctx) @@ -80,6 +81,24 @@ void spawn_doom(ControllerContext &ctx) log_info("Spawned doom#%zu, pid=%d", ds.id, ds.pid); } +void quit_all_dooms(ControllerContext &ctx) +{ + // Publish { DP_MT_QuitDoom, doomid }. + { + nng_msg *msg = nullptr; + int res = 0; + + if ((res = nng_msg_alloc(&msg, 0))) + dp_nng_fatal("ctrl/alloc", res); + + if ((res = nng_msg_append_u16(msg, DP_MT_QuitDoom))) + dp_nng_fatal("ctrl/msg", res); + + if ((res = nng_sendmsg(ctx.pub, msg, 0))) + dp_nng_fatal("ctrl/sendmsg", res); + } +} + void perform_actions(ControllerContext &ctx, const ControllerActions &actions) { if (actions.doomsToSpawn) @@ -88,6 +107,12 @@ void perform_actions(ControllerContext &ctx, const ControllerActions &actions) for (int i=0; i 1 ? "s" : ""); if (ImGui::SameLine(); ImGui::Button(strbuf.data())) result.doomsToSpawn = doomsToSpawn; + if (ImGui::Button("Quit all Dooms")) + result.quitAllDooms = true; + ImGui::PopItemWidth(); ImGui::End(); diff --git a/src/doomsim.cc b/src/doomsim.cc index c5695f9..9e8cec5 100644 --- a/src/doomsim.cc +++ b/src/doomsim.cc @@ -35,7 +35,7 @@ DEF_DOOM_STATE_FUNC(do_doom_ready) { nng_msg *msg = NULL; - if ((res = nng_msg_alloc(&msg, sizeof(dmt_t) + sizeof(doomid_t)))) + if ((res = nng_msg_alloc(&msg, 0))) dp_nng_fatal("doom/alloc", res); if ((res = nng_msg_append_u16(msg, DP_MT_DoomReady))) @@ -51,15 +51,12 @@ DEF_DOOM_STATE_FUNC(do_doom_ready) // Incoming Message | Next State // ------------------------------- // DP_MT_RunDoom -> DP_DS_Running - // DP_MT_QuitDoom -> DP_DS_Quit + // DP_MT_QuitDoom -> DP_DS_Quitting // */none -> DP_DS_Ready { nng_msg *msg = NULL; - if ((res = nng_msg_alloc(&msg, sizeof(int) + sizeof(doomid_t)))) - dp_nng_fatal("doom/alloc", res); - - if ((res = nng_recvmsg(ctx->sub, &msg, 0))) + if ((res = dp_recv_new_msg(ctx->sub, &msg))) { if (res != NNG_ETIMEDOUT) dp_nng_fatal("doom/recvmsg", res); @@ -67,6 +64,9 @@ DEF_DOOM_STATE_FUNC(do_doom_ready) return 0; } + auto len = nng_msg_len(msg); + log_trace("do_doom_ready received message of size %zu", len); + dmt_t mt = DP_MT_Invalid; if ((res = nng_msg_trim_u16(msg, &mt))) @@ -80,7 +80,12 @@ DEF_DOOM_STATE_FUNC(do_doom_ready) ctx->f = do_doom_running; } else if (mt == DP_MT_QuitDoom) - ctx->state = DP_DS_Quit; + // TODO: pop off the doomid and check against ours. + // TODO: add a QuitAllDooms message + ctx->state = DP_DS_Quitting; + + // No error on receiving different message types because other dooms + // might get readied or be told to quit. } return res; @@ -93,10 +98,35 @@ DEF_DOOM_STATE_FUNC(do_doom_running) // Non-blocking receive of incoming messages. // Check if we should quit. // Handle incoming input. + // Let doom render a new frame. + // Publish the frame. - // Let doom render a new frame + int res = 0; + nng_msg *msg = NULL; - // Publish the frame + // FIXME: this is blocking while testing things + if ((res = dp_recv_new_msg_nonblock(ctx->sub, &msg))) + { + if (res != NNG_ETIMEDOUT && res != NNG_EAGAIN) + dp_nng_fatal("doom/recvmsg", res); + + return 0; + } + + auto len = nng_msg_len(msg); + log_trace("do_doom_running received message of size %zu", len); + + dmt_t mt = DP_MT_Invalid; + + if ((res = nng_msg_trim_u16(msg, &mt))) + dp_nng_fatal("doom/msg_trim", res); + + nng_msg_free(msg); + + if (mt == DP_MT_QuitDoom) + ctx->state = DP_DS_Quitting; + + // Otherwise stay in running state return 0; } @@ -107,7 +137,7 @@ int doom_loop(DoomContext *ctx) int res = 0; - while (ctx->state != DP_DS_Quit && res == 0) + while (ctx->state != DP_DS_Quitting && res == 0) { DP_DoomState prevState = ctx->state; res = ctx->f(ctx); @@ -123,6 +153,13 @@ int doom_loop(DoomContext *ctx) int main(int argc, char *argv[]) { +#ifndef NDEBUG + log_set_level(LOG_TRACE); +#else + log_set_level(LOG_DEBUG); +#endif + log_set_level(LOG_DEBUG); // FIXME: silence! + log_info("doomsim starting"); std::optional doomId; diff --git a/src/dp_common.c b/src/dp_common.c index e882580..41451bb 100644 --- a/src/dp_common.c +++ b/src/dp_common.c @@ -1,5 +1,6 @@ #include "dp_common.h" +#include #include #include #include @@ -49,7 +50,7 @@ nng_socket make_ctrl_sub(const char *url) if ((res = nng_sub0_open(&sock))) dp_nng_fatal("make_ctrl_sub/nng_sub0_open", res); - if ((res = nng_socket_set_string(sock, NNG_OPT_SUB_SUBSCRIBE, ""))) + if ((res = nng_setopt(sock, NNG_OPT_SUB_SUBSCRIBE, "", 0))) dp_nng_fatal("make_ctrl_sub/subscribe", res); if ((res = nng_socket_set_ms(sock, NNG_OPT_RECVTIMEO, 100))) @@ -84,7 +85,7 @@ nng_socket make_doom_sub(const char *url) if ((res = nng_sub0_open(&sock))) dp_nng_fatal("make_doom_sub/nng_sub0_open", res); - if ((res = nng_socket_set_string(sock, NNG_OPT_SUB_SUBSCRIBE, ""))) + if ((res = nng_setopt(sock, NNG_OPT_SUB_SUBSCRIBE, "", 0))) dp_nng_fatal("make_doom_sub/subscribe", res); if ((res = nng_socket_set_ms(sock, NNG_OPT_RECVTIMEO, 100))) @@ -96,12 +97,37 @@ nng_socket make_doom_sub(const char *url) return sock; } -const char *const DP_DoomState_Strings[DP_DS_COUNT] = +const char *const DP_DoomState_Strings[] = { + "DoomState_Unknown", "DoomState_Ready", "DoomState_Running", "DoomState_Quit", }; _Static_assert(sizeof(DP_DoomState_Strings) / sizeof(DP_DoomState_Strings[0]) == DP_DS_COUNT, - "DP_DoomState enum and strings do not match up"); \ No newline at end of file + "DP_DoomState enum and strings do not match up"); + +int dp_recv_new_msg(nng_socket sock, nng_msg **msg_ptr) +{ + return dp_recv_new_msg_flags(sock, msg_ptr, 0); +} + +int dp_recv_new_msg_nonblock(nng_socket sock, nng_msg **msg_ptr) +{ + return dp_recv_new_msg_flags(sock, msg_ptr, NNG_FLAG_NONBLOCK); +} + +int dp_recv_new_msg_flags(nng_socket sock, nng_msg **msg_ptr, int flags) +{ + assert(msg_ptr); + int res = 0; + + if ((res = nng_recvmsg(sock, msg_ptr, flags))) + { + nng_msg_free(*msg_ptr); + *msg_ptr = NULL; + } + + return res; +} \ No newline at end of file diff --git a/src/dp_common.h b/src/dp_common.h index 2535f0a..8670a28 100644 --- a/src/dp_common.h +++ b/src/dp_common.h @@ -42,7 +42,7 @@ typedef enum DP_DoomState DP_DS_Unknown, DP_DS_Ready, DP_DS_Running, - DP_DS_Quit, + DP_DS_Quitting, DP_DS_COUNT, } DP_DoomState; @@ -53,6 +53,11 @@ static inline const char *doomstate_str(DP_DoomState ds) return DP_DoomState_Strings[ds]; } +int dp_recv_new_msg(nng_socket sock, nng_msg **msg_ptr); +int dp_recv_new_msg_nonblock(nng_socket sock, nng_msg **msg_ptr); +int dp_recv_new_msg_flags(nng_socket sock, nng_msg **msg_ptr, int flags); + + #ifdef __cplusplus } #endif