caturday work: leak fixes, can now tell dooms to quit, nng util functions
This commit is contained in:
parent
7dbcf4bbb5
commit
e26e406f29
4 changed files with 114 additions and 18 deletions
|
@ -48,6 +48,7 @@ struct ControllerContext
|
||||||
struct ControllerActions
|
struct ControllerActions
|
||||||
{
|
{
|
||||||
int doomsToSpawn = 0;
|
int doomsToSpawn = 0;
|
||||||
|
bool quitAllDooms = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
void spawn_doom(ControllerContext &ctx)
|
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);
|
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)
|
void perform_actions(ControllerContext &ctx, const ControllerActions &actions)
|
||||||
{
|
{
|
||||||
if (actions.doomsToSpawn)
|
if (actions.doomsToSpawn)
|
||||||
|
@ -88,6 +107,12 @@ void perform_actions(ControllerContext &ctx, const ControllerActions &actions)
|
||||||
for (int i=0; i<actions.doomsToSpawn; ++i)
|
for (int i=0; i<actions.doomsToSpawn; ++i)
|
||||||
spawn_doom(ctx);
|
spawn_doom(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actions.quitAllDooms)
|
||||||
|
{
|
||||||
|
log_info("Telling all dooms to quit");
|
||||||
|
quit_all_dooms(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_on_dooms(ControllerContext &ctx)
|
void check_on_dooms(ControllerContext &ctx)
|
||||||
|
@ -122,10 +147,10 @@ void do_networking(ControllerContext &ctx)
|
||||||
nng_msg *msg = nullptr;
|
nng_msg *msg = nullptr;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if ((res = nng_msg_alloc(&msg, sizeof(dmt_t))))
|
if ((res = nng_msg_alloc(&msg, 0)))
|
||||||
dp_nng_fatal("ctrl/alloc", res);
|
dp_nng_fatal("ctrl/alloc", res);
|
||||||
|
|
||||||
if ((res = nng_msg_append_u16(msg, DP_MT_DoomReady)))
|
if ((res = nng_msg_append_u16(msg, DP_MT_RunDoom)))
|
||||||
dp_nng_fatal("ctrl/msg", res);
|
dp_nng_fatal("ctrl/msg", res);
|
||||||
|
|
||||||
if ((res = nng_sendmsg(ctx.pub, msg, 0)))
|
if ((res = nng_sendmsg(ctx.pub, msg, 0)))
|
||||||
|
@ -209,11 +234,14 @@ ControllerActions run_ui(ControllerContext &ctx)
|
||||||
|
|
||||||
ImGui::SliderInt("Layout columns##columns", &ctx.columns, 1, 32, "%d", ImGuiSliderFlags_AlwaysClamp);
|
ImGui::SliderInt("Layout columns##columns", &ctx.columns, 1, 32, "%d", ImGuiSliderFlags_AlwaysClamp);
|
||||||
|
|
||||||
ImGui::SliderInt("##dooms", &doomsToSpawn, 1, 16, "%d", ImGuiSliderFlags_AlwaysClamp);
|
ImGui::SliderInt("##dooms", &doomsToSpawn, 1, 256, "%d", ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_Logarithmic);
|
||||||
aprintf(strbuf, "Spawn %d more doom%s###spawnmore", doomsToSpawn, doomsToSpawn > 1 ? "s" : "");
|
aprintf(strbuf, "Spawn %d more doom%s###spawnmore", doomsToSpawn, doomsToSpawn > 1 ? "s" : "");
|
||||||
if (ImGui::SameLine(); ImGui::Button(strbuf.data()))
|
if (ImGui::SameLine(); ImGui::Button(strbuf.data()))
|
||||||
result.doomsToSpawn = doomsToSpawn;
|
result.doomsToSpawn = doomsToSpawn;
|
||||||
|
|
||||||
|
if (ImGui::Button("Quit all Dooms"))
|
||||||
|
result.quitAllDooms = true;
|
||||||
|
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ DEF_DOOM_STATE_FUNC(do_doom_ready)
|
||||||
{
|
{
|
||||||
nng_msg *msg = NULL;
|
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);
|
dp_nng_fatal("doom/alloc", res);
|
||||||
|
|
||||||
if ((res = nng_msg_append_u16(msg, DP_MT_DoomReady)))
|
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
|
// Incoming Message | Next State
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
// DP_MT_RunDoom -> DP_DS_Running
|
// DP_MT_RunDoom -> DP_DS_Running
|
||||||
// DP_MT_QuitDoom -> DP_DS_Quit
|
// DP_MT_QuitDoom -> DP_DS_Quitting
|
||||||
// */none -> DP_DS_Ready
|
// */none -> DP_DS_Ready
|
||||||
{
|
{
|
||||||
nng_msg *msg = NULL;
|
nng_msg *msg = NULL;
|
||||||
|
|
||||||
if ((res = nng_msg_alloc(&msg, sizeof(int) + sizeof(doomid_t))))
|
if ((res = dp_recv_new_msg(ctx->sub, &msg)))
|
||||||
dp_nng_fatal("doom/alloc", res);
|
|
||||||
|
|
||||||
if ((res = nng_recvmsg(ctx->sub, &msg, 0)))
|
|
||||||
{
|
{
|
||||||
if (res != NNG_ETIMEDOUT)
|
if (res != NNG_ETIMEDOUT)
|
||||||
dp_nng_fatal("doom/recvmsg", res);
|
dp_nng_fatal("doom/recvmsg", res);
|
||||||
|
@ -67,6 +64,9 @@ DEF_DOOM_STATE_FUNC(do_doom_ready)
|
||||||
return 0;
|
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;
|
dmt_t mt = DP_MT_Invalid;
|
||||||
|
|
||||||
if ((res = nng_msg_trim_u16(msg, &mt)))
|
if ((res = nng_msg_trim_u16(msg, &mt)))
|
||||||
|
@ -80,7 +80,12 @@ DEF_DOOM_STATE_FUNC(do_doom_ready)
|
||||||
ctx->f = do_doom_running;
|
ctx->f = do_doom_running;
|
||||||
}
|
}
|
||||||
else if (mt == DP_MT_QuitDoom)
|
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;
|
return res;
|
||||||
|
@ -93,10 +98,35 @@ DEF_DOOM_STATE_FUNC(do_doom_running)
|
||||||
// Non-blocking receive of incoming messages.
|
// Non-blocking receive of incoming messages.
|
||||||
// Check if we should quit.
|
// Check if we should quit.
|
||||||
// Handle incoming input.
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +137,7 @@ int doom_loop(DoomContext *ctx)
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
while (ctx->state != DP_DS_Quit && res == 0)
|
while (ctx->state != DP_DS_Quitting && res == 0)
|
||||||
{
|
{
|
||||||
DP_DoomState prevState = ctx->state;
|
DP_DoomState prevState = ctx->state;
|
||||||
res = ctx->f(ctx);
|
res = ctx->f(ctx);
|
||||||
|
@ -123,6 +153,13 @@ int doom_loop(DoomContext *ctx)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
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");
|
log_info("doomsim starting");
|
||||||
|
|
||||||
std::optional<doomid_t> doomId;
|
std::optional<doomid_t> doomId;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "dp_common.h"
|
#include "dp_common.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <nng/protocol/pubsub0/pub.h>
|
#include <nng/protocol/pubsub0/pub.h>
|
||||||
#include <nng/protocol/pubsub0/sub.h>
|
#include <nng/protocol/pubsub0/sub.h>
|
||||||
|
@ -49,7 +50,7 @@ nng_socket make_ctrl_sub(const char *url)
|
||||||
if ((res = nng_sub0_open(&sock)))
|
if ((res = nng_sub0_open(&sock)))
|
||||||
dp_nng_fatal("make_ctrl_sub/nng_sub0_open", res);
|
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);
|
dp_nng_fatal("make_ctrl_sub/subscribe", res);
|
||||||
|
|
||||||
if ((res = nng_socket_set_ms(sock, NNG_OPT_RECVTIMEO, 100)))
|
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)))
|
if ((res = nng_sub0_open(&sock)))
|
||||||
dp_nng_fatal("make_doom_sub/nng_sub0_open", res);
|
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);
|
dp_nng_fatal("make_doom_sub/subscribe", res);
|
||||||
|
|
||||||
if ((res = nng_socket_set_ms(sock, NNG_OPT_RECVTIMEO, 100)))
|
if ((res = nng_socket_set_ms(sock, NNG_OPT_RECVTIMEO, 100)))
|
||||||
|
@ -96,8 +97,9 @@ nng_socket make_doom_sub(const char *url)
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *const DP_DoomState_Strings[DP_DS_COUNT] =
|
const char *const DP_DoomState_Strings[] =
|
||||||
{
|
{
|
||||||
|
"DoomState_Unknown",
|
||||||
"DoomState_Ready",
|
"DoomState_Ready",
|
||||||
"DoomState_Running",
|
"DoomState_Running",
|
||||||
"DoomState_Quit",
|
"DoomState_Quit",
|
||||||
|
@ -105,3 +107,27 @@ const char *const DP_DoomState_Strings[DP_DS_COUNT] =
|
||||||
|
|
||||||
_Static_assert(sizeof(DP_DoomState_Strings) / sizeof(DP_DoomState_Strings[0]) == DP_DS_COUNT,
|
_Static_assert(sizeof(DP_DoomState_Strings) / sizeof(DP_DoomState_Strings[0]) == DP_DS_COUNT,
|
||||||
"DP_DoomState enum and strings do not match up");
|
"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;
|
||||||
|
}
|
|
@ -42,7 +42,7 @@ typedef enum DP_DoomState
|
||||||
DP_DS_Unknown,
|
DP_DS_Unknown,
|
||||||
DP_DS_Ready,
|
DP_DS_Ready,
|
||||||
DP_DS_Running,
|
DP_DS_Running,
|
||||||
DP_DS_Quit,
|
DP_DS_Quitting,
|
||||||
DP_DS_COUNT,
|
DP_DS_COUNT,
|
||||||
} DP_DoomState;
|
} DP_DoomState;
|
||||||
|
|
||||||
|
@ -53,6 +53,11 @@ static inline const char *doomstate_str(DP_DoomState ds)
|
||||||
return DP_DoomState_Strings[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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue