#include "executor.h" #include "machine.h" #include #include Executor::Executor(Machine* m) : QObject(nullptr), machine(m), timer(nullptr) { } Executor::~Executor() { if (timer) { timer->stop(); delete timer; timer = nullptr; } } bool Executor::hasEnded() const { return ended; } void Executor::resetProgram() { // resetiraj stanje, poruši izvajanje in spravi lučko v stopped ended = false; running = false; stepping = false; if (timer) timer->stop(); emit signalStopped(); emit updateRequested(); } // START: pripravimo timer (v threadu, kjer je ta objekt) in ga zaženemo void Executor::start() { // če je končano, pošljemo ended in ne začnemo if (ended) { emit signalEnded(); return; } // če že tečemo, nič if (running) return; running = true; emit signalStarted(); // timer naj bo kreiran v končni niti (start() bo klican v executorThread preko queued connection) if (!timer) { timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &Executor::runStep, Qt::DirectConnection); } // zaženi timer z intervalom timer->start(intervalMs); } // STOP: takoj ustavimo timer in sporočimo stopped void Executor::stop() { if (!running && !timer) { emit signalStopped(); return; } running = false; stepping = false; if (timer && timer->isActive()) timer->stop(); emit signalStopped(); emit updateRequested(); } // runStep: izvede en ukaz — klican iz timer timeout void Executor::runStep() { if (!running || ended) { if (timer && timer->isActive()) timer->stop(); return; } // izvedemo en ukaz int pc_before = machine->getPC(); machine->execute(); int pc_after = machine->getPC(); // obvestimo UI emit updateRequested(); // preverimo halt / ended if (pc_before == pc_after) { ended = true; // ustavimo timer in pošljemo samo ended (ne stopped) if (timer && timer->isActive()) timer->stop(); emit signalEnded(); return; } // Če je uporabnik pritisnil stop med izvajanjem, ustavimo timer if (!running) { if (timer && timer->isActive()) timer->stop(); emit signalStopped(); } } // step: en sam korak, le če ne tečemo že v avtomatskem načinu void Executor::step() { if (ended) { emit signalEnded(); return; } // če je avtomatsko izvajanje v teku, ignoriramo manualni step if (running) return; // preprečimo reentrance if (stepping) return; stepping = true; int pc_before = machine->getPC(); machine->execute(); int pc_after = machine->getPC(); emit updateRequested(); if (pc_after == pc_before) { ended = true; emit signalEnded(); } else { emit signalStopped(); } stepping = false; }