fwt_software/include/fgc/ui/TuiUi.h

55 lines
1.6 KiB
C++

#pragma once
#include "fgc/ui/IUserInterface.h"
#include <atomic>
#include <deque>
#include <mutex>
#include <string>
#include <thread>
namespace ftxui {
class ScreenInteractive;
}
namespace fgc {
// Full-screen FTXUI dashboard: sectioned, colored panels (gimbal, sensors,
// camera, connectivity) updated in place, a scrolling log pane fed from a Logger
// sink, and a nano-style key bar. Pure observer + command source: it renders the
// UiSnapshot it pulls and forwards keystrokes/typed commands to the sink.
//
// Compiled only when FGC_WITH_TUI; the Application falls back to HeadlessUi
// otherwise.
class TuiUi : public IUserInterface {
public:
TuiUi();
~TuiUi() override;
void start(SnapshotFn snapshot, CommandSink sink) override;
void stop() override;
private:
void uiLoop(); // runs the FTXUI event loop (own thread)
void refreshLoop(); // posts redraw events at ~10 Hz (own thread)
void pushLog(LogLevel level, const std::string& line);
SnapshotFn snapshot_;
CommandSink sink_;
// Raw pointer to the loop thread's stack-local screen (ScreenInteractive is
// neither copyable nor movable, so it can't be a value/unique_ptr member).
// Set inside uiLoop(); read by stop()/refreshLoop() to Exit()/PostEvent().
std::atomic<ftxui::ScreenInteractive*> screen_{nullptr};
std::thread ui_thread_;
std::thread refresh_thread_;
std::atomic<bool> running_{false};
// Log ring buffer (newest last), filled by the Logger sink.
std::mutex log_mutex_;
std::deque<LogLine> log_;
static constexpr size_t kLogCap = 500;
};
} // namespace fgc