spo/simulator_SIC_XE/gui/qt/MachineController.cpp
2025-12-07 11:27:01 +01:00

76 lines
2 KiB
C++

#include "MachineController.h"
#include "../../include/machine.h"
#include <chrono>
#include <QDebug>
using namespace std::chrono;
MachineController::MachineController(std::shared_ptr<Machine> machine, QObject *parent)
: QObject(parent), m_machine(std::move(machine))
{
if (!m_machine) {
m_machine = std::make_shared<Machine>();
}
m_lastUpdateTime = steady_clock::now();
}
MachineController::~MachineController() {
stop();
}
void MachineController::start() {
if (m_running.exchange(true)) return;
m_thread = std::thread([this]{ runLoop(); });
}
void MachineController::stop() {
if (!m_running.exchange(false)) return;
if (m_thread.joinable()) m_thread.join();
}
void MachineController::step() {
try {
if (m_machine) {
m_machine->execute();
m_machine->tick();
emit tick();
}
} catch (const std::exception &e) {
emit error(QString::fromStdString(e.what()));
}
}
void MachineController::runLoop() {
const auto minUpdateInterval = milliseconds(16);
while (m_running.load()) {
try {
if (m_machine) {
m_machine->execute();
m_machine->tick();
m_ticksSinceLastUpdate++;
// Throttle GUI updates to 60 Hz
auto now = steady_clock::now();
auto elapsed = duration_cast<milliseconds>(now - m_lastUpdateTime);
if (elapsed >= minUpdateInterval) {
emit tick();
m_lastUpdateTime = now;
m_ticksSinceLastUpdate = 0;
}
if (m_machine->isStopped()) {
emit tick();
m_running.store(false);
break;
}
}
} catch (const std::exception &e) {
emit error(QString::fromStdString(e.what()));
// Stop on fatal error
m_running.store(false);
break;
}
}
}