diff --git a/src/drivers/Qt/QtScriptManager.cpp b/src/drivers/Qt/QtScriptManager.cpp index 298b3ba3..010077a6 100644 --- a/src/drivers/Qt/QtScriptManager.cpp +++ b/src/drivers/Qt/QtScriptManager.cpp @@ -1842,6 +1842,63 @@ void MemoryScriptObject::unregisterAll() numWriteFuncsRegistered = 0; numExecFuncsRegistered = 0; } + +//---------------------------------------------------- +//---- Module Loader Object +//---------------------------------------------------- +//---------------------------------------------------- +ModuleLoaderObject::ModuleLoaderObject(QObject* parent) + : QObject(parent) +{ + script = qobject_cast(parent); + engine = script->getEngine(); + scopeCounter = 0; +} +//---------------------------------------------------- +ModuleLoaderObject::~ModuleLoaderObject() +{ +} +//---------------------------------------------------- +void ModuleLoaderObject::GlobalImport(const QString& ns, const QString& file) +{ + const QString& srcFile = script->getSrcFile(); + QFileInfo srcFileInfo(srcFile); + QString srcPath = srcFileInfo.canonicalPath(); + QString cwd = QDir::currentPath(); + + scopeCounter++; + + QDir::setCurrent(srcPath); + QFileInfo moduleFileInfo(file); + QString modulePath = moduleFileInfo.canonicalFilePath(); + + //printf("%i Namespace: %s File: %s\n", scopeCounter, ns.toLocal8Bit().constData(), modulePath.toLocal8Bit().constData() ); + + QJSValue newModule = engine->importModule( modulePath ); + QDir::setCurrent(cwd); + + scopeCounter--; + + if (newModule.isError()) + { + QString errMsg = QString("Failed to load module: ") + file + "\n" + + newModule.toString() + "\n" + + newModule.property("fileName").toString() + ":" + + newModule.property("lineNumber").toString() + " : " + + newModule.toString() + "\nStack:\n" + + newModule.property("stack").toString() + "\n"; + + script->throwError(QJSValue::GenericError, errMsg); + return; + } + + engine->globalObject().setProperty(ns, newModule); + + QString msg = QString("Global import * as '") + ns + QString("' from \"") + file + "\";\n"; + script->print(msg); +} +//---------------------------------------------------- + } // JS //---------------------------------------------------- //---- FCEU JSEngine @@ -2004,6 +2061,11 @@ void QtScriptInstance::shutdownEngine() delete movie; movie = nullptr; } + if (moduleLoader != nullptr) + { + delete moduleLoader; + moduleLoader = nullptr; + } if (ui_rootWidget != nullptr) { @@ -2032,6 +2094,7 @@ int QtScriptInstance::initEngine() mem = new JS::MemoryScriptObject(this); input = new JS::InputScriptObject(this); movie = new JS::MovieScriptObject(this); + moduleLoader = new JS::ModuleLoaderObject(this); emu->setDialog(dialog); rom->setDialog(dialog); @@ -2078,6 +2141,11 @@ int QtScriptInstance::initEngine() engine->globalObject().setProperty("gui", guiObject); + // module + QJSValue moduleLoaderObject = engine->newQObject(moduleLoader); + + engine->globalObject().setProperty("Module", moduleLoaderObject); + // Class Type Definitions for Script Use QJSValue jsColorMetaObject = engine->newQMetaObject(&JS::ColorScriptObject::staticMetaObject); engine->globalObject().setProperty("Color", jsColorMetaObject); @@ -2108,6 +2176,8 @@ int QtScriptInstance::loadScriptFile( QString filepath ) QString fileText = stream.readAll(); scriptFile.close(); + srcFile = filepath; + FCEU_WRAPPER_LOCK(); engine->acquireThreadContext(); QJSValue evalResult = engine->evaluate(fileText, filepath); diff --git a/src/drivers/Qt/QtScriptManager.h b/src/drivers/Qt/QtScriptManager.h index c481ba45..96030106 100644 --- a/src/drivers/Qt/QtScriptManager.h +++ b/src/drivers/Qt/QtScriptManager.h @@ -604,6 +604,24 @@ public slots: Q_INVOKABLE int maxJoypadPlayers(){ return JoypadScriptObject::MAX_JOYPAD_PLAYERS; } }; +class ModuleLoaderObject: public QObject +{ + Q_OBJECT +public: + ModuleLoaderObject(QObject* parent = nullptr); + ~ModuleLoaderObject(); + + void setEngine(FCEU::JSEngine* _engine){ engine = _engine; } + +private: + FCEU::JSEngine* engine = nullptr; + QtScriptInstance* script = nullptr; + int scopeCounter = 0; + +public slots: + Q_INVOKABLE void GlobalImport(const QString& ns, const QString& file); +}; + } // JS class ScriptExecutionState @@ -659,6 +677,7 @@ public: int throwError(QJSValue::ErrorType errorType, const QString &message = QString()); + const QString& getSrcFile(){ return srcFile; }; FCEU::JSEngine* getEngine(){ return engine; }; private: @@ -677,6 +696,7 @@ private: JS::MemoryScriptObject* mem = nullptr; JS::InputScriptObject* input = nullptr; JS::MovieScriptObject* movie = nullptr; + JS::ModuleLoaderObject* moduleLoader = nullptr; QWidget* ui_rootWidget = nullptr; QJSValue *onFrameBeginCallback = nullptr; QJSValue *onFrameFinishCallback = nullptr; @@ -687,6 +707,7 @@ private: int frameAdvanceCount = 0; int frameAdvanceState = 0; bool running = false; + QString srcFile; signals: void errorNotify();