diff options
author | pommicket <pommicket@gmail.com> | 2025-08-24 10:56:27 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2025-08-24 10:56:27 -0400 |
commit | 82f08e0d21520a6c673a2a4ee5737f12752db6c5 (patch) | |
tree | 9db5ce3b5256e0bd8dc6c3d36c0caa88026241f3 | |
parent | 8f5e37f02d9c9247461137edbdbce86e2d96ebb1 (diff) |
Show Macondo log
-rw-r--r-- | quacker/macondo.cpp | 50 | ||||
-rw-r--r-- | quacker/macondo.h | 12 | ||||
-rw-r--r-- | quacker/macondobackend.cpp | 14 | ||||
-rw-r--r-- | quacker/macondobackend.h | 1 |
4 files changed, 68 insertions, 9 deletions
diff --git a/quacker/macondo.cpp b/quacker/macondo.cpp index 0cd0021..8272dd4 100644 --- a/quacker/macondo.cpp +++ b/quacker/macondo.cpp @@ -10,6 +10,7 @@ #include <QLineEdit> #include <QMessageBox> #include <QOperatingSystemVersion> +#include <QPlainTextEdit> #include <QPushButton> #include <QSettings> #include <QSpinBox> @@ -45,6 +46,8 @@ Macondo::Macondo(Quackle::Game *game) : View() { connect(m_execPath, SIGNAL(editingFinished()), this, SLOT(execPathChanged())); m_solve = new QPushButton(tr("Solve")); m_solve->setDisabled(true); + m_log = new QPlainTextEdit; + //m_log->setReadOnly(true); QHBoxLayout *execPathLayout = new QHBoxLayout; execPathLayout->addWidget(execPathLabel); @@ -105,6 +108,7 @@ Macondo::Macondo(Quackle::Game *game) : View() { layout->addWidget(pegBox); layout->addWidget(endgameBox); layout->addWidget(m_solve); + layout->addWidget(m_log, 1); connect(m_solve, SIGNAL(clicked()), this, SLOT(solve())); } @@ -173,6 +177,7 @@ bool Macondo::simulate() { } if (isRunning()) stop(); + clearLog(); MacondoSimulateOptions options; return m_backend->simulate(options, m_movesFromKibitzer); } @@ -189,6 +194,7 @@ void Macondo::solve() { if (wasSolving) { emit stoppedSolver(); } else { + clearLog(); if (m_tilesUnseen > 7) { MacondoPreEndgameOptions options; options.endgamePlies = m_preEndgameMaxPlies->value(); @@ -230,6 +236,7 @@ void Macondo::gameChanged(Quackle::Game *game) { void Macondo::connectBackendSignals() { connect(m_backend, SIGNAL(gotMoves(const Quackle::MoveList &)), this, SLOT(gotMoves(const Quackle::MoveList &))); connect(m_backend, SIGNAL(statusMessage(const QString &)), this, SIGNAL(statusMessage(const QString &))); + connect(m_backend, SIGNAL(newLogOutput(const QByteArray &)), this, SLOT(newLogOutput(const QByteArray &))); } void Macondo::stop() { @@ -276,3 +283,46 @@ void Macondo::updateSolveButton() { m_solve->setDisabled(true); } } + +void Macondo::clearLog() { + m_log->clear(); + m_logANSIState = 0; +} + +void Macondo::newLogOutput(const QByteArray &text) { + // annoying stuff to handle incomplete UTF-8 at end of text + QByteArray logContents = m_logPartialUtf8; + logContents.append(text); + size_t completeUtf8Len = 0; + while (completeUtf8Len < logContents.length()) { + uint8_t firstByte = logContents.at(completeUtf8Len); + size_t codepointLen = (firstByte & 0xe0) == 0xc0 ? 2 + : (firstByte & 0xf0) == 0xe0 ? 3 + : (firstByte & 0xf8) == 0xf0 ? 4 : 1; + if (completeUtf8Len + codepointLen > logContents.length()) break; + completeUtf8Len += codepointLen; + } + m_logPartialUtf8 = QByteArray(text.constData() + completeUtf8Len, text.length() - completeUtf8Len); + // remove ANSI escape sequences (color/formatting codes) + std::string filteredText; + for (size_t i = 0; i < completeUtf8Len; i++) { + uint8_t byte = text.at(i); + if (m_logANSIState == 0 && byte == 0x1b) { + m_logANSIState = 1; + } else if (m_logANSIState == 1 && byte == '[') { + m_logANSIState = 2; + } else if (m_logANSIState == 2 && byte >= 0x20 && byte < 0x40) { + // continuation of ANSI escape sequence + } else if (m_logANSIState == 2 && byte >= 0x40 && byte < 0x80) { + // terminator for ANSI escape sequence + m_logANSIState = 0; + } else { + m_logANSIState = 0; + filteredText.push_back(byte); + } + } + m_log->moveCursor(QTextCursor::MoveOperation::End); + m_log->insertPlainText(QString::fromStdString(filteredText)); + m_log->moveCursor(QTextCursor::MoveOperation::End); + m_log->centerCursor(); +} diff --git a/quacker/macondo.h b/quacker/macondo.h index d56a577..a8a61b9 100644 --- a/quacker/macondo.h +++ b/quacker/macondo.h @@ -4,13 +4,14 @@ #include "view.h" #include "game.h" +class MacondoBackend; +struct MacondoInitOptions; +class MoveBox; class QCheckBox; class QPushButton; class QLineEdit; +class QPlainTextEdit; class QSpinBox; -class MacondoBackend; -struct MacondoInitOptions; -class MoveBox; class Macondo : public View { Q_OBJECT @@ -39,10 +40,12 @@ public slots: void gameChanged(Quackle::Game *game) override; void positionChanged(const Quackle::GamePosition *position) override; private slots: + void newLogOutput(const QByteArray &text); void gotMoves(const Quackle::MoveList &moves); void execPathChanged(); void chooseExecPath(); private: + void clearLog(); void setExecPath(const std::string &); void connectBackendSignals(); bool checkExecPath(); @@ -66,11 +69,14 @@ private: QSpinBox *m_preEndgameMaxPlies; QPushButton *m_solve; + QPlainTextEdit *m_log; + QByteArray m_logPartialUtf8; Quackle::Game *m_game; MacondoBackend *m_backend; Quackle::MoveList m_movesFromKibitzer; int m_tilesUnseen = 93; int m_viewingPlyNumber = 0; + int m_logANSIState = 0; bool m_anyUpdates = false; bool m_isSolving = false; std::unique_ptr<MacondoInitOptions> m_initOptions; diff --git a/quacker/macondobackend.cpp b/quacker/macondobackend.cpp index 6ec1e85..628066a 100644 --- a/quacker/macondobackend.cpp +++ b/quacker/macondobackend.cpp @@ -413,15 +413,17 @@ void MacondoBackend::timer() { bool anyNewOutput = false; if (m_process) { QByteArray data = m_process->readAllStandardError(); - anyNewOutput |= data.size() != 0; - fprintf(stderr,"%.*s",data.size(), data.constData()); + if (data.size()) { + anyNewOutput = true; + emit newLogOutput(data); + } + //fprintf(stderr,"%.*s",data.size(), data.constData()); m_processStderr.append(data); data = m_process->readAllStandardOutput(); - anyNewOutput |= data.size() != 0; m_processOutput.append(data); - if (true) { - // print Macondo stdout - printf("%.*s",data.size(), data.constData()); + if (data.size()) { + anyNewOutput = true; + emit newLogOutput(data); } fflush(stdout); } diff --git a/quacker/macondobackend.h b/quacker/macondobackend.h index 981ab1e..28ba65c 100644 --- a/quacker/macondobackend.h +++ b/quacker/macondobackend.h @@ -50,6 +50,7 @@ public: signals: void gotMoves(const Quackle::MoveList &moves); void statusMessage(const QString &message); + void newLogOutput(const QByteArray &log); private slots: void processStarted(); void processFinished(int, QProcess::ExitStatus); |