ctrl: register externally started dooms that introduce themselves

TODO: Check on those via kill(pid, 0) or store the last activity time in
DoomState and let dooms time out if they don't send more updates.
This commit is contained in:
oxmox 2023-02-19 12:46:17 +01:00
parent 9e857180be
commit e53023079e

View file

@ -64,6 +64,7 @@ void spawn_doom(ControllerContext &ctx)
// TODO: Close stdin and stdout? Leave them open for now to see the logging
// output.
// FIXME: this doesn't work with SDL :(
if (auto err = posix_spawn(&ds.id, DOOM_EXECUTABLE, nullptr, nullptr,
const_cast<char *const *>(argv), nullptr))
{
@ -77,9 +78,8 @@ void spawn_doom(ControllerContext &ctx)
if (!ds.texture)
dp_sdl_fatal("SDL_CreateTexture");
ctx.dooms.emplace_back(ds);
log_info("Spawned new doom, pid=%d", ds.id);
ctx.dooms.emplace_back(ds);
}
void end_all_dooms(ControllerContext &ctx)
@ -127,6 +127,8 @@ void check_on_dooms(ControllerContext &ctx)
{
pid_t pid = 0;
// This works for dooms forked from the controller, not for externally
// started dooms.
do
{
int wstatus = 0;
@ -153,13 +155,18 @@ void check_on_dooms(ControllerContext &ctx)
void do_networking(ControllerContext &ctx)
{
// Set to true if we receive at least on DP_DS_Ready DoomState update. Then
// a single DP_DC_RunDoom command is broadcast.
bool sendRunDoom = false;
// Limit the max time we spend doing network stuff.
static const auto MaxNetworkingTime = std::chrono::milliseconds(10);
auto tStart = std::chrono::steady_clock::now();
while (true)
{
if (auto elapsed = std::chrono::steady_clock::now() - tStart;
elapsed >= std::chrono::milliseconds(10))
elapsed >= MaxNetworkingTime)
{
break;
}
@ -179,6 +186,30 @@ void do_networking(ControllerContext &ctx)
{
auto msgDoomState = DP_NNG_BODY_AS(msg, MsgDoomState);
// Check if we know this doom. If it was externally started register
// it in ctx.dooms.
auto pid = msgDoomState->doomId;
auto dit = find_in_container(ctx.dooms, [pid] (const auto &ds) { return ds.id == pid; });
if (dit != std::end(ctx.dooms))
{
dit->state = msgDoomState->doomState;
}
else
{
DoomState ds;
ds.id = pid;
ds.state = msgDoomState->doomState;
ds.texture = SDL_CreateTexture(ctx.renderer, SDL_PIXELFORMAT_RGB888,
SDL_TEXTUREACCESS_STREAMING, DoomScreenWidth, DoomScreenHeight);
if (!ds.texture)
dp_sdl_fatal("SDL_CreateTexture");
log_info("Registered external doom, pid=%d", ds.id);
ctx.dooms.emplace_back(ds);
}
if (msgDoomState->doomState == DP_DS_Ready)
sendRunDoom = true;
}
@ -193,6 +224,8 @@ void do_networking(ControllerContext &ctx)
auto &ds = *dit;
SDL_UpdateTexture(ds.texture, nullptr, msgDoomFrame->frame, DoomFramePitch);
}
else
log_warn("Received DoomFrame from unregistered doom, pid=%d", pid);
}
nng_msg_free(msg);