implement logging of arena states
This commit is contained in:
@@ -1,13 +1,69 @@
|
||||
#include "BalancingWindow.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QFile>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QTextStream>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "ConfigLoader.h"
|
||||
#include "InspectWindow.h"
|
||||
#include "VisualsLoader.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// Escapes characters that would break a markdown table cell.
|
||||
QString escapeCell(const QString& text)
|
||||
{
|
||||
QString escaped = text;
|
||||
escaped.replace("|", "\\|");
|
||||
return escaped;
|
||||
}
|
||||
|
||||
QString stateText(ArenaWidget::State state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case ArenaWidget::State::NotStarted:
|
||||
return QStringLiteral("not started");
|
||||
case ArenaWidget::State::Running:
|
||||
return QStringLiteral("running");
|
||||
case ArenaWidget::State::Ended:
|
||||
return QStringLiteral("ended");
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Team column header: "[WON] Name — threat N", matching the arena widget.
|
||||
QString teamHeaderCell(const ArenaStatus& status, int teamIndex)
|
||||
{
|
||||
const ArenaStatus::TeamStatus& team = status.teams[teamIndex];
|
||||
QString header = QString::fromStdString(team.name);
|
||||
if (status.finished && status.winnerTeam == teamIndex)
|
||||
{
|
||||
header = QStringLiteral("[WON] ") + header;
|
||||
}
|
||||
header += QStringLiteral(" - threat %1").arg(QString::number(team.threatLevel, 'f', 0));
|
||||
return escapeCell(header);
|
||||
}
|
||||
|
||||
// Single entry line: "surviving/total DisplayName [L<level>]", matching the arena widget.
|
||||
QString entryCell(const ArenaStatus::Entry& entry)
|
||||
{
|
||||
QString cell = QString("%1/%2 %3")
|
||||
.arg(entry.surviving)
|
||||
.arg(entry.total)
|
||||
.arg(QString::fromStdString(entry.displayName));
|
||||
if (entry.level.has_value())
|
||||
{
|
||||
cell += QStringLiteral(" L%1").arg(entry.level.value());
|
||||
}
|
||||
return escapeCell(cell);
|
||||
}
|
||||
}
|
||||
|
||||
BalancingWindow::BalancingWindow(const BalancingConfig& balancingConfig,
|
||||
GameConfig gameConfig,
|
||||
const std::string& configDir,
|
||||
@@ -31,13 +87,16 @@ BalancingWindow::BalancingWindow(const BalancingConfig& balancingConfig,
|
||||
QHBoxLayout* buttonRow = new QHBoxLayout();
|
||||
m_reloadButton = new QPushButton(tr("Reload Config"), this);
|
||||
m_startAllButton = new QPushButton(tr("Start All"), this);
|
||||
m_logButton = new QPushButton(tr("Log"), this);
|
||||
buttonRow->addWidget(m_reloadButton);
|
||||
buttonRow->addWidget(m_startAllButton);
|
||||
buttonRow->addWidget(m_logButton);
|
||||
buttonRow->addStretch();
|
||||
mainLayout->addLayout(buttonRow);
|
||||
|
||||
connect(m_reloadButton, &QPushButton::clicked, this, &BalancingWindow::reloadConfig);
|
||||
connect(m_startAllButton, &QPushButton::clicked, this, &BalancingWindow::startAll);
|
||||
connect(m_logButton, &QPushButton::clicked, this, &BalancingWindow::writeLog);
|
||||
|
||||
m_scrollArea = new QScrollArea(this);
|
||||
m_scrollArea->setWidgetResizable(true);
|
||||
@@ -255,6 +314,7 @@ void BalancingWindow::setMainControlsEnabled(bool enabled)
|
||||
{
|
||||
m_reloadButton->setEnabled(enabled);
|
||||
m_startAllButton->setEnabled(enabled);
|
||||
m_logButton->setEnabled(enabled);
|
||||
for (ArenaEntry& entry : m_arenas)
|
||||
{
|
||||
for (QPushButton* btn : entry.widget->findChildren<QPushButton*>())
|
||||
@@ -291,4 +351,50 @@ void BalancingWindow::updateButtons()
|
||||
|
||||
m_reloadButton->setEnabled(!anyRunning);
|
||||
m_startAllButton->setEnabled(!allRunning);
|
||||
m_logButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void BalancingWindow::writeLog()
|
||||
{
|
||||
QFile file(QStringLiteral("balancing_log.md"));
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Log Failed"),
|
||||
tr("Could not open balancing_log.md for writing."));
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream out(&file);
|
||||
out.setCodec("UTF-8");
|
||||
|
||||
out << "# Balancing Log\n";
|
||||
|
||||
for (const ArenaEntry& entry : m_arenas)
|
||||
{
|
||||
const ArenaStatus& status = entry.widget->getLastStatus();
|
||||
|
||||
out << "\n## Arena: " << QString::fromStdString(entry.config.name)
|
||||
<< " (" << stateText(entry.widget->getState()) << ")\n\n";
|
||||
|
||||
out << "| " << teamHeaderCell(status, 0) << " | "
|
||||
<< teamHeaderCell(status, 1) << " |\n";
|
||||
out << "|---|---|\n";
|
||||
|
||||
const std::size_t rowCount = std::max(status.teams[0].entries.size(),
|
||||
status.teams[1].entries.size());
|
||||
for (std::size_t row = 0; row < rowCount; ++row)
|
||||
{
|
||||
QString leftCell;
|
||||
if (row < status.teams[0].entries.size())
|
||||
{
|
||||
leftCell = entryCell(status.teams[0].entries[row]);
|
||||
}
|
||||
QString rightCell;
|
||||
if (row < status.teams[1].entries.size())
|
||||
{
|
||||
rightCell = entryCell(status.teams[1].entries[row]);
|
||||
}
|
||||
out << "| " << leftCell << " | " << rightCell << " |\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user