Say when a paused dashboard was frozen, so it cannot be mistaken for a hung one
This commit is contained in:
parent
e2bdc8debf
commit
575e3c590b
|
|
@ -3,6 +3,7 @@
|
|||
#include "fgc/ui/IUserInterface.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
|
@ -46,7 +47,15 @@ private:
|
|||
std::atomic<bool> running_{false};
|
||||
// When set, the 100ms auto-redraw is suspended so the screen holds still and
|
||||
// the operator can select/copy text (terminals drop a selection on repaint).
|
||||
// Display freeze (the `p` key), for selecting text out of the pane. While
|
||||
// set, refreshLoop() stops posting redraws, so the frame on screen ages.
|
||||
// paused_at_ is when it was frozen, so the badge can say how stale it is.
|
||||
std::atomic<bool> paused_{false};
|
||||
// Wall-clock time of the freeze, "HH:MM:SS", shown in the badge. Captured
|
||||
// once: the badge must stay truthful WITHOUT a repaint, because repainting
|
||||
// would pull the live snapshot and unfreeze what the pause is holding still.
|
||||
std::string paused_at_hms_;
|
||||
static std::string nowHms();
|
||||
// True while the gimbal overlay is open, so the refresh loop can periodically
|
||||
// re-pull a firmware dump (keeps the tracking counters ticking without 'd').
|
||||
std::atomic<bool> gimbal_overlay_open_{false};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "fgc/ui/TuiUi.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "fgc/ChannelTopics.h"
|
||||
|
||||
#include "fgc/DumpParser.h"
|
||||
|
|
@ -1247,13 +1249,30 @@ void TuiUi::pushLog(LogLevel level, const std::string& line) {
|
|||
}
|
||||
}
|
||||
|
||||
// Wall-clock time the frame was frozen at, "HH:MM:SS". Captured once, because
|
||||
// the badge must not need a repaint to stay truthful - repainting would unfreeze
|
||||
// the very data the pause is holding still.
|
||||
std::string TuiUi::nowHms() {
|
||||
const auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
std::tm tm{};
|
||||
localtime_r(&t, &tm);
|
||||
char buf[16];
|
||||
std::strftime(buf, sizeof(buf), "%H:%M:%S", &tm);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void TuiUi::refreshLoop() {
|
||||
using namespace std::chrono_literals;
|
||||
auto last_dump = std::chrono::steady_clock::now();
|
||||
while (running_) {
|
||||
std::this_thread::sleep_for(100ms);
|
||||
if (!running_) break;
|
||||
if (paused_) continue; // frozen for text selection; don't repaint
|
||||
// Frozen for text selection: do NOT repaint. Re-rendering would pull the
|
||||
// live snapshot and the numbers would keep moving under the cursor,
|
||||
// which is precisely what the freeze exists to prevent. The badge
|
||||
// carries the wall-clock time of the freeze instead, so the frame says
|
||||
// how old it is without having to be redrawn to say it.
|
||||
if (paused_) continue;
|
||||
// While the gimbal overlay is open, re-pull a firmware dump every ~3s so
|
||||
// the encoder-tracking counters stay current without pressing 'd'.
|
||||
if (gimbal_overlay_open_.load() && sink_ &&
|
||||
|
|
@ -1332,7 +1351,15 @@ void TuiUi::uiLoop() {
|
|||
text(" " + s.header.tower + " ") | bold,
|
||||
text("build " + s.header.build) | dim,
|
||||
filler(),
|
||||
(paused_ ? text(" PAUSED ") | color(Color::Black) | bgcolor(Color::Yellow) | bold
|
||||
// A frozen frame has to say that it is frozen, and for how long.
|
||||
// Without the age it is indistinguishable from a hung program: the
|
||||
// numbers simply stop, which during a multi-minute home reads as a
|
||||
// crash. Costing 15 minutes of "is it stuck?" is how this got added.
|
||||
// Says WHEN it froze, not just that it is frozen. Without the time a
|
||||
// held frame is indistinguishable from a hung program - the numbers
|
||||
// simply stop - which during a multi-minute home reads as a crash.
|
||||
(paused_ ? text(" PAUSED @" + paused_at_hms_ + " ")
|
||||
| color(Color::Black) | bgcolor(Color::Yellow) | bold
|
||||
: text("")),
|
||||
text(" " + mode + " ") | (s.header.live ? color(Color::Green) : color(Color::Yellow)) | bold,
|
||||
text(" up " + std::to_string(s.header.uptime_ms / 1000) + "s ") | dim,
|
||||
|
|
@ -1649,6 +1676,7 @@ void TuiUi::uiLoop() {
|
|||
}
|
||||
if (c == "p") { // freeze/unfreeze the live refresh so text can be selected
|
||||
paused_ = !paused_;
|
||||
if (paused_) paused_at_hms_ = nowHms();
|
||||
return true; // this keypress redraws once so the indicator updates
|
||||
}
|
||||
if (overlay == Overlay::Help) { // vim-style section nav while help is open
|
||||
|
|
|
|||
Loading…
Reference in New Issue