//// ScriptEngine.h// libraries/script-engine/src//// Created by Brad Hefta-Gaub on 12/14/13.// Copyright 2013 High Fidelity, Inc.//// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// #ifndef hifi_ScriptEngine_h#define hifi_ScriptEngine_h #include <unordered_map>#include <vector> #include <QtCore/QObject>#include <QtCore/QUrl>#include <QtCore/QSet>#include <QtCore/QWaitCondition>#include <QtCore/QStringList> #include <QtScript/QScriptEngine> #include <AnimationCache.h>#include <AnimVariant.h>#include <AvatarData.h>#include <AvatarHashMap.h>#include <LimitedNodeList.h>#include <EntityItemID.h>#include <EntitiesScriptEngineProvider.h>#include <EntityScriptUtils.h> #include "PointerEvent.h"#include "ArrayBufferClass.h"#include "AssetScriptingInterface.h"#include "AudioScriptingInterface.h"#include "BaseScriptEngine.h"#include "Quat.h"#include "Mat4.h"#include "ScriptCache.h"#include "ScriptUUID.h"#include "Vec3.h"#include "ConsoleScriptingInterface.h"#include "SettingHandle.h"#include "Profile.h" class QScriptEngineDebugger; static const QString NO_SCRIPT(""); static const int SCRIPT_FPS = 60;static const int DEFAULT_MAX_ENTITY_PPS = 9000;static const int DEFAULT_ENTITY_PPS_PER_SCRIPT = 900; class ScriptEngines; Q_DECLARE_METATYPE(ScriptEnginePointer) class CallbackData {public: QScriptValue function; EntityItemID definingEntityIdentifier; QUrl definingSandboxURL;}; class DeferredLoadEntity {public: EntityItemID entityID; QString entityScript; //bool forceRedownload;}; struct EntityScriptContentAvailable { EntityItemID entityID; QString scriptOrURL; QString contents; bool isURL; bool success; QString status;}; typedef std::unordered_map<EntityItemID, EntityScriptContentAvailable> EntityScriptContentAvailableMap; typedef QList<CallbackData> CallbackList;typedef QHash<QString, CallbackList> RegisteredEventHandlers; class EntityScriptDetails {public: EntityScriptStatus status { EntityScriptStatus::PENDING }; // If status indicates an error, this contains a human-readable string giving more information about the error. QString errorInfo { "" }; QString scriptText { "" }; QScriptValue scriptObject { QScriptValue() }; int64_t lastModified { 0 }; QUrl definingSandboxURL { QUrl("about:EntityScript") };}; /**jsdoc * @namespace Script * * @hifi-interface * @hifi-client-entity * @hifi-server-entity * @hifi-assignment-client * * @property {string} context */class ScriptEngine : public BaseScriptEngine, public EntitiesScriptEngineProvider { Q_OBJECT Q_PROPERTY(QString context READ getContext)public: enum Context { CLIENT_SCRIPT, ENTITY_CLIENT_SCRIPT, ENTITY_SERVER_SCRIPT, AGENT_SCRIPT }; enum Type { CLIENT, ENTITY_CLIENT, ENTITY_SERVER, AGENT, AVATAR }; static int processLevelMaxRetries; ScriptEngine(Context context, const QString& scriptContents = NO_SCRIPT, const QString& fileNameString = QString("about:ScriptEngine")); ~ScriptEngine(); /// run the script in a dedicated thread. This will have the side effect of evalulating /// the current script contents and calling run(). Callers will likely want to register the script with external /// services before calling this. void runInThread(); void runDebuggable(); /// run the script in the callers thread, exit when stop() is called. void run(); QString getFilename() const; /**jsdoc * Stop the current script. * @function Script.stop * @param {boolean} [marshal=false] */ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts Q_INVOKABLE void stop(bool marshal = false); // Stop any evaluating scripts and wait for the scripting thread to finish. void waitTillDoneRunning(); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - these are NOT intended to be public interfaces available to scripts, the are only Q_INVOKABLE so we can // properly ensure they are only called on the correct thread /**jsdoc * @function Script.registerGlobalObject * @param {string} name * @param {object} object */ /// registers a global object by name Q_INVOKABLE void registerGlobalObject(const QString& name, QObject* object); /**jsdoc * @function Script.registerGetterSetter * @param {string} name * @param {object} getter * @param {object} setter * @param {string} [parent=""] */ /// registers a global getter/setter Q_INVOKABLE void registerGetterSetter(const QString& name, QScriptEngine::FunctionSignature getter, QScriptEngine::FunctionSignature setter, const QString& parent = QString("")); /**jsdoc * @function Script.registerFunction * @param {string} name * @param {object} function * @param {number} [numArguments=-1] */ /// register a global function Q_INVOKABLE void registerFunction(const QString& name, QScriptEngine::FunctionSignature fun, int numArguments = -1); /**jsdoc * @function Script.registerFunction * @param {string} parent * @param {string} name * @param {object} function * @param {number} [numArguments=-1] */ /// register a function as a method on a previously registered global object Q_INVOKABLE void registerFunction(const QString& parent, const QString& name, QScriptEngine::FunctionSignature fun, int numArguments = -1); /**jsdoc * @function Script.registerValue * @param {string} name * @param {object} value */ /// registers a global object by name Q_INVOKABLE void registerValue(const QString& valueName, QScriptValue value); /**jsdoc * @function Script.evaluate * @param {string} program * @param {string} filename * @param {number} [lineNumber=-1] * @returns {object} */ /// evaluate some code in the context of the ScriptEngine and return the result Q_INVOKABLE QScriptValue evaluate(const QString& program, const QString& fileName, int lineNumber = 1); // this is also used by the script tool widget /**jsdoc * @function Script.evaluateInClosure * @param {object} locals * @param {object} program * @returns {object} */ Q_INVOKABLE QScriptValue evaluateInClosure(const QScriptValue& locals, const QScriptProgram& program); /// if the script engine is not already running, this will download the URL and start the process of seting it up /// to run... NOTE - this is used by Application currently to load the url. We don't really want it to be exposed /// to scripts. we may not need this to be invokable void loadURL(const QUrl& scriptURL, bool reload); bool hasValidScriptSuffix(const QString& scriptFileName); /**jsdoc * @function Script.getContext * @returns {string} */ Q_INVOKABLE QString getContext() const; /**jsdoc * @function Script.isClientScript * @returns {boolean} */ Q_INVOKABLE bool isClientScript() const { return _context == CLIENT_SCRIPT; } /**jsdoc * @function Script.isDebugMode * @returns {boolean} */ Q_INVOKABLE bool isDebugMode() const; /**jsdoc * @function Script.isEntityClientScript * @returns {boolean} */ Q_INVOKABLE bool isEntityClientScript() const { return _context == ENTITY_CLIENT_SCRIPT; } /**jsdoc * @function Script.isEntityServerScript * @returns {boolean} */ Q_INVOKABLE bool isEntityServerScript() const { return _context == ENTITY_SERVER_SCRIPT; } /**jsdoc * @function Script.isAgentScript * @returns {boolean} */ Q_INVOKABLE bool isAgentScript() const { return _context == AGENT_SCRIPT; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - these are intended to be public interfaces available to scripts /**jsdoc * @function Script.addEventHandler * @param {Uuid} entityID * @param {string} eventName * @param {function} handler */ Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); /**jsdoc * @function Script.removeEventHandler * @param {Uuid} entityID * @param {string} eventName * @param {function} handler */ Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); /**jsdoc * Start a new Interface or entity script. * @function Script.load * @param {string} filename - The URL of the script to load. Can be relative to the current script. * @example <caption>Load a script from another script.</caption> * // First file: scriptA.js * print("This is script A"); * * // Second file: scriptB.js * print("This is script B"); * Script.load("scriptA.js"); * * // If you run scriptB.js you should see both scripts in the running scripts list. * // And you should see the following output: * // This is script B * // This is script A */ Q_INVOKABLE void load(const QString& loadfile); /**jsdoc * Include JavaScript from other files in the current script. If a callback is specified the files are loaded and included * asynchronously, otherwise they are included synchronously (i.e., script execution blocks while the files are included). * @function Script.include * @param {string[]} filenames - The URLs of the scripts to include. Each can be relative to the current script. * @param {function} [callback=null] - The function to call back when the scripts have been included. Can be an in-line * function or the name of a function. */ Q_INVOKABLE void include(const QStringList& includeFiles, QScriptValue callback = QScriptValue()); /**jsdoc * Include JavaScript from another file in the current script. If a callback is specified the file is loaded and included * asynchronously, otherwise it is included synchronously (i.e., script execution blocks while the file is included). * @function Script.include * @param {string} filename - The URL of the script to include. Can be relative to the current script. * @param {function} [callback=null] - The function to call back when the script has been included. Can be an in-line * function or the name of a function. * @example <caption>Include a script file asynchronously.</caption> * // First file: scriptA.js * print("This is script A"); * * // Second file: scriptB.js * print("This is script B"); * Script.include("scriptA.js", function () { * print("Script A has been included"); * }); * * // If you run scriptB.js you should see only scriptB.js in the running scripts list. * // And you should see the following output: * // This is script B * // This is script A * // Script A has been included */ Q_INVOKABLE void include(const QString& includeFile, QScriptValue callback = QScriptValue()); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MODULE related methods /**jsdoc * @function Script.require * @param {string} module */ Q_INVOKABLE QScriptValue require(const QString& moduleId); /**jsdoc * @function Script.resetModuleCache * @param {boolean} [deleteScriptCache=false] */ Q_INVOKABLE void resetModuleCache(bool deleteScriptCache = false); QScriptValue currentModule(); bool registerModuleWithParent(const QScriptValue& module, const QScriptValue& parent); QScriptValue newModule(const QString& modulePath, const QScriptValue& parent = QScriptValue()); QVariantMap fetchModuleSource(const QString& modulePath, const bool forceDownload = false); QScriptValue instantiateModule(const QScriptValue& module, const QString& sourceCode); /**jsdoc * Call a function at a set interval. * @function Script.setInterval * @param {function} function - The function to call. Can be an in-line function or the name of a function. * @param {number} interval - The interval at which to call the function, in ms. * @returns {object} A handle to the interval timer. Can be used by {@link Script.clearInterval}. * @example <caption>Print a message every second.</caption> * Script.setInterval(function () { * print("Timer fired"); * }, 1000); */ Q_INVOKABLE QObject* setInterval(const QScriptValue& function, int intervalMS); /**jsdoc * Call a function after a delay. * @function Script.setTimeout * @param {function} function - The function to call. Can be an in-line function or the name of a function. * @param {number} timeout - The delay after which to call the function, in ms. * @returns {object} A handle to the timeout timer. Can be used by {@link Script.clearTimeout}. * @example <caption>Print a message after a second.</caption> * Script.setTimeout(function () { * print("Timer fired"); * }, 1000); */ Q_INVOKABLE QObject* setTimeout(const QScriptValue& function, int timeoutMS); /**jsdoc * Stop an interval timer set by {@link Script.setInterval|setInterval}. * @function Script.clearInterval * @param {object} timer - The interval timer to clear. * @example <caption>Stop an interval timer.</caption> * // Print a message every second. * var timer = Script.setInterval(function () { * print("Timer fired"); * }, 1000); * * // Stop the timer after 10 seconds. * Script.setTimeout(function () { * print("Stop timer"); * Script.clearInterval(timer); * }, 10000); */ Q_INVOKABLE void clearInterval(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); } /**jsdoc * Clear a timeout timer set by {@link Script.setTimeout|setTimeout}. * @function Script.clearTimeout * @param {object} timer - The timeout timer to clear. * @example <caption>Stop a timeout timer.</caption> * // Print a message after two seconds. * var timer = Script.setTimeout(function () { * print("Timer fired"); * }, 2000); * * // Uncomment the following line to stop the timer from firing. * //Script.clearTimeout(timer); */ Q_INVOKABLE void clearTimeout(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); } /**jsdoc * @function Script.print * @param {string} message */ Q_INVOKABLE void print(const QString& message); /**jsdoc * Resolve a relative path to an absolute path. * @function Script.resolvePath * @param {string} path - The relative path to resolve. * @returns {string} The absolute path. */ Q_INVOKABLE QUrl resolvePath(const QString& path) const; /**jsdoc * @function Script.resourcesPath * @returns {string} */ Q_INVOKABLE QUrl resourcesPath() const; /**jsdoc * @function Script.beginProfileRange * @param {string} label */ Q_INVOKABLE void beginProfileRange(const QString& label) const; /**jsdoc * @function Script.endProfileRange * @param {string} label */ Q_INVOKABLE void endProfileRange(const QString& label) const; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Entity Script Related methods /**jsdoc * @function Script.isEntityScriptRunning * @param {Uuid} entityID * @returns {boolean} */ Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID& entityID) { QReadLocker locker { &_entityScriptsLock }; auto it = _entityScripts.constFind(entityID); return it != _entityScripts.constEnd() && it->status == EntityScriptStatus::RUNNING; } QVariant cloneEntityScriptDetails(const EntityItemID& entityID); QFuture<QVariant> getLocalEntityScriptDetails(const EntityItemID& entityID) override; /**jsdoc * @function Script.loadEntityScript * @param {Uuid} entityID * @param {string} script * @param {boolean} forceRedownload */ Q_INVOKABLE void loadEntityScript(const EntityItemID& entityID, const QString& entityScript, bool forceRedownload); /**jsdoc * @function Script.unloadEntityScript * @param {Uuid} entityID * @param {boolean} [shouldRemoveFromMap=false] */ Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap = false); // will call unload method /**jsdoc * @function Script.unloadAllEntityScripts */ Q_INVOKABLE void unloadAllEntityScripts(); /**jsdoc * @function Script.callEntityScriptMethod * @param {Uuid} entityID * @param {string} methodName * @param {string[]} parameters * @param {Uuid} [remoteCallerID=Uuid.NULL] */ Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params = QStringList(), const QUuid& remoteCallerID = QUuid()) override;Lines 1–500 of 819. Load more
// // ScriptEngine.h // libraries/script-engine/src // // Created by Brad Hefta-Gaub on 12/14/13. // Copyright 2013 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef hifi_ScriptEngine_h #define hifi_ScriptEngine_h #include <unordered_map> #include <vector> #include <QtCore/QObject> #include <QtCore/QUrl> #include <QtCore/QSet> #include <QtCore/QWaitCondition> #include <QtCore/QStringList> #include <QtScript/QScriptEngine> #include <AnimationCache.h> #include <AnimVariant.h> #include <AvatarData.h> #include <AvatarHashMap.h> #include <LimitedNodeList.h> #include <EntityItemID.h> #include <EntitiesScriptEngineProvider.h> #include <EntityScriptUtils.h> #include "PointerEvent.h" #include "ArrayBufferClass.h" #include "AssetScriptingInterface.h" #include "AudioScriptingInterface.h" #include "BaseScriptEngine.h" #include "Quat.h" #include "Mat4.h" #include "ScriptCache.h" #include "ScriptUUID.h" #include "Vec3.h" #include "ConsoleScriptingInterface.h" #include "SettingHandle.h" #include "Profile.h" class QScriptEngineDebugger; static const QString NO_SCRIPT(""); static const int SCRIPT_FPS = 60; static const int DEFAULT_MAX_ENTITY_PPS = 9000; static const int DEFAULT_ENTITY_PPS_PER_SCRIPT = 900; class ScriptEngines; Q_DECLARE_METATYPE(ScriptEnginePointer) class CallbackData { public: QScriptValue function; EntityItemID definingEntityIdentifier; QUrl definingSandboxURL; }; class DeferredLoadEntity { public: EntityItemID entityID; QString entityScript; //bool forceRedownload; }; struct EntityScriptContentAvailable { EntityItemID entityID; QString scriptOrURL; QString contents; bool isURL; bool success; QString status; }; typedef std::unordered_map<EntityItemID, EntityScriptContentAvailable> EntityScriptContentAvailableMap; typedef QList<CallbackData> CallbackList; typedef QHash<QString, CallbackList> RegisteredEventHandlers; class EntityScriptDetails { public: EntityScriptStatus status { EntityScriptStatus::PENDING }; // If status indicates an error, this contains a human-readable string giving more information about the error. QString errorInfo { "" }; QString scriptText { "" }; QScriptValue scriptObject { QScriptValue() }; int64_t lastModified { 0 }; QUrl definingSandboxURL { QUrl("about:EntityScript") }; }; /**jsdoc * @namespace Script * * @hifi-interface * @hifi-client-entity * @hifi-server-entity * @hifi-assignment-client * * @property {string} context */ class ScriptEngine : public BaseScriptEngine, public EntitiesScriptEngineProvider { Q_OBJECT Q_PROPERTY(QString context READ getContext) public: enum Context { CLIENT_SCRIPT, ENTITY_CLIENT_SCRIPT, ENTITY_SERVER_SCRIPT, AGENT_SCRIPT }; enum Type { CLIENT, ENTITY_CLIENT, ENTITY_SERVER, AGENT, AVATAR }; static int processLevelMaxRetries; ScriptEngine(Context context, const QString& scriptContents = NO_SCRIPT, const QString& fileNameString = QString("about:ScriptEngine")); ~ScriptEngine(); /// run the script in a dedicated thread. This will have the side effect of evalulating /// the current script contents and calling run(). Callers will likely want to register the script with external /// services before calling this. void runInThread(); void runDebuggable(); /// run the script in the callers thread, exit when stop() is called. void run(); QString getFilename() const; /**jsdoc * Stop the current script. * @function Script.stop * @param {boolean} [marshal=false] */ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts Q_INVOKABLE void stop(bool marshal = false); // Stop any evaluating scripts and wait for the scripting thread to finish. void waitTillDoneRunning(); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - these are NOT intended to be public interfaces available to scripts, the are only Q_INVOKABLE so we can // properly ensure they are only called on the correct thread /**jsdoc * @function Script.registerGlobalObject * @param {string} name * @param {object} object */ /// registers a global object by name Q_INVOKABLE void registerGlobalObject(const QString& name, QObject* object); /**jsdoc * @function Script.registerGetterSetter * @param {string} name * @param {object} getter * @param {object} setter * @param {string} [parent=""] */ /// registers a global getter/setter Q_INVOKABLE void registerGetterSetter(const QString& name, QScriptEngine::FunctionSignature getter, QScriptEngine::FunctionSignature setter, const QString& parent = QString("")); /**jsdoc * @function Script.registerFunction * @param {string} name * @param {object} function * @param {number} [numArguments=-1] */ /// register a global function Q_INVOKABLE void registerFunction(const QString& name, QScriptEngine::FunctionSignature fun, int numArguments = -1); /**jsdoc * @function Script.registerFunction * @param {string} parent * @param {string} name * @param {object} function * @param {number} [numArguments=-1] */ /// register a function as a method on a previously registered global object Q_INVOKABLE void registerFunction(const QString& parent, const QString& name, QScriptEngine::FunctionSignature fun, int numArguments = -1); /**jsdoc * @function Script.registerValue * @param {string} name * @param {object} value */ /// registers a global object by name Q_INVOKABLE void registerValue(const QString& valueName, QScriptValue value); /**jsdoc * @function Script.evaluate * @param {string} program * @param {string} filename * @param {number} [lineNumber=-1] * @returns {object} */ /// evaluate some code in the context of the ScriptEngine and return the result Q_INVOKABLE QScriptValue evaluate(const QString& program, const QString& fileName, int lineNumber = 1); // this is also used by the script tool widget /**jsdoc * @function Script.evaluateInClosure * @param {object} locals * @param {object} program * @returns {object} */ Q_INVOKABLE QScriptValue evaluateInClosure(const QScriptValue& locals, const QScriptProgram& program); /// if the script engine is not already running, this will download the URL and start the process of seting it up /// to run... NOTE - this is used by Application currently to load the url. We don't really want it to be exposed /// to scripts. we may not need this to be invokable void loadURL(const QUrl& scriptURL, bool reload); bool hasValidScriptSuffix(const QString& scriptFileName); /**jsdoc * @function Script.getContext * @returns {string} */ Q_INVOKABLE QString getContext() const; /**jsdoc * @function Script.isClientScript * @returns {boolean} */ Q_INVOKABLE bool isClientScript() const { return _context == CLIENT_SCRIPT; } /**jsdoc * @function Script.isDebugMode * @returns {boolean} */ Q_INVOKABLE bool isDebugMode() const; /**jsdoc * @function Script.isEntityClientScript * @returns {boolean} */ Q_INVOKABLE bool isEntityClientScript() const { return _context == ENTITY_CLIENT_SCRIPT; } /**jsdoc * @function Script.isEntityServerScript * @returns {boolean} */ Q_INVOKABLE bool isEntityServerScript() const { return _context == ENTITY_SERVER_SCRIPT; } /**jsdoc * @function Script.isAgentScript * @returns {boolean} */ Q_INVOKABLE bool isAgentScript() const { return _context == AGENT_SCRIPT; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - these are intended to be public interfaces available to scripts /**jsdoc * @function Script.addEventHandler * @param {Uuid} entityID * @param {string} eventName * @param {function} handler */ Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); /**jsdoc * @function Script.removeEventHandler * @param {Uuid} entityID * @param {string} eventName * @param {function} handler */ Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); /**jsdoc * Start a new Interface or entity script. * @function Script.load * @param {string} filename - The URL of the script to load. Can be relative to the current script. * @example <caption>Load a script from another script.</caption> * // First file: scriptA.js * print("This is script A"); * * // Second file: scriptB.js * print("This is script B"); * Script.load("scriptA.js"); * * // If you run scriptB.js you should see both scripts in the running scripts list. * // And you should see the following output: * // This is script B * // This is script A */ Q_INVOKABLE void load(const QString& loadfile); /**jsdoc * Include JavaScript from other files in the current script. If a callback is specified the files are loaded and included * asynchronously, otherwise they are included synchronously (i.e., script execution blocks while the files are included). * @function Script.include * @param {string[]} filenames - The URLs of the scripts to include. Each can be relative to the current script. * @param {function} [callback=null] - The function to call back when the scripts have been included. Can be an in-line * function or the name of a function. */ Q_INVOKABLE void include(const QStringList& includeFiles, QScriptValue callback = QScriptValue()); /**jsdoc * Include JavaScript from another file in the current script. If a callback is specified the file is loaded and included * asynchronously, otherwise it is included synchronously (i.e., script execution blocks while the file is included). * @function Script.include * @param {string} filename - The URL of the script to include. Can be relative to the current script. * @param {function} [callback=null] - The function to call back when the script has been included. Can be an in-line * function or the name of a function. * @example <caption>Include a script file asynchronously.</caption> * // First file: scriptA.js * print("This is script A"); * * // Second file: scriptB.js * print("This is script B"); * Script.include("scriptA.js", function () { * print("Script A has been included"); * }); * * // If you run scriptB.js you should see only scriptB.js in the running scripts list. * // And you should see the following output: * // This is script B * // This is script A * // Script A has been included */ Q_INVOKABLE void include(const QString& includeFile, QScriptValue callback = QScriptValue()); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MODULE related methods /**jsdoc * @function Script.require * @param {string} module */ Q_INVOKABLE QScriptValue require(const QString& moduleId); /**jsdoc * @function Script.resetModuleCache * @param {boolean} [deleteScriptCache=false] */ Q_INVOKABLE void resetModuleCache(bool deleteScriptCache = false); QScriptValue currentModule(); bool registerModuleWithParent(const QScriptValue& module, const QScriptValue& parent); QScriptValue newModule(const QString& modulePath, const QScriptValue& parent = QScriptValue()); QVariantMap fetchModuleSource(const QString& modulePath, const bool forceDownload = false); QScriptValue instantiateModule(const QScriptValue& module, const QString& sourceCode); /**jsdoc * Call a function at a set interval. * @function Script.setInterval * @param {function} function - The function to call. Can be an in-line function or the name of a function. * @param {number} interval - The interval at which to call the function, in ms. * @returns {object} A handle to the interval timer. Can be used by {@link Script.clearInterval}. * @example <caption>Print a message every second.</caption> * Script.setInterval(function () { * print("Timer fired"); * }, 1000); */ Q_INVOKABLE QObject* setInterval(const QScriptValue& function, int intervalMS); /**jsdoc * Call a function after a delay. * @function Script.setTimeout * @param {function} function - The function to call. Can be an in-line function or the name of a function. * @param {number} timeout - The delay after which to call the function, in ms. * @returns {object} A handle to the timeout timer. Can be used by {@link Script.clearTimeout}. * @example <caption>Print a message after a second.</caption> * Script.setTimeout(function () { * print("Timer fired"); * }, 1000); */ Q_INVOKABLE QObject* setTimeout(const QScriptValue& function, int timeoutMS); /**jsdoc * Stop an interval timer set by {@link Script.setInterval|setInterval}. * @function Script.clearInterval * @param {object} timer - The interval timer to clear. * @example <caption>Stop an interval timer.</caption> * // Print a message every second. * var timer = Script.setInterval(function () { * print("Timer fired"); * }, 1000); * * // Stop the timer after 10 seconds. * Script.setTimeout(function () { * print("Stop timer"); * Script.clearInterval(timer); * }, 10000); */ Q_INVOKABLE void clearInterval(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); } /**jsdoc * Clear a timeout timer set by {@link Script.setTimeout|setTimeout}. * @function Script.clearTimeout * @param {object} timer - The timeout timer to clear. * @example <caption>Stop a timeout timer.</caption> * // Print a message after two seconds. * var timer = Script.setTimeout(function () { * print("Timer fired"); * }, 2000); * * // Uncomment the following line to stop the timer from firing. * //Script.clearTimeout(timer); */ Q_INVOKABLE void clearTimeout(QObject* timer) { stopTimer(reinterpret_cast<QTimer*>(timer)); } /**jsdoc * @function Script.print * @param {string} message */ Q_INVOKABLE void print(const QString& message); /**jsdoc * Resolve a relative path to an absolute path. * @function Script.resolvePath * @param {string} path - The relative path to resolve. * @returns {string} The absolute path. */ Q_INVOKABLE QUrl resolvePath(const QString& path) const; /**jsdoc * @function Script.resourcesPath * @returns {string} */ Q_INVOKABLE QUrl resourcesPath() const; /**jsdoc * @function Script.beginProfileRange * @param {string} label */ Q_INVOKABLE void beginProfileRange(const QString& label) const; /**jsdoc * @function Script.endProfileRange * @param {string} label */ Q_INVOKABLE void endProfileRange(const QString& label) const; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Entity Script Related methods /**jsdoc * @function Script.isEntityScriptRunning * @param {Uuid} entityID * @returns {boolean} */ Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID& entityID) { QReadLocker locker { &_entityScriptsLock }; auto it = _entityScripts.constFind(entityID); return it != _entityScripts.constEnd() && it->status == EntityScriptStatus::RUNNING; } QVariant cloneEntityScriptDetails(const EntityItemID& entityID); QFuture<QVariant> getLocalEntityScriptDetails(const EntityItemID& entityID) override; /**jsdoc * @function Script.loadEntityScript * @param {Uuid} entityID * @param {string} script * @param {boolean} forceRedownload */ Q_INVOKABLE void loadEntityScript(const EntityItemID& entityID, const QString& entityScript, bool forceRedownload); /**jsdoc * @function Script.unloadEntityScript * @param {Uuid} entityID * @param {boolean} [shouldRemoveFromMap=false] */ Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap = false); // will call unload method /**jsdoc * @function Script.unloadAllEntityScripts */ Q_INVOKABLE void unloadAllEntityScripts(); /**jsdoc * @function Script.callEntityScriptMethod * @param {Uuid} entityID * @param {string} methodName * @param {string[]} parameters * @param {Uuid} [remoteCallerID=Uuid.NULL] */ Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params = QStringList(), const QUuid& remoteCallerID = QUuid()) override;