diff --git a/src/drivers/Qt/QtScriptManager.cpp b/src/drivers/Qt/QtScriptManager.cpp index 9cdfdcfc..37a734e2 100644 --- a/src/drivers/Qt/QtScriptManager.cpp +++ b/src/drivers/Qt/QtScriptManager.cpp @@ -126,7 +126,7 @@ EmuStateScriptObject::EmuStateScriptObject(const QJSValue& jsArg1, const QJSValu //printf("EmuStateScriptObject %p JS Constructor(int): %i\n", this, numInstances); setSlot(jsVal.toInt()); - if (slot >= 0) + if ( (slot >= 0) && saveFileExists()) { loadFromFile(filename); } @@ -251,7 +251,7 @@ bool EmuStateScriptObject::loadFromFile(const QString& filepath) FILE* inf = fopen(filepath.toLocal8Bit().data(),"rb"); if (inf == nullptr) { - QString msg = "Warning: JS EmuState::loadFromFile failed to open file: " + filepath + "\n"; + QString msg = "JS EmuState::loadFromFile failed to open file: " + filepath; logMessage(FCEU::JSEngine::WARNING, msg); return false; } @@ -261,7 +261,7 @@ bool EmuStateScriptObject::loadFromFile(const QString& filepath) data = new EMUFILE_MEMORY(len); if ( fread(data->buf(),1,len,inf) != static_cast(len) ) { - QString msg = "Warning: JS EmuState::loadFromFile failed to load full buffer.\n"; + QString msg = "JS EmuState::loadFromFile failed to load full buffer."; logMessage(FCEU::JSEngine::WARNING, msg); delete data; data = nullptr; @@ -280,6 +280,41 @@ void EmuStateScriptObject::logMessage(int lvl, QString& msg) } } //---------------------------------------------------- +bool EmuStateScriptObject::saveFileExists() +{ + bool exists = false; + QFileInfo fileInfo(filename); + + if (fileInfo.exists() && fileInfo.isFile()) + { + exists = true; + } + return exists; +} +//---------------------------------------------------- +QJSValue EmuStateScriptObject::copy() +{ + QJSValue jsVal; + auto* engine = FCEU::JSEngine::getCurrent(); + + if (engine != nullptr) + { + EmuStateScriptObject* emuStateObj = new EmuStateScriptObject(); + + if (emuStateObj != nullptr) + { + *emuStateObj = *this; + + jsVal = engine->newQObject(emuStateObj); + +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QJSEngine::setObjectOwnership( emuStateObj, QJSEngine::JavaScriptOwnership); +#endif + } + } + return jsVal; +} +//---------------------------------------------------- //---- EMU Script Object //---------------------------------------------------- EmuScriptObject::EmuScriptObject(QObject* parent) @@ -1159,7 +1194,27 @@ namespace FCEU { if (lvl <= _logLevel) { - dialog->logOutput(msg); + const char *prefix = "Warning: "; + switch (lvl) + { + case FCEU::JSEngine::DEBUG: + prefix = "Debug: "; + break; + case FCEU::JSEngine::INFO: + prefix = "Info: "; + break; + case FCEU::JSEngine::WARNING: + prefix = "Warning: "; + break; + case FCEU::JSEngine::CRITICAL: + prefix = "Critical: "; + break; + case FCEU::JSEngine::FATAL: + prefix = "Fatal: "; + break; + } + QString fullMsg = prefix + msg.trimmed() + "\n"; + dialog->logOutput(fullMsg); } } } @@ -1356,9 +1411,11 @@ int QtScriptInstance::loadScriptFile( QString filepath ) if (evalResult.isError()) { - QString msg; - msg += evalResult.property("lineNumber").toString() + ": "; - msg += evalResult.toString(); + QString msg = "Uncaught exception at: " + + evalResult.property("fileName").toString() + ":" + + evalResult.property("lineNumber").toString() + " : " + + evalResult.toString() + "\nStack:\n" + + evalResult.property("stack").toString() + "\n"; print(msg); return -1; } @@ -1534,7 +1591,12 @@ int QtScriptInstance::runFunc(QJSValue &func, const QJSValueList& args) { retval = -1; running = false; - print(callResult.toString()); + QString msg = "Uncaught exception at: " + + callResult.property("fileName").toString() + ":" + + callResult.property("lineNumber").toString() + " : " + + callResult.toString() + "\nStack:\n" + + callResult.property("stack").toString() + "\n"; + print(msg); } return retval; } @@ -1754,6 +1816,36 @@ void QtScriptManager::destroy(void) } } //---------------------------------------------------- +void QtScriptManager::logMessageQt(QtMsgType type, const QString &msg) +{ + auto* engine = FCEU::JSEngine::getCurrent(); + + if (engine != nullptr) + { + int logLevel = FCEU::JSEngine::WARNING; + + switch (type) + { + case QtDebugMsg: + logLevel = FCEU::JSEngine::DEBUG; + break; + case QtInfoMsg: + logLevel = FCEU::JSEngine::INFO; + break; + case QtWarningMsg: + logLevel = FCEU::JSEngine::WARNING; + break; + case QtCriticalMsg: + logLevel = FCEU::JSEngine::CRITICAL; + break; + case QtFatalMsg: + logLevel = FCEU::JSEngine::FATAL; + break; + } + engine->logMessage( logLevel, msg ); + } +} +//---------------------------------------------------- void QtScriptManager::addScriptInstance(QtScriptInstance* script) { FCEU::autoScopedLock autoLock(scriptListMutex); diff --git a/src/drivers/Qt/QtScriptManager.h b/src/drivers/Qt/QtScriptManager.h index 71bcda27..7b3e48d0 100644 --- a/src/drivers/Qt/QtScriptManager.h +++ b/src/drivers/Qt/QtScriptManager.h @@ -142,6 +142,8 @@ public slots: Q_INVOKABLE void setFilename(const QString& name){ filename = name; } Q_INVOKABLE bool saveToFile(const QString& filepath); Q_INVOKABLE bool loadFromFile(const QString& filepath); + Q_INVOKABLE bool saveFileExists(); + Q_INVOKABLE QJSValue copy(); }; class EmuScriptObject: public QObject @@ -413,6 +415,8 @@ public: static QtScriptManager* create(QObject* parent = nullptr); static void destroy(); + static void logMessageQt(QtMsgType type, const QString &msg); + int numScriptsLoaded(void){ return scriptList.size(); } void addScriptInstance(QtScriptInstance* script); void removeScriptInstance(QtScriptInstance* script); diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index b6c3c0a1..6c0fe718 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -27,6 +27,7 @@ #include "Qt/ConsoleWindow.h" #include "Qt/fceuWrapper.h" #include "Qt/SplashScreen.h" +#include "Qt/QtScriptManager.h" #ifdef WIN32 #include @@ -65,6 +66,10 @@ static void MessageOutput(QtMsgType type, const QMessageLogContext &context, con } cmsg[sizeof(cmsg)-1] = 0; fprintf(stderr, "%s", cmsg ); + +#ifdef __FCEU_QSCRIPT_ENABLE__ + QtScriptManager::logMessageQt(type, msg); +#endif }