refactor(console): unify lite + full-node console behind a pluggable executor
The two consoles were separate implementations (the rich full-node ConsoleTab and a
minimal RenderLiteConsoleTab). Introduce ConsoleCommandExecutor to abstract the only
real differences — command execution + log source — so both variants share the one rich
terminal (the lite console now gains selection, zoom, copy, and JSON-colored output).
- console_command_executor.{h,cpp}: interface + FullNodeConsoleExecutor (dragonxd log
ingestion + RPC command execution, result queue) and LiteConsoleExecutor (lite
diagnostics ring + backend runConsoleCommand/takeConsoleResult, connection/sync status).
- ConsoleTab::render() now takes a ConsoleCommandExecutor&; log ingestion, command
submission, and command results flow through it. The RPC command-reference popup and
the daemon/errors/rpc-trace/app filter toggles are gated on the executor's capabilities;
the toolbar status dot + a status header come from the executor.
- Safety preserved: `clear`/`cls` is intercepted as a view-only clear in the shared UI so
it is NEVER forwarded (the lite backend's `clear` wipes tx history); command output is
not persisted to diagnostics.
- App owns the executor (created per variant) and routes both NavPages to console_tab_;
lite_console_tab.{h,cpp} deleted.
Needs runtime verification of BOTH consoles (full-node RPC + lite: clear, seed/export
secrecy, sync status, command results).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
111
src/ui/windows/console_command_executor.h
Normal file
111
src/ui/windows/console_command_executor.h
Normal file
@@ -0,0 +1,111 @@
|
||||
// DragonX Wallet - ImGui Edition
|
||||
// Copyright 2024-2026 The Hush Developers
|
||||
// Released under the GPLv3
|
||||
//
|
||||
// ConsoleCommandExecutor — the pluggable backend behind the shared ConsoleTab UI. It
|
||||
// abstracts the only real differences between the full-node console (dragonxd log + RPC
|
||||
// command execution) and the lite console (lite diagnostics ring + backend command),
|
||||
// so both variants use one rich terminal widget instead of two implementations.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace dragonx {
|
||||
class App;
|
||||
namespace ui {
|
||||
|
||||
using ConsoleAddLineFn = std::function<void(const std::string&, ImU32)>;
|
||||
|
||||
struct ConsoleStatusLine {
|
||||
std::string text;
|
||||
ImU32 color = IM_COL32(200, 200, 200, 255);
|
||||
bool pulse = false; // animate the toolbar dot (starting/connecting)
|
||||
};
|
||||
|
||||
class ConsoleCommandExecutor {
|
||||
public:
|
||||
virtual ~ConsoleCommandExecutor() = default;
|
||||
|
||||
// True when commands can be run (RPC connected / lite wallet open).
|
||||
virtual bool isReady() const = 0;
|
||||
// A command is currently in flight (input is disabled while true).
|
||||
virtual bool busy() const { return false; }
|
||||
// Submit a user command for async execution. The UI has already echoed "> cmd" and
|
||||
// handled the built-ins (clear/help/quit). Results arrive later via pollResult().
|
||||
virtual void submit(const std::string& cmd) = 0;
|
||||
// Pop one completed command result (raw text + error flag) if available; the UI
|
||||
// formats/colors it via FormatConsoleRpcResultLines. Returns false if none pending.
|
||||
virtual bool pollResult(std::string& result, bool& isError) = 0;
|
||||
|
||||
// Pull any new passive log lines (daemon/xmrig output, or the lite diagnostics ring)
|
||||
// and hand each to `add`. Called once per frame.
|
||||
virtual void pollLogLines(const ConsoleAddLineFn& add) { (void)add; }
|
||||
|
||||
// UI-chrome capabilities.
|
||||
virtual bool hasRpcReference() const { return false; } // show the RPC command-reference popup
|
||||
virtual bool hasLogFilters() const { return false; } // show daemon/errors/rpc-trace/app filters
|
||||
|
||||
// Print the backend-appropriate `help` output via `add`.
|
||||
virtual void printHelp(const ConsoleAddLineFn& add) = 0;
|
||||
|
||||
// Extra status lines drawn above the toolbar (lite shows sync + last error).
|
||||
virtual std::vector<ConsoleStatusLine> statusLines() const { return {}; }
|
||||
// Short status shown in the toolbar (daemon state / lite connection). Empty text =>
|
||||
// the toolbar shows its generic "no daemon" label.
|
||||
virtual ConsoleStatusLine toolbarStatus() const { return {}; }
|
||||
};
|
||||
|
||||
// ── Full-node: dragonxd log ingestion + RPC command execution ────────────────
|
||||
class FullNodeConsoleExecutor : public ConsoleCommandExecutor {
|
||||
public:
|
||||
explicit FullNodeConsoleExecutor(App* app) : app_(app) {}
|
||||
|
||||
bool isReady() const override;
|
||||
void submit(const std::string& cmd) override;
|
||||
bool pollResult(std::string& result, bool& isError) override;
|
||||
void pollLogLines(const ConsoleAddLineFn& add) override;
|
||||
bool hasRpcReference() const override { return true; }
|
||||
bool hasLogFilters() const override { return true; }
|
||||
void printHelp(const ConsoleAddLineFn& add) override;
|
||||
ConsoleStatusLine toolbarStatus() const override;
|
||||
|
||||
private:
|
||||
App* app_;
|
||||
size_t last_daemon_output_size_ = 0;
|
||||
size_t last_xmrig_output_size_ = 0;
|
||||
int last_daemon_state_ = -1; // daemon::EmbeddedDaemon::State as int
|
||||
bool last_rpc_connected_ = false;
|
||||
std::deque<std::pair<std::string, bool>> results_; // {text, isError}
|
||||
std::mutex results_mutex_;
|
||||
};
|
||||
|
||||
// ── Lite: diagnostics ring + backend console command ─────────────────────────
|
||||
class LiteConsoleExecutor : public ConsoleCommandExecutor {
|
||||
public:
|
||||
explicit LiteConsoleExecutor(App* app) : app_(app) {}
|
||||
|
||||
bool isReady() const override;
|
||||
bool busy() const override;
|
||||
void submit(const std::string& cmd) override;
|
||||
bool pollResult(std::string& result, bool& isError) override;
|
||||
void pollLogLines(const ConsoleAddLineFn& add) override;
|
||||
void printHelp(const ConsoleAddLineFn& add) override;
|
||||
std::vector<ConsoleStatusLine> statusLines() const override;
|
||||
ConsoleStatusLine toolbarStatus() const override;
|
||||
|
||||
private:
|
||||
App* app_;
|
||||
std::uint64_t diag_gen_ = static_cast<std::uint64_t>(-1); // last consumed diagnostics generation
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
Reference in New Issue
Block a user