126 lines
3.4 KiB
C++
126 lines
3.4 KiB
C++
#include "BalancingWindow.h"
|
|
|
|
#include <QScrollArea>
|
|
#include <QVBoxLayout>
|
|
|
|
BalancingWindow::BalancingWindow(const BalancingConfig& balancingConfig,
|
|
const GameConfig& gameConfig,
|
|
QWidget* parent)
|
|
: QWidget(parent)
|
|
, m_gameConfig(gameConfig)
|
|
, m_nextSeed(0)
|
|
{
|
|
setWindowTitle("DotaFactory — Balancing Tool");
|
|
resize(800, 600);
|
|
|
|
QVBoxLayout* mainLayout = new QVBoxLayout(this);
|
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
m_startAllButton = new QPushButton("Start All", this);
|
|
mainLayout->addWidget(m_startAllButton);
|
|
connect(m_startAllButton, &QPushButton::clicked, this, &BalancingWindow::startAll);
|
|
|
|
QScrollArea* scrollArea = new QScrollArea(this);
|
|
scrollArea->setWidgetResizable(true);
|
|
|
|
QWidget* scrollContent = new QWidget(scrollArea);
|
|
QVBoxLayout* contentLayout = new QVBoxLayout(scrollContent);
|
|
contentLayout->setSpacing(8);
|
|
contentLayout->setContentsMargins(8, 8, 8, 8);
|
|
|
|
for (const ArenaConfig& arenaConfig : balancingConfig.arenas)
|
|
{
|
|
int index = static_cast<int>(m_arenas.size());
|
|
|
|
ArenaEntry entry;
|
|
entry.config = arenaConfig;
|
|
entry.simulation = std::make_unique<ArenaSimulation>(
|
|
m_gameConfig, arenaConfig, m_nextSeed++);
|
|
entry.widget = new ArenaWidget(arenaConfig.name, scrollContent);
|
|
contentLayout->addWidget(entry.widget);
|
|
|
|
entry.widget->updateStatus(entry.simulation->status());
|
|
|
|
connect(entry.widget, &ArenaWidget::startRequested,
|
|
this, [this, index]() { startArena(index); });
|
|
|
|
m_arenas.push_back(std::move(entry));
|
|
}
|
|
|
|
contentLayout->addStretch();
|
|
scrollArea->setWidget(scrollContent);
|
|
mainLayout->addWidget(scrollArea);
|
|
|
|
m_pollTimer = new QTimer(this);
|
|
connect(m_pollTimer, &QTimer::timeout, this, &BalancingWindow::pollStatuses);
|
|
m_pollTimer->start(100);
|
|
}
|
|
|
|
BalancingWindow::~BalancingWindow()
|
|
{
|
|
m_pollTimer->stop();
|
|
|
|
for (ArenaEntry& entry : m_arenas)
|
|
{
|
|
entry.simulation->requestStop();
|
|
}
|
|
for (ArenaEntry& entry : m_arenas)
|
|
{
|
|
if (entry.worker.joinable())
|
|
{
|
|
entry.worker.join();
|
|
}
|
|
}
|
|
}
|
|
|
|
void BalancingWindow::pollStatuses()
|
|
{
|
|
for (ArenaEntry& entry : m_arenas)
|
|
{
|
|
if (entry.worker.joinable())
|
|
{
|
|
const ArenaStatus status = entry.simulation->status();
|
|
entry.widget->updateStatus(status);
|
|
}
|
|
}
|
|
updateStartAllButton();
|
|
}
|
|
|
|
void BalancingWindow::startAll()
|
|
{
|
|
for (int i = 0; i < static_cast<int>(m_arenas.size()); ++i)
|
|
{
|
|
startArena(i);
|
|
}
|
|
}
|
|
|
|
void BalancingWindow::startArena(int index)
|
|
{
|
|
ArenaEntry& entry = m_arenas[index];
|
|
if (entry.worker.joinable())
|
|
{
|
|
entry.simulation->requestStop();
|
|
entry.worker.join();
|
|
}
|
|
entry.simulation = std::make_unique<ArenaSimulation>(
|
|
m_gameConfig, entry.config, m_nextSeed++);
|
|
entry.widget->startSimulation();
|
|
entry.widget->updateStatus(entry.simulation->status());
|
|
ArenaSimulation* sim = entry.simulation.get();
|
|
entry.worker = std::thread([sim]() { sim->run(); });
|
|
updateStartAllButton();
|
|
}
|
|
|
|
void BalancingWindow::updateStartAllButton()
|
|
{
|
|
for (ArenaEntry& entry : m_arenas)
|
|
{
|
|
if (!entry.worker.joinable() || entry.simulation->status().finished)
|
|
{
|
|
m_startAllButton->setEnabled(true);
|
|
return;
|
|
}
|
|
}
|
|
m_startAllButton->setEnabled(false);
|
|
}
|