From d027450502fcbf6998785467f950defd17238f63 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 7 Jun 2020 00:31:46 -0400 Subject: [PATCH] Consolidates timer/thread ownership for the timer. --- OSBindings/Qt/mainwindow.cpp | 25 ++++--------------------- OSBindings/Qt/mainwindow.h | 2 -- OSBindings/Qt/timer.cpp | 25 ++++++++++++++++++++++++- OSBindings/Qt/timer.h | 8 ++++++++ 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/OSBindings/Qt/mainwindow.cpp b/OSBindings/Qt/mainwindow.cpp index 36a90b249..30da58958 100644 --- a/OSBindings/Qt/mainwindow.cpp +++ b/OSBindings/Qt/mainwindow.cpp @@ -23,18 +23,7 @@ MainWindow::MainWindow(QWidget *parent) createActions(); qApp->installEventFilter(this); - // 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. - qTimer = std::make_unique(this); - qTimer->setInterval(1); - - timerThread = std::make_unique(this); - - timer = std::make_unique(); - timer->moveToThread(timerThread.get()); - - connect(qTimer.get(), SIGNAL(timeout()), timer.get(), SLOT(tick())); + timer = std::make_unique(this); // Hide the missing ROMs box unless or until it's needed; grab the text it // began with as a prefix for future mutation. @@ -75,10 +64,8 @@ void MainWindow::open() { } MainWindow::~MainWindow() { - // Stop the timer by asking its QThread to exit and - // waiting for it to do so. - timerThread->exit(); - while(timerThread->isRunning()); + // Stop the timer + timer.reset(); } // MARK: Machine launch. @@ -178,9 +165,6 @@ void MainWindow::launchMachine() { idealFormat.setChannelCount(1 + int(audioIsStereo)); idealFormat.setSampleSize(audioIs8bit ? 8 : 16); audioOutput = std::make_unique(idealFormat, this); -// audioOutput->setBufferSize(samplesPerBuffer * (audioIsStereo ? 2 : 1) * (audioIs8bit ? 1 : 2)); - - qDebug() << idealFormat; // Start the output. speaker->set_delegate(this); @@ -192,8 +176,7 @@ void MainWindow::launchMachine() { const auto timedMachine = machine->timed_machine(); if(timedMachine) { timer->setMachine(timedMachine, &machineMutex); - timerThread->start(); - qTimer->start(); + timer->start(); } } break; diff --git a/OSBindings/Qt/mainwindow.h b/OSBindings/Qt/mainwindow.h index 4dfa39231..5c6c48f1b 100644 --- a/OSBindings/Qt/mainwindow.h +++ b/OSBindings/Qt/mainwindow.h @@ -29,8 +29,6 @@ class MainWindow : public QMainWindow, public Outputs::Speaker::Speaker::Delegat private: std::unique_ptr ui; - std::unique_ptr qTimer; - std::unique_ptr timerThread; std::unique_ptr timer; // Initial setup stuff. diff --git a/OSBindings/Qt/timer.cpp b/OSBindings/Qt/timer.cpp index 292c0e16d..36b4e6556 100644 --- a/OSBindings/Qt/timer.cpp +++ b/OSBindings/Qt/timer.cpp @@ -5,7 +5,18 @@ #include #include -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(this); + timer->setInterval(1); + + thread = std::make_unique(this); + + moveToThread(thread.get()); + connect(timer.get(), SIGNAL(timeout()), this, SLOT(tick())); +} void Timer::setMachine(MachineTypes::TimedMachine *machine, std::mutex *machineMutex) { this->machine = machine; @@ -21,3 +32,15 @@ void Timer::tick() { std::lock_guard lock_guard(*machineMutex); 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()); +} diff --git a/OSBindings/Qt/timer.h b/OSBindings/Qt/timer.h index 44e10c725..e1d3e0dd0 100644 --- a/OSBindings/Qt/timer.h +++ b/OSBindings/Qt/timer.h @@ -2,7 +2,10 @@ #define TIMER_H #include + #include +#include +#include #include "../../Machines/Utility/MachineForTarget.hpp" @@ -12,7 +15,10 @@ class Timer : public QObject public: explicit Timer(QObject *parent = nullptr); + ~Timer(); + void setMachine(MachineTypes::TimedMachine *machine, std::mutex *machineMutex); + void start(); public slots: void tick(); @@ -21,6 +27,8 @@ class Timer : public QObject MachineTypes::TimedMachine *machine = nullptr; std::mutex *machineMutex = nullptr; int64_t lastTickNanos = 0; + std::unique_ptr thread; + std::unique_ptr timer; }; #endif // TIMER_H