1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-10 12:29:01 +00:00

Consolidates timer/thread ownership for the timer.

This commit is contained in:
Thomas Harte 2020-06-07 00:31:46 -04:00
parent 63ad1290f4
commit d027450502
4 changed files with 36 additions and 24 deletions

View File

@ -23,18 +23,7 @@ MainWindow::MainWindow(QWidget *parent)
createActions(); createActions();
qApp->installEventFilter(this); qApp->installEventFilter(this);
// Set up the emulation timer. Bluffer's guide: the QTimer will post an timer = std::make_unique<Timer>(this);
// event to an event loop. QThread is a thread with an event loop.
// My class, Timer, will be wired up to receive the QTimer's events.
qTimer = std::make_unique<QTimer>(this);
qTimer->setInterval(1);
timerThread = std::make_unique<QThread>(this);
timer = std::make_unique<Timer>();
timer->moveToThread(timerThread.get());
connect(qTimer.get(), SIGNAL(timeout()), timer.get(), SLOT(tick()));
// Hide the missing ROMs box unless or until it's needed; grab the text it // Hide the missing ROMs box unless or until it's needed; grab the text it
// began with as a prefix for future mutation. // began with as a prefix for future mutation.
@ -75,10 +64,8 @@ void MainWindow::open() {
} }
MainWindow::~MainWindow() { MainWindow::~MainWindow() {
// Stop the timer by asking its QThread to exit and // Stop the timer
// waiting for it to do so. timer.reset();
timerThread->exit();
while(timerThread->isRunning());
} }
// MARK: Machine launch. // MARK: Machine launch.
@ -178,9 +165,6 @@ void MainWindow::launchMachine() {
idealFormat.setChannelCount(1 + int(audioIsStereo)); idealFormat.setChannelCount(1 + int(audioIsStereo));
idealFormat.setSampleSize(audioIs8bit ? 8 : 16); idealFormat.setSampleSize(audioIs8bit ? 8 : 16);
audioOutput = std::make_unique<QAudioOutput>(idealFormat, this); audioOutput = std::make_unique<QAudioOutput>(idealFormat, this);
// audioOutput->setBufferSize(samplesPerBuffer * (audioIsStereo ? 2 : 1) * (audioIs8bit ? 1 : 2));
qDebug() << idealFormat;
// Start the output. // Start the output.
speaker->set_delegate(this); speaker->set_delegate(this);
@ -192,8 +176,7 @@ void MainWindow::launchMachine() {
const auto timedMachine = machine->timed_machine(); const auto timedMachine = machine->timed_machine();
if(timedMachine) { if(timedMachine) {
timer->setMachine(timedMachine, &machineMutex); timer->setMachine(timedMachine, &machineMutex);
timerThread->start(); timer->start();
qTimer->start();
} }
} break; } break;

View File

@ -29,8 +29,6 @@ class MainWindow : public QMainWindow, public Outputs::Speaker::Speaker::Delegat
private: private:
std::unique_ptr<Ui::MainWindow> ui; std::unique_ptr<Ui::MainWindow> ui;
std::unique_ptr<QTimer> qTimer;
std::unique_ptr<QThread> timerThread;
std::unique_ptr<Timer> timer; std::unique_ptr<Timer> timer;
// Initial setup stuff. // Initial setup stuff.

View File

@ -5,7 +5,18 @@
#include <algorithm> #include <algorithm>
#include <QDebug> #include <QDebug>
Timer::Timer(QObject *parent) : QObject(parent) {} Timer::Timer(QObject *parent) : QObject(parent) {
// Set up the emulation timer. Bluffer's guide: the QTimer will post an
// event to an event loop. QThread is a thread with an event loop.
// My class, Timer, will be wired up to receive the QTimer's events.
timer = std::make_unique<QTimer>(this);
timer->setInterval(1);
thread = std::make_unique<QThread>(this);
moveToThread(thread.get());
connect(timer.get(), SIGNAL(timeout()), this, SLOT(tick()));
}
void Timer::setMachine(MachineTypes::TimedMachine *machine, std::mutex *machineMutex) { void Timer::setMachine(MachineTypes::TimedMachine *machine, std::mutex *machineMutex) {
this->machine = machine; this->machine = machine;
@ -21,3 +32,15 @@ void Timer::tick() {
std::lock_guard lock_guard(*machineMutex); std::lock_guard lock_guard(*machineMutex);
machine->run_for(double(duration) / 1e9); machine->run_for(double(duration) / 1e9);
} }
void Timer::start() {
thread->start();
timer->start();
}
Timer::~Timer() {
// Stop the timer, then ask the QThread to exit and wait for it to do so.
timer->stop();
thread->exit();
while(thread->isRunning());
}

View File

@ -2,7 +2,10 @@
#define TIMER_H #define TIMER_H
#include <atomic> #include <atomic>
#include <QObject> #include <QObject>
#include <QThread>
#include <QTimer>
#include "../../Machines/Utility/MachineForTarget.hpp" #include "../../Machines/Utility/MachineForTarget.hpp"
@ -12,7 +15,10 @@ class Timer : public QObject
public: public:
explicit Timer(QObject *parent = nullptr); explicit Timer(QObject *parent = nullptr);
~Timer();
void setMachine(MachineTypes::TimedMachine *machine, std::mutex *machineMutex); void setMachine(MachineTypes::TimedMachine *machine, std::mutex *machineMutex);
void start();
public slots: public slots:
void tick(); void tick();
@ -21,6 +27,8 @@ class Timer : public QObject
MachineTypes::TimedMachine *machine = nullptr; MachineTypes::TimedMachine *machine = nullptr;
std::mutex *machineMutex = nullptr; std::mutex *machineMutex = nullptr;
int64_t lastTickNanos = 0; int64_t lastTickNanos = 0;
std::unique_ptr<QThread> thread;
std::unique_ptr<QTimer> timer;
}; };
#endif // TIMER_H #endif // TIMER_H