diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index c072dedaf9..39700bfc31 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -1770,6 +1770,7 @@ signals: /**jsdoc * Triggered on the client that is the physics simulation owner during the collision of two entities. Note: Isn't triggered * for a collision with an avatar. + *

See also, {@link Script.addEventHandler}.

* @function Entities.collisionWithEntity * @param {Uuid} idA - The ID of one entity in the collision. For an entity script, this is the ID of the entity containing * the script. @@ -1882,6 +1883,7 @@ signals: /**jsdoc * Triggered when a mouse button is clicked while the mouse cursor is on an entity, or a controller trigger is fully * pressed while its laser is on an entity. + *

See also, {@link Script.addEventHandler}.

* @function Entities.mousePressOnEntity * @param {Uuid} entityID - The ID of the entity that was pressed. * @param {PointerEvent} event - Details of the event. @@ -1906,6 +1908,7 @@ signals: /**jsdoc * Repeatedly triggered while the mouse cursor or controller laser moves on an entity. + *

See also, {@link Script.addEventHandler}.

* @function Entities.mouseMoveOnEntity * @param {Uuid} entityID - The ID of the entity that was moved on. * @param {PointerEvent} event - Details of the event. @@ -1916,6 +1919,7 @@ signals: /**jsdoc * Triggered when a mouse button is released after clicking on an entity or the controller trigger is partly or fully * released after pressing on an entity, even if the mouse pointer or controller laser has moved off the entity. + *

See also, {@link Script.addEventHandler}.

* @function Entities.mouseReleaseOnEntity * @param {Uuid} entityID - The ID of the entity that was originally pressed. * @param {PointerEvent} event - Details of the event. @@ -1942,6 +1946,7 @@ signals: /**jsdoc * Triggered when a mouse button is clicked while the mouse cursor is on an entity. Note: Not triggered by controller. + *

See also, {@link Script.addEventHandler}.

* @function Entities.clickDownOnEntity * @param {Uuid} entityID - The ID of the entity that was clicked. * @param {PointerEvent} event - Details of the event. @@ -1952,6 +1957,7 @@ signals: /**jsdoc * Repeatedly triggered while a mouse button continues to be held after clicking an entity, even if the mouse cursor has * moved off the entity. Note: Not triggered by controller. + *

See also, {@link Script.addEventHandler}.

* @function Entities.holdingClickOnEntity * @param {Uuid} entityID - The ID of the entity that was originally clicked. * @param {PointerEvent} event - Details of the event. @@ -1962,6 +1968,7 @@ signals: /**jsdoc * Triggered when a mouse button is released after clicking on an entity, even if the mouse cursor has moved off the * entity. Note: Not triggered by controller. + *

See also, {@link Script.addEventHandler}.

* @function Entities.clickReleaseOnEntity * @param {Uuid} entityID - The ID of the entity that was originally clicked. * @param {PointerEvent} event - Details of the event. @@ -1971,6 +1978,7 @@ signals: /**jsdoc * Triggered when the mouse cursor or controller laser starts hovering on an entity. + *

See also, {@link Script.addEventHandler}.

* @function Entities.hoverEnterEntity * @param {Uuid} entityID - The ID of the entity that is being hovered. * @param {PointerEvent} event - Details of the event. @@ -1980,6 +1988,7 @@ signals: /**jsdoc * Repeatedly triggered when the mouse cursor or controller laser moves while hovering over an entity. + *

See also, {@link Script.addEventHandler}.

* @function Entities.hoverOverEntity * @param {Uuid} entityID - The ID of the entity that is being hovered. * @param {PointerEvent} event - Details of the event. @@ -1989,6 +1998,7 @@ signals: /**jsdoc * Triggered when the mouse cursor or controller laser stops hovering over an entity. + *

See also, {@link Script.addEventHandler}.

* @function Entities.hoverLeaveEntity * @param {Uuid} entityID - The ID of the entity that was being hovered. * @param {PointerEvent} event - Details of the event. @@ -1999,6 +2009,7 @@ signals: /**jsdoc * Triggered when an avatar enters an entity. + *

See also, {@link Script.addEventHandler}.

* @function Entities.enterEntity * @param {Uuid} entityID - The ID of the entity that the avatar entered. * @returns {Signal} @@ -2032,6 +2043,7 @@ signals: /**jsdoc * Triggered when an avatar leaves an entity. + *

See also, {@link Script.addEventHandler}.

* @function Entities.leaveEntity * @param {Uuid} entityID - The ID of the entity that the avatar left. * @returns {Signal} diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 7abb63ca1c..309161206c 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -987,6 +987,31 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& }; }; + /**jsdoc + * The name of an entity event. When the entity event occurs, any function that has been registered for that event via + * {@link Script.addEventHandler} is called with parameters per the entity event. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Event NameEntity Event
"enterEntity"{@link Entities.enterEntity}
"leaveEntity"{@link Entities.leaveEntity}
"mousePressOnEntity"{@link Entities.mousePressOnEntity}
"mouseMoveOnEntity"{@link Entities.mouseMoveOnEntity}
"mouseReleaseOnEntity"{@link Entities.mouseReleaseOnEntity}
"clickDownOnEntity"{@link Entities.clickDownOnEntity}
"holdingClickOnEntity"{@link Entities.holdingClickOnEntity}
"clickReleaseOnEntity"{@link Entities.clickReleaseOnEntity}
"hoverEnterEntity"{@link Entities.hoverEnterEntity}
"hoverOverEntity"{@link Entities.hoverOverEntity}
"hoverLeaveEntity"{@link Entities.hoverLeaveEntity}
"collisionWithEntity"{@link Entities.collisionWithEntity}
+ * + * @typedef {string} Script.EntityEvent + */ connect(entities.data(), &EntityScriptingInterface::enterEntity, this, makeSingleEntityHandler("enterEntity")); connect(entities.data(), &EntityScriptingInterface::leaveEntity, this, makeSingleEntityHandler("leaveEntity")); @@ -2147,7 +2172,7 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& } /**jsdoc - * Triggered when the script starts for a user. + * Triggered when the script starts for a user. See also, {@link Script.entityScriptPreloadFinished}. *

Note: Can only be connected to via this.preload = function (...) { ... } in the entity script.

*
Available in:Client Entity ScriptsServer Entity Scripts
* @function Entities.preload @@ -2161,7 +2186,7 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& * this.entityID = entityID; * print("Entity ID: " + this.entityID); * }; - * ); + * }); * * var entityID = Entities.addEntity({ * type: "Box", diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index b81829aa54..c6b1135fc6 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -110,7 +110,14 @@ public: * @hifi-server-entity * @hifi-assignment-client * - * @property {string} context + * @property {string} context - The context that the script is running in: + * + * Read-only. */ class ScriptEngine : public BaseScriptEngine, public EntitiesScriptEngineProvider { Q_OBJECT @@ -153,6 +160,7 @@ public: /**jsdoc * Stops and unloads the current script. + *

Warning: If an assignment client script, the script gets restarted after stopping.

* @function Script.stop * @param {boolean} [marshal=false] - Marshal. *

Deprecated: This parameter is deprecated and will be removed.

@@ -255,38 +263,53 @@ public: bool hasValidScriptSuffix(const QString& scriptFileName); /**jsdoc + * Gets the context that the script is running in: Interface/avatar, client entity, server entity, or assignment client. * @function Script.getContext - * @returns {string} + * @returns {string} The context that the script is running in: + * */ Q_INVOKABLE QString getContext() const; /**jsdoc + * Checks whether the script is running as an Interface or avatar script. * @function Script.isClientScript - * @returns {boolean} + * @returns {boolean} true if the script is running as an Interface or avatar script, false if it + * isn't. */ Q_INVOKABLE bool isClientScript() const { return _context == CLIENT_SCRIPT; } /**jsdoc + * Checks whether the application was compiled as a debug build. * @function Script.isDebugMode - * @returns {boolean} + * @returns {boolean} true if the software was compiled as a debug build, false if it was + * compiled as a release build. */ Q_INVOKABLE bool isDebugMode() const; /**jsdoc + * Checks whether the script content is a client entity script. * @function Script.isEntityClientScript - * @returns {boolean} + * @returns {boolean} true if the script is running as a client entity script, false if it isn't. */ Q_INVOKABLE bool isEntityClientScript() const { return _context == ENTITY_CLIENT_SCRIPT; } /**jsdoc + * Checks whether the script context is a server entity script. * @function Script.isEntityServerScript - * @returns {boolean} + * @returns {boolean} true if the script is running as a server entity script, false if it isn't. */ Q_INVOKABLE bool isEntityServerScript() const { return _context == ENTITY_SERVER_SCRIPT; } /**jsdoc + * Checks whether the script is running as an assignment client script. * @function Script.isAgentScript - * @returns {boolean} + * @returns {boolean} true if the script is running as an assignment client script, false if it + * isn't. */ Q_INVOKABLE bool isAgentScript() const { return _context == AGENT_SCRIPT; } @@ -294,24 +317,40 @@ public: // NOTE - these are intended to be public interfaces available to scripts /**jsdoc + * Adds a function to the list of functions called upon the occurrence of an entity event on a particular entity. * @function Script.addEventHandler - * @param {Uuid} entityID - * @param {string} eventName - * @param {function} handler + * @param {Uuid} entityID - The ID of the entity. + * @param {Script.EntityEvent} eventName - The name of the entity event. + * @param {function} handler - The function to call when the entity event occurs on the entity. It can be either the name + * of a function or an in-line definition. + * @example Report when a mouse press occurs on a particular entity. + * var entityID = Entities.addEntity({ + * type: "Box", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * dimensions: { x: 0.5, y: 0.5, z: 0.5 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * function reportMousePress(entityID, event) { + * print("Mouse pressed on entity: " + JSON.stringify(event)); + * } + * + * Script.addEventHandler(entityID, "mousePressOnEntity", reportMousePress); */ Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); /**jsdoc + * Removes a function from the list of functions called upon the occurrence of an entity event on a particular entity. * @function Script.removeEventHandler - * @param {Uuid} entityID - * @param {string} eventName - * @param {function} handler + * @param {Uuid} entityID - The ID of the entity. + * @param {Script.EntityEvent} eventName - The name of the entity event. + * @param {function} handler - The name of the function to no longer call when the entity event occurs on the entity. */ Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); /**jsdoc * Starts running another script in Interface. - *

Note: Only works for Interface and avatar scripts.

+ *
Available in:Interface ScriptsAvatar Scripts
* @function Script.load * @param {string} filename - The URL of the script to load. This can be relative to the current script's URL. * @example Load a script from another script. @@ -336,8 +375,8 @@ public: * @function Script.include * @variation 0 * @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. It can be an in-line - * function or the name of a function. + * @param {function} [callback=null] - The function to call back when the scripts have been included. It can be either the + * name of a function or an in-line definition. */ Q_INVOKABLE void include(const QStringList& includeFiles, QScriptValue callback = QScriptValue()); @@ -346,8 +385,8 @@ public: * 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. It can be relative to the current script. - * @param {function} [callback=null] - The function to call back when the script has been included. It can be an in-line - * function or the name of a function. + * @param {function} [callback=null] - The function to call back when the script has been included. It can be either the + * name of a function or an in-line definition. * @example Include a script file asynchronously. * // First file: scriptA.js * print("This is script A"); @@ -370,14 +409,18 @@ public: // MODULE related methods /**jsdoc + * Provides access to methods or objects provided in an external JavaScript or JSON file. + * See {@link https://docs.highfidelity.com/script/js-tips.html} for further details. * @function Script.require - * @param {string} module + * @param {string} module - The module to use. May be a JavaScript file or the name of system model such as + * "sppUi". */ Q_INVOKABLE QScriptValue require(const QString& moduleId); /**jsdoc * @function Script.resetModuleCache - * @param {boolean} [deleteScriptCache=false] + * @param {boolean} [deleteScriptCache=false] - Delete script cache. + * @deprecated This function is deprecated and will be removed. */ Q_INVOKABLE void resetModuleCache(bool deleteScriptCache = false); @@ -390,7 +433,7 @@ public: /**jsdoc * Calls a function repeatedly, at a set interval. * @function Script.setInterval - * @param {function} function - The function to call. This can be an in-line function or the name of a function. + * @param {function} function - The function to call. This can be either the name of a function or an in-line definition. * @param {number} interval - The interval at which to call the function, in ms. * @returns {object} A handle to the interval timer. This can be used by {@link Script.clearInterval}. * @example Print a message every second. @@ -403,7 +446,7 @@ public: /**jsdoc * Calls a function once, after a delay. * @function Script.setTimeout - * @param {function} function - The function to call. This can be an in-line function or the name of a function. + * @param {function} function - The function to call. This can be either the name of a function or an in-line definition. * @param {number} timeout - The delay after which to call the function, in ms. * @returns {object} A handle to the timeout timer. This can be used by {@link Script.clearTimeout}. * @example Print a message once, after a second. @@ -447,8 +490,16 @@ public: Q_INVOKABLE void clearTimeout(QObject* timer) { stopTimer(reinterpret_cast(timer)); } /**jsdoc + * Prints a message to the program log. + *

Alternatively, you can use {@link print}, {@link console.log}, or one of the other {@link console} methods.

* @function Script.print - * @param {string} message + * @param {string} message - The message to print. + */ + /**jsdoc + * Prints a message to the program log. + *

This is an alias of {@link Script.print}.

+ * @function print + * @param {string} message - The message to print. */ Q_INVOKABLE void print(const QString& message); @@ -467,20 +518,25 @@ public: Q_INVOKABLE QUrl resolvePath(const QString& path) const; /**jsdoc + * Gets the path to the resources directory for QML files. * @function Script.resourcesPath - * @returns {string} + * @returns {string} The path to the resources directory for QML files. */ Q_INVOKABLE QUrl resourcesPath() const; /**jsdoc + * Starts timing a section of code in order to send usage data about it to High Fidelity. Shouldn't be used outside of the + * standard scripts. * @function Script.beginProfileRange - * @param {string} label + * @param {string} label - A name that identifies the section of code. */ Q_INVOKABLE void beginProfileRange(const QString& label) const; /**jsdoc + * Finishes timing a section of code in order to send usage data about it to High Fidelity. Shouldn't be used outside of + * the standard scripts. * @function Script.endProfileRange - * @param {string} label + * @param {string} label - A name that identifies the section of code. */ Q_INVOKABLE void endProfileRange(const QString& label) const; @@ -488,9 +544,10 @@ public: // Entity Script Related methods /**jsdoc + * Checks whether an entity has an entity script running. * @function Script.isEntityScriptRunning - * @param {Uuid} entityID - * @returns {boolean} + * @param {Uuid} entityID - The ID of the entity. + * @returns {boolean} true if the entity has an entity script running, false if it doesn't. */ Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID& entityID) { QReadLocker locker { &_entityScriptsLock }; @@ -524,34 +581,41 @@ public: Q_INVOKABLE void unloadAllEntityScripts(); /**jsdoc + * Calls a method in an entity script. * @function Script.callEntityScriptMethod - * @param {Uuid} entityID - * @param {string} methodName - * @param {string[]} [parameters=[]] - * @param {Uuid} [remoteCallerID=Uuid.NULL] + * @param {Uuid} entityID - The ID of the entity running the entity script. + * @param {string} methodName - The name of the method to call. + * @param {string[]} [parameters=[]] - The parameters to call the specified method with. + * @param {Uuid} [remoteCallerID=Uuid.NULL] - An ID that identifies the caller. */ Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params = QStringList(), const QUuid& remoteCallerID = QUuid()) override; /**jsdoc + * Calls a method in an entity script. * @function Script.callEntityScriptMethod - * @param {Uuid} entityID - * @param {string} methodName - * @param {PointerEvent} event + * @param {Uuid} entityID - Entity ID. + * @param {string} methodName - Method name. + * @param {PointerEvent} event - Pointer event. + * @deprecated This function is deprecated and will be removed. */ Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const PointerEvent& event); /**jsdoc + * Calls a method in an entity script. * @function Script.callEntityScriptMethod - * @param {Uuid} entityID - * @param {string} methodName - * @param {Uuid} otherID - * @param {Collision} collision + * @param {Uuid} entityID - Entity ID. + * @param {string} methodName - Method name. + * @param {Uuid} otherID - Other entity ID. + * @param {Collision} collision - Collision. + * @deprecated This function is deprecated and will be removed. */ Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision); /**jsdoc + * Manually runs the JavaScript garbage collector which reclaims memory by disposing of objects that are no longer + * reachable. * @function Script.requestGarbageCollection */ Q_INVOKABLE void requestGarbageCollection() { collectGarbage(); } @@ -625,15 +689,17 @@ signals: /**jsdoc * @function Script.scriptLoaded - * @param {string} filename + * @param {string} filename - File name. * @returns {Signal} + * @deprecated This signal is deprecated and will be removed. */ void scriptLoaded(const QString& scriptFilename); /**jsdoc * @function Script.errorLoadingScript - * @param {string} filename + * @param {string} filename - File name. * @returns {Signal} + * @deprecated This signal is deprecated and will be removed. */ void errorLoadingScript(const QString& scriptFilename); @@ -685,38 +751,44 @@ signals: void cleanupMenuItem(const QString& menuItemString); /**jsdoc + * Triggered when a script prints a message to the program log via {@link Script.print}, {@link print}, + * {@link console.log}, {@link console.info}, {@link console.warn}, {@link console.error}, or {@link console.debug}. * @function Script.printedMessage - * @param {string} message - * @param {string} scriptName + * @param {string} message - The message. + * @param {string} scriptName - The name of the script that generated the message. * @returns {Signal} */ void printedMessage(const QString& message, const QString& scriptName); /**jsdoc + * Triggered when a script generates an error or {@link console.error} is called. * @function Script.errorMessage - * @param {string} message - * @param {string} scriptName + * @param {string} message - The error message. + * @param {string} scriptName - The name of the script that generated the error message. * @returns {Signal} */ void errorMessage(const QString& message, const QString& scriptName); /**jsdoc + * Triggered when a script generates a warning or {@link console.warn} is called. * @function Script.warningMessage - * @param {string} message - * @param {string} scriptName + * @param {string} message - The warning message. + * @param {string} scriptName - The name of the script that generated the warning message. * @returns {Signal} */ void warningMessage(const QString& message, const QString& scriptName); /**jsdoc + * Triggered when a script generates an information message or {@link console.info} is called. * @function Script.infoMessage - * @param {string} message - * @param {string} scriptName + * @param {string} message - The information message. + * @param {string} scriptName - The name of the script that generated the information message. * @returns {Signal} */ void infoMessage(const QString& message, const QString& scriptName); /**jsdoc + * Triggered when the running state of the script changes, e.g., from running to stopping. * @function Script.runningStateChanged * @returns {Signal} */ @@ -731,21 +803,24 @@ signals: /**jsdoc * @function Script.loadScript - * @param {string} scriptName - * @param {boolean} isUserLoaded + * @param {string} scriptName - Script name. + * @param {boolean} isUserLoaded - Is user loaded. * @returns {Signal} + * @deprecated This signal is deprecated and will be removed. */ void loadScript(const QString& scriptName, bool isUserLoaded); /**jsdoc * @function Script.reloadScript - * @param {string} scriptName - * @param {boolean} isUserLoaded + * @param {string} scriptName - Script name. + * @param {boolean} isUserLoaded - Is user loaded. * @returns {Signal} + * @deprecated This signal is deprecated and will be removed. */ void reloadScript(const QString& scriptName, bool isUserLoaded); /**jsdoc + * Triggered when the script has stopped. * @function Script.doneRunning * @returns {Signal} */ @@ -761,9 +836,28 @@ signals: void entityScriptDetailsUpdated(); /**jsdoc + * Triggered when the script starts for the user. See also, {@link Entities.preload}. + *
Available in:Client Entity ScriptsServer Entity Scripts
* @function Script.entityScriptPreloadFinished - * @param {Uuid} entityID + * @param {Uuid} entityID - The ID of the entity that the script is running in. * @returns {Signal} + * @example Get the ID of the entity that a client entity script is running in. + * var entityScript = (function () { + * this.entityID = Uuid.NULL; + * + * Script.entityScriptPreloadFinished.connect(function (entityID) { + * this.entityID = entityID; + * print("Entity ID: " + this.entityID); + * }); + * + * var entityID = Entities.addEntity({ + * type: "Box", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * dimensions: { x: 0.5, y: 0.5, z: 0.5 }, + * color: { red: 255, green: 0, blue: 0 }, + * script: "(" + entityScript + ")", // Could host the script on a Web server instead. + * lifetime: 300 // Delete after 5 minutes. + * }); */ // Emitted when an entity script has finished running preload void entityScriptPreloadFinished(const EntityItemID& entityID); diff --git a/libraries/shared/src/BaseScriptEngine.h b/libraries/shared/src/BaseScriptEngine.h index 6baa5d3c35..b750c20028 100644 --- a/libraries/shared/src/BaseScriptEngine.h +++ b/libraries/shared/src/BaseScriptEngine.h @@ -33,10 +33,11 @@ public: /**jsdoc * @function Script.lintScript - * @param {string} sourceCode - * @param {string} fileName - * @param {number} [lineNumber=1] - * @returns {object} + * @param {string} sourceCode - Source code. + * @param {string} fileName - File name. + * @param {number} [lineNumber=1] - Line number. + * @returns {object} Object. + * @deprecated This function is deprecated and will be removed. */ Q_INVOKABLE QScriptValue lintScript(const QString& sourceCode, const QString& fileName, const int lineNumber = 1); @@ -80,9 +81,15 @@ signals: // Script.signalHandlerException is exposed by QScriptEngine. /**jsdoc + * Triggered when a script generates an unhandled exception. * @function Script.unhandledException - * @param {object} exception + * @param {object} exception - The details of the exception. * @returns {Signal} + * @example Report the details of an unhandled exception. + * Script.unhandledException.connect(function (exception) { + * print("Unhandled exception: " + JSON.stringify(exception)); + * }); + * var properties = JSON.parse("{ x: 1"); // Invalid JSON string. */ void unhandledException(const QScriptValue& exception);