status light fixed and stop btn fixed
This commit is contained in:
parent
87b9c1dc62
commit
55a126dcca
10 changed files with 197 additions and 129 deletions
|
|
@ -1,76 +1,132 @@
|
|||
#include "executor.h"
|
||||
#include "machine.h"
|
||||
#include<chrono>
|
||||
#include<thread>
|
||||
#include <QCoreApplication>
|
||||
Executor::Executor() {}
|
||||
#include <QTimer>
|
||||
#include <QThread>
|
||||
|
||||
Executor::Executor(Machine* m) {
|
||||
machine = m;
|
||||
Executor::Executor(Machine* m)
|
||||
: QObject(nullptr), machine(m), timer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void Executor::start() {
|
||||
if (ended) {
|
||||
emit signalEnded();
|
||||
return;
|
||||
}
|
||||
running = true;
|
||||
emit signalStarted();
|
||||
while (running && !ended) {
|
||||
int pc_before = machine->getPC();
|
||||
machine->execute();
|
||||
int pc_after = machine->getPC();
|
||||
emit updateRequested(); // signal za posodobitev UI
|
||||
if (pc_before == pc_after) {
|
||||
ended = true;
|
||||
emit signalEnded();
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
QCoreApplication::processEvents();
|
||||
Executor::~Executor()
|
||||
{
|
||||
if (timer) {
|
||||
timer->stop();
|
||||
delete timer;
|
||||
timer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Executor::stop() {
|
||||
running = false;
|
||||
emit signalStopped();
|
||||
emit updateRequested();
|
||||
}
|
||||
|
||||
bool Executor::isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
bool Executor::hasEnded() {
|
||||
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;
|
||||
}
|
||||
|
||||
emit signalStarted();
|
||||
// č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();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
emit signalStopped();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
if (pc_after == pc_before) {
|
||||
ended = true;
|
||||
emit signalEnded();
|
||||
} else {
|
||||
emit signalStopped();
|
||||
}
|
||||
}
|
||||
|
||||
stepping = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue