1 #ifndef EMUTHREAD_H 2 #define EMUTHREAD_H 3 4 #include "../../core/debug/debug.h" 5 #include "../../core/emu.h" 6 #include "../../core/link.h" 7 8 #include <QtCore/QMutex> 9 #include <QtCore/QQueue> 10 #include <QtCore/QSemaphore> 11 #include <QtCore/QThread> 12 #include <QtCore/QTimer> 13 14 #include <chrono> 15 #include <condition_variable> 16 17 #define CONSOLE_BUFFER_SIZE 512 18 19 class EmuThread : public QThread { 20 Q_OBJECT 21 22 public: 23 explicit EmuThread(QObject *parent = Q_NULLPTR); 24 void stop(); 25 void reset(); 26 void resume(); 27 void receive(); 28 void unblock(); 29 void debug(bool); 30 void doStuff(); 31 void throttleWait(); 32 void setSpeed(int value); 33 void setThrottle(bool state); 34 void writeConsole(int console, const char *format, va_list args); 35 void debugOpen(int reason, uint32_t addr); 36 void save(emu_data_t type, const QString &path); 37 void setRam(const QString &path); 38 void load(emu_data_t type, const QString &path); 39 void test(const QString &config, bool run); 40 41 enum { 42 ConsoleNorm, 43 ConsoleErr, 44 ConsoleMax 45 }; 46 enum { 47 RequestNone, 48 RequestPause, 49 RequestReset, 50 RequestSave, 51 RequestLoad, 52 RequestSend, 53 RequestReceive, 54 RequestAutoTester, 55 RequestDebugger 56 }; 57 58 int type = ConsoleNorm; 59 int writePos = 0; 60 int readPos = 0; 61 char buffer[CONSOLE_BUFFER_SIZE]; 62 QSemaphore write; 63 QSemaphore read; 64 65 signals: 66 // console 67 void consoleStr(); 68 void consoleClear(); 69 70 // debug 71 void debugDisable(); 72 void debugCommand(int reason, uint32_t addr); 73 74 // speed 75 void sendSpeed(int value); 76 77 // state 78 void tested(int status); 79 void saved(bool success); 80 void loaded(emu_state_t state, emu_data_t type); 81 void blocked(int req); 82 void sentFile(const QString &file, int ok); 83 84 public slots: 85 void send(const QStringList &names, int location); 86 void enqueueKeys(quint16 key1, quint16 key2 = 0, bool repeat = false); 87 88 protected: 89 virtual void run() Q_DECL_OVERRIDE; 90 91 private: 92 sendFiles()93 void sendFiles() { 94 for (const QString &f : m_vars) { 95 emit sentFile(f, emu_send_variable(f.toUtf8(), m_sendLoc)); 96 } 97 emit sentFile(QString(), LINK_GOOD); 98 } 99 req(int req)100 void req(int req) { 101 m_reqQueue.enqueue(req); 102 } 103 block(int status)104 void block(int status) { 105 std::unique_lock<std::mutex> lock(m_mutex); 106 emit blocked(status); 107 m_cv.wait(lock); 108 } 109 110 QQueue<int> m_reqQueue; 111 emu_data_t m_saveType; 112 emu_data_t m_loadType; 113 114 int m_speed, m_actualSpeed; 115 bool m_throttle; 116 std::chrono::steady_clock::time_point m_lastTime; 117 std::mutex m_mutexSpeed; 118 std::condition_variable m_cvSpeed; 119 120 bool m_debug; // protected by m_mutexDebug 121 122 QString m_autotesterPath; 123 bool m_autotesterRun; 124 125 QString m_savePath; 126 QString m_loadPath; 127 QStringList m_vars; 128 int m_sendLoc; 129 130 std::mutex m_mutex; 131 std::condition_variable m_cv; 132 std::mutex m_mutexDebug; 133 std::condition_variable m_cvDebug; // protected by m_mutexDebug 134 135 QQueue<quint16> m_keyQueue; 136 QMutex m_keyQueueMutex; 137 }; 138 139 #endif 140