attempting at fixing Stop function. also lay base for EmuThread command queue.

This commit is contained in:
Arisotura 2024-06-14 19:22:24 +02:00
parent fd065f4803
commit 77548ac086
4 changed files with 79 additions and 10 deletions

View File

@ -180,12 +180,12 @@ bool EmuInstance::emuIsActive()
void EmuInstance::emuStop(StopReason reason)
{
emuThread->emuStop();
if (reason != StopReason::External)
emuThread->emuStop(false);
switch (reason)
{
case StopReason::GBAModeNotSupported:
Log(LogLevel::Error, "!! GBA MODE NOT SUPPORTED\n");
osdAddMessage(0xFFA0A0, "GBA mode not supported");
break;
case StopReason::BadExceptionRegion:

View File

@ -460,6 +460,8 @@ void EmuThread::run()
ContextRequest = contextRequest_None;
}
}
handleMessages();
}
file = Platform::OpenLocalFile("rtc.bin", Platform::FileMode::Write);
@ -476,6 +478,45 @@ void EmuThread::run()
NDS::Current = nullptr;
}
void EmuThread::sendMessage(Message msg)
{
msgMutex.lock();
msgQueue.enqueue(msg);
msgMutex.unlock();
}
void EmuThread::waitMessage()
{
msgSemaphore.acquire();
}
void EmuThread::waitAllMessages()
{
msgSemaphore.acquire(msgSemaphore.available());
}
void EmuThread::handleMessages()
{
msgMutex.lock();
while (!msgQueue.empty())
{
Message msg = msgQueue.dequeue();
switch (msg.type)
{
case msg_EmuStop:
if (msg.stopExternal) emuInstance->nds->Stop();
EmuRunning = emuStatus_Paused;
emuActive = false;
emuInstance->audioDisable();
emit windowEmuStop();
break;
}
msgSemaphore.release();
}
msgMutex.unlock();
}
void EmuThread::changeWindowTitle(char* title)
{
emit windowTitleChange(QString(title));
@ -528,10 +569,9 @@ void EmuThread::emuUnpause()
emuInstance->audioEnable();
}
void EmuThread::emuStop()
void EmuThread::emuStop(bool external)
{
emuPause();
emuActive = false;
sendMessage({.type = msg_EmuStop, .stopExternal = external});
}
void EmuThread::emuExit()

View File

@ -21,6 +21,8 @@
#include <QThread>
#include <QMutex>
#include <QSemaphore>
#include <QQueue>
#include <atomic>
#include <variant>
@ -53,13 +55,36 @@ public:
void attachWindow(MainWindow* window);
void detachWindow(MainWindow* window);
enum MessageType
{
msg_EmuStop,
};
struct Message
{
MessageType type;
union
{
bool stopExternal;
};
};
void sendMessage(Message msg);
void waitMessage();
void waitAllMessages();
void sendMessage(MessageType type)
{
return sendMessage({.type = type});
}
void changeWindowTitle(char* title);
// to be called from the UI thread
void emuRun();
void emuPause();
void emuUnpause();
void emuStop();
void emuStop(bool external);
void emuExit();
void emuFrameStep();
@ -95,6 +120,8 @@ signals:
void syncVolumeLevel();
private:
void handleMessages();
void updateRenderer();
void compileShaders();
@ -115,6 +142,10 @@ private:
constexpr static int EmuPauseStackPauseThreshold = 1;
int EmuPauseStack;
QMutex msgMutex;
QSemaphore msgSemaphore;
QQueue<Message> msgQueue;
enum ContextRequestKind
{
contextRequest_None = 0,

View File

@ -1621,8 +1621,8 @@ void MainWindow::onStop()
{
if (!emuThread->emuIsActive()) return;
emuThread->emuPause();
emuInstance->nds->Stop();
emuThread->emuStop(true);
emuThread->waitMessage();
}
void MainWindow::onFrameStep()
@ -2068,8 +2068,6 @@ void MainWindow::onEmuStart()
void MainWindow::onEmuStop()
{
emuThread->emuStop();
for (int i = 0; i < 9; i++)
{
actSaveState[i]->setEnabled(false);