History

Create ScriptManagerScriptingInterface to move off the scripting API into its own class

Add a lot of documentation

Dale Glass committed 3 years ago

Commit 4d701551 parent 9e217923 files · +1598 −536Browse files

Showing the changes to libraries/script-engine/src/ScriptManagerScriptingInterface.h (1 of 3 files). Show all

Unified · Split

libraries/script-engine/src/ScriptManagerScriptingInterface.h+717−0
@@ -0,0 +1,717 @@
1+//
2+// ScriptManagerScriptingInterface.h
3+// libraries/script-engine/src
4+//
5+// Created by Dale Glass on 24/02/2023.
6+// Copyright 2022 Overte e.V.
7+//
8+// Distributed under the Apache License, Version 2.0.
9+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10+//
11+
12+#pragma once
13+
14+#include <QObject>
15+#include "ScriptManager.h"
16+
17+
18+/**jsdoc
19+ * The <code>Script</code> API provides facilities for working with scripts.
20+ *
21+ * @namespace Script
22+ *
23+ * @hifi-interface
24+ * @hifi-client-entity
25+ * @hifi-avatar
26+ * @hifi-server-entity
27+ * @hifi-assignment-client
28+ *
29+ * @property {string} context - The context that the script is running in:
30+ * <ul>
31+ * <li><code>"client"</code>: An Interface or avatar script.</li>
32+ * <li><code>"entity_client"</code>: A client entity script.</li>
33+ * <li><code>"entity_server"</code>: A server entity script.</li>
34+ * <li><code>"agent"</code>: An assignment client script.</li>
35+ * </ul>
36+ * <em>Read-only.</em>
37+ * @property {string} type - The type of script that is running:
38+ * <ul>
39+ * <li><code>"client"</code>: An Interface script.</li>
40+ * <li><code>"entity_client"</code>: A client entity script.</li>
41+ * <li><code>"avatar"</code>: An avatar script.</li>
42+ * <li><code>"entity_server"</code>: A server entity script.</li>
43+ * <li><code>"agent"</code>: An assignment client script.</li>
44+ * </ul>
45+ * <em>Read-only.</em>
46+ * @property {string} filename - The filename of the script file.
47+ * <em>Read-only.</em>
48+ * @property {Script.ResourceBuckets} ExternalPaths - External resource buckets.
49+ */
50+
51+class ScriptManagerScriptingInterface : public QObject {
52+ Q_OBJECT
53+public:
54+ ScriptManagerScriptingInterface(ScriptManager *parent) : QObject(parent), _manager(parent) {
55+
56+ connect(_manager, &ScriptManager::scriptLoaded, this, &ScriptManagerScriptingInterface::scriptLoaded);
57+ connect(_manager, &ScriptManager::errorLoadingScript, this, &ScriptManagerScriptingInterface::errorLoadingScript);
58+ connect(_manager, &ScriptManager::update, this, &ScriptManagerScriptingInterface::update);
59+ connect(_manager, &ScriptManager::scriptEnding, this, &ScriptManagerScriptingInterface::scriptEnding);
60+ connect(_manager, &ScriptManager::finished, this, &ScriptManagerScriptingInterface::finished);
61+ connect(_manager, &ScriptManager::printedMessage, this, &ScriptManagerScriptingInterface::printedMessage);
62+ connect(_manager, &ScriptManager::errorMessage, this, &ScriptManagerScriptingInterface::errorMessage);
63+ connect(_manager, &ScriptManager::warningMessage, this, &ScriptManagerScriptingInterface::warningMessage);
64+ connect(_manager, &ScriptManager::infoMessage, this, &ScriptManagerScriptingInterface::infoMessage);
65+ connect(_manager, &ScriptManager::runningStateChanged, this, &ScriptManagerScriptingInterface::runningStateChanged);
66+ connect(_manager, &ScriptManager::clearDebugWindow, this, &ScriptManagerScriptingInterface::clearDebugWindow);
67+ connect(_manager, &ScriptManager::loadScript, this, &ScriptManagerScriptingInterface::loadScript);
68+ connect(_manager, &ScriptManager::doneRunning, this, &ScriptManagerScriptingInterface::doneRunning);
69+ connect(_manager, &ScriptManager::entityScriptDetailsUpdated, this, &ScriptManagerScriptingInterface::entityScriptDetailsUpdated);
70+ connect(_manager, &ScriptManager::entityScriptPreloadFinished, this, &ScriptManagerScriptingInterface::entityScriptPreloadFinished);
71+ connect(_manager, &ScriptManager::unhandledException, this, &ScriptManagerScriptingInterface::unhandledException);
72+ }
73+
74+ /**jsdoc
75+ * Stops and unloads the current script.
76+ * <p><strong>Warning:</strong> If an assignment client script, the script gets restarted after stopping.</p>
77+ * @function Script.stop
78+ * @param {boolean} [marshal=false] - Marshal.
79+ * <p class="important">Deprecated: This parameter is deprecated and will be removed.</p>
80+ * @example <caption>Stop a script after 5s.</caption>
81+ * Script.setInterval(function () {
82+ * print("Hello");
83+ * }, 1000);
84+ *
85+ * Script.setTimeout(function () {
86+ * Script.stop(true);
87+ * }, 5000);
88+ */
89+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
90+ // NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts
91+ Q_INVOKABLE void stop(bool marshal = false) { _manager->stop(marshal); }
92+
93+ /**jsdoc
94+ * Gets the context that the script is running in: Interface/avatar, client entity, server entity, or assignment client.
95+ * @function Script.getContext
96+ * @returns {string} The context that the script is running in:
97+ * <ul>
98+ * <li><code>"client"</code>: An Interface or avatar script.</li>
99+ * <li><code>"entity_client"</code>: A client entity script.</li>
100+ * <li><code>"entity_server"</code>: A server entity script.</li>
101+ * <li><code>"agent"</code>: An assignment client script.</li>
102+ * </ul>
103+ */
104+ Q_INVOKABLE QString getContext() const { return _manager->getContext(); }
105+
106+
107+ /**jsdoc
108+ * Checks whether the script is running as an Interface or avatar script.
109+ * @function Script.isClientScript
110+ * @returns {boolean} <code>true</code> if the script is running as an Interface or avatar script, <code>false</code> if it
111+ * isn't.
112+ */
113+ Q_INVOKABLE bool isClientScript() const { return _manager->isClientScript(); }
114+
115+ /**jsdoc
116+ * Checks whether the application was compiled as a debug build.
117+ * @function Script.isDebugMode
118+ * @returns {boolean} <code>true</code> if the application was compiled as a debug build, <code>false</code> if it was
119+ * compiled as a release build.
120+ */
121+ Q_INVOKABLE bool isDebugMode() const { return _manager->isDebugMode(); }
122+
123+ /**jsdoc
124+ * Checks whether the script is running as a client entity script.
125+ * @function Script.isEntityClientScript
126+ * @returns {boolean} <code>true</code> if the script is running as a client entity script, <code>false</code> if it isn't.
127+ */
128+ Q_INVOKABLE bool isEntityClientScript() const { return _manager->isEntityClientScript(); }
129+
130+ /**jsdoc
131+ * Checks whether the script is running as a server entity script.
132+ * @function Script.isEntityServerScript
133+ * @returns {boolean} <code>true</code> if the script is running as a server entity script, <code>false</code> if it isn't.
134+ */
135+ Q_INVOKABLE bool isEntityServerScript() const { return _manager->isEntityServerScript(); }
136+
137+ /**jsdoc
138+ * Checks whether the script is running as an assignment client script.
139+ * @function Script.isAgentScript
140+ * @returns {boolean} <code>true</code> if the script is running as an assignment client script, <code>false</code> if it
141+ * isn't.
142+ */
143+ Q_INVOKABLE bool isAgentScript() const { return _manager->isAgentScript(); }
144+
145+ /*@jsdoc
146+ * registers a global object by name.
147+ * @function Script.registerValue
148+ * @param {string} valueName
149+ * @param {value} value
150+ */
151+ /// registers a global object by name
152+ Q_INVOKABLE void registerValue(const QString& valueName, ScriptValue value) { _manager->registerValue(valueName, value); }
153+
154+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
155+ // NOTE - these are intended to be public interfaces available to scripts
156+
157+ /**jsdoc
158+ * @function Script.formatExecption
159+ * @param {object} exception - Exception.
160+ * @param {boolean} inludeExtendeDetails - Include extended details.
161+ * @returns {string} String.
162+ * @deprecated This function is deprecated and will be removed.
163+ */
164+ Q_INVOKABLE QString formatException(const ScriptValue& exception, bool includeExtendedDetails) { return _manager->formatException(exception, includeExtendedDetails); }
165+
166+ /**jsdoc
167+ * Adds a function to the list of functions called when a particular event occurs on a particular entity.
168+ * <p>See also, the {@link Entities} API.</p>
169+ * @function Script.addEventHandler
170+ * @param {Uuid} entityID - The ID of the entity.
171+ * @param {Script.EntityEvent} eventName - The name of the event.
172+ * @param {Script~entityEventCallback|Script~pointerEventCallback|Script~collisionEventCallback} handler - The function to
173+ * call when the event occurs on the entity. It can be either the name of a function or an in-line definition.
174+ * @example <caption>Report when a mouse press occurs on a particular entity.</caption>
175+ * var entityID = Entities.addEntity({
176+ * type: "Box",
177+ * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
178+ * dimensions: { x: 0.5, y: 0.5, z: 0.5 },
179+ * lifetime: 300 // Delete after 5 minutes.
180+ * });
181+ *
182+ * function reportMousePress(entityID, event) {
183+ * print("Mouse pressed on entity: " + JSON.stringify(event));
184+ * }
185+ *
186+ * Script.addEventHandler(entityID, "mousePressOnEntity", reportMousePress);
187+ */
188+ Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, const ScriptValue& handler) { _manager->addEventHandler(entityID, eventName, handler); }
189+
190+ /**jsdoc
191+ * Removes a function from the list of functions called when an entity event occurs on a particular entity.
192+ * <p>See also, the {@link Entities} API.</p>
193+ * @function Script.removeEventHandler
194+ * @param {Uuid} entityID - The ID of the entity.
195+ * @param {Script.EntityEvent} eventName - The name of the entity event.
196+ * @param {function} handler - The name of the function to no longer call when the entity event occurs on the entity.
197+ */
198+ Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, const ScriptValue& handler) { _manager->removeEventHandler(entityID, eventName, handler); }
199+
200+ /**jsdoc
201+ * Starts running another script in Interface, if it isn't already running. The script is not automatically loaded next
202+ * time Interface starts.
203+ * <p class="availableIn"><strong>Supported Script Types:</strong> Interface Scripts &bull; Avatar Scripts</p>
204+ * <p>See also, {@link ScriptDiscoveryService.loadScript}.</p>
205+ * @function Script.load
206+ * @param {string} filename - The URL of the script to load. This can be relative to the current script's URL.
207+ * @example <caption>Load a script from another script.</caption>
208+ * // First file: scriptA.js
209+ * print("This is script A");
210+ *
211+ * // Second file: scriptB.js
212+ * print("This is script B");
213+ * Script.load("scriptA.js");
214+ *
215+ * // If you run scriptB.js you should see both scripts in the Running Scripts dialog.
216+ * // And you should see the following output:
217+ * // This is script B
218+ * // This is script A
219+ */
220+ Q_INVOKABLE void load(const QString& loadfile) { _manager->load(loadfile); }
221+
222+ /**jsdoc
223+ * Includes JavaScript from other files in the current script. If a callback is specified, the files are loaded and
224+ * included asynchronously, otherwise they are included synchronously (i.e., script execution blocks while the files are
225+ * included).
226+ * @function Script.include
227+ * @variation 0
228+ * @param {string[]} filenames - The URLs of the scripts to include. Each can be relative to the current script.
229+ * @param {function} [callback=null] - The function to call back when the scripts have been included. It can be either the
230+ * name of a function or an in-line definition.
231+ */
232+ Q_INVOKABLE void include(const QStringList& includeFiles, const ScriptValue& callback = ScriptValue()) { _manager->include(includeFiles, callback);};
233+
234+ /**jsdoc
235+ * Includes JavaScript from another file in the current script. If a callback is specified, the file is loaded and included
236+ * asynchronously, otherwise it is included synchronously (i.e., script execution blocks while the file is included).
237+ * @function Script.include
238+ * @param {string} filename - The URL of the script to include. It can be relative to the current script.
239+ * @param {function} [callback=null] - The function to call back when the script has been included. It can be either the
240+ * name of a function or an in-line definition.
241+ * @example <caption>Include a script file asynchronously.</caption>
242+ * // First file: scriptA.js
243+ * print("This is script A");
244+ *
245+ * // Second file: scriptB.js
246+ * print("This is script B");
247+ * Script.include("scriptA.js", function () {
248+ * print("Script A has been included");
249+ * });
250+ *
251+ * // If you run scriptB.js you should see only scriptB.js in the running scripts list.
252+ * // And you should see the following output:
253+ * // This is script B
254+ * // This is script A
255+ * // Script A has been included
256+ */
257+ Q_INVOKABLE void include(const QString& includeFile, const ScriptValue& callback = ScriptValue()) { _manager->include( includeFile, callback); };
258+
259+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
260+ // MODULE related methods
261+
262+ /**jsdoc
263+ * Provides access to methods or objects provided in an external JavaScript or JSON file.
264+ * See {@link https://docs.overte.org/script/js-tips.html} for further details.
265+ * @function Script.require
266+ * @param {string} module - The module to use. May be a JavaScript file, a JSON file, or the name of a system module such
267+ * as <code>"appUi"</code> (i.e., the "appUi.js" system module JavaScript file).
268+ * @returns {object|array} The value assigned to <code>module.exports</code> in the JavaScript file, or the value defined
269+ * in the JSON file.
270+ */
271+ Q_INVOKABLE ScriptValue require(const QString& moduleId) { return _manager->require(moduleId); }
272+
273+ /**jsdoc
274+ * @function Script.resetModuleCache
275+ * @param {boolean} [deleteScriptCache=false] - Delete script cache.
276+ * @deprecated This function is deprecated and will be removed.
277+ */
278+ Q_INVOKABLE void resetModuleCache(bool deleteScriptCache = false) { _manager->resetModuleCache(deleteScriptCache);}
279+
280+ /**jsdoc
281+ * Calls a function repeatedly, at a set interval.
282+ * @function Script.setInterval
283+ * @param {function} function - The function to call. This can be either the name of a function or an in-line definition.
284+ * @param {number} interval - The interval at which to call the function, in ms.
285+ * @returns {object} A handle to the interval timer. This can be used in {@link Script.clearInterval}.
286+ * @example <caption>Print a message every second.</caption>
287+ * Script.setInterval(function () {
288+ * print("Interval timer fired");
289+ * }, 1000);
290+ */
291+ Q_INVOKABLE QTimer* setInterval(const ScriptValue& function, int intervalMS) { return _manager->setInterval(function, intervalMS); }
292+
293+ /**jsdoc
294+ * Calls a function once, after a delay.
295+ * @function Script.setTimeout
296+ * @param {function} function - The function to call. This can be either the name of a function or an in-line definition.
297+ * @param {number} timeout - The delay after which to call the function, in ms.
298+ * @returns {object} A handle to the timeout timer. This can be used in {@link Script.clearTimeout}.
299+ * @example <caption>Print a message once, after a second.</caption>
300+ * Script.setTimeout(function () {
301+ * print("Timeout timer fired");
302+ * }, 1000);
303+ */
304+ Q_INVOKABLE QTimer* setTimeout(const ScriptValue& function, int timeoutMS) { return _manager->setTimeout(function, timeoutMS); };
305+
306+ /**jsdoc
307+ * Stops an interval timer set by {@link Script.setInterval|setInterval}.
308+ * @function Script.clearInterval
309+ * @param {object} timer - The interval timer to stop.
310+ * @example <caption>Stop an interval timer.</caption>
311+ * // Print a message every second.
312+ * var timer = Script.setInterval(function () {
313+ * print("Interval timer fired");
314+ * }, 1000);
315+ *
316+ * // Stop the timer after 10 seconds.
317+ * Script.setTimeout(function () {
318+ * print("Stop interval timer");
319+ * Script.clearInterval(timer);
320+ * }, 10000);
321+ */
322+ Q_INVOKABLE void clearInterval(QTimer* timer) { _manager->clearInterval(timer); }
323+
324+ // Overloaded version is needed in case the timer has expired
325+ Q_INVOKABLE void clearInterval(QVariantMap timer) { ; }
326+
327+ /**jsdoc
328+ * Stops a timeout timer set by {@link Script.setTimeout|setTimeout}.
329+ * @function Script.clearTimeout
330+ * @param {object} timer - The timeout timer to stop.
331+ * @example <caption>Stop a timeout timer.</caption>
332+ * // Print a message after two seconds.
333+ * var timer = Script.setTimeout(function () {
334+ * print("Timer fired");
335+ * }, 2000);
336+ *
337+ * // Uncomment the following line to stop the timer from firing.
338+ * //Script.clearTimeout(timer);
339+ */
340+ Q_INVOKABLE void clearTimeout(QTimer* timer) { _manager->clearTimeout(timer); }
341+
342+ // Overloaded version is needed in case the timer has expired
343+ Q_INVOKABLE void clearTimeout(QVariantMap timer) { ; }
344+
345+ /**jsdoc
346+ * Prints a message to the program log and emits {@link Script.printedMessage}.
347+ * <p>Alternatively, you can use {@link print} or one of the {@link console} API methods.</p>
348+ * @function Script.print
349+ * @param {string} message - The message to print.
350+ */
351+ Q_INVOKABLE void print(const QString& message) { _manager->print(message); }
352+
353+ /**jsdoc
354+ * Resolves a relative path to an absolute path. The relative path is relative to the script's location.
355+ * @function Script.resolvePath
356+ * @param {string} path - The relative path to resolve.
357+ * @returns {string} The absolute path.
358+ * @example <caption>Report the directory and filename of the running script.</caption>
359+ * print(Script.resolvePath(""));
360+ * @example <caption>Report the directory of the running script.</caption>
361+ * print(Script.resolvePath("."));
362+ * @example <caption>Report the path to a file located relative to the running script.</caption>
363+ * print(Script.resolvePath("../assets/sounds/hello.wav"));
364+ */
365+ Q_INVOKABLE QUrl resolvePath(const QString& path) const { return _manager->resolvePath(path);}
366+
367+ /**jsdoc
368+ * Gets the path to the resources directory for QML files.
369+ * @function Script.resourcesPath
370+ * @returns {string} The path to the resources directory for QML files.
371+ */
372+ Q_INVOKABLE QUrl resourcesPath() const { return _manager->resourcesPath(); }
373+
374+ /**jsdoc
375+ * Starts timing a section of code in order to send usage data about it to Vircadia. Shouldn't be used outside of the
376+ * standard scripts.
377+ * @function Script.beginProfileRange
378+ * @param {string} label - A name that identifies the section of code.
379+ */
380+ Q_INVOKABLE void beginProfileRange(const QString& label) const { _manager->beginProfileRange(label); }
381+
382+ /**jsdoc
383+ * Finishes timing a section of code in order to send usage data about it to Vircadia. Shouldn't be used outside of
384+ * the standard scripts.
385+ * @function Script.endProfileRange
386+ * @param {string} label - A name that identifies the section of code.
387+ */
388+ Q_INVOKABLE void endProfileRange(const QString& label) const { _manager->endProfileRange(label); }
389+
390+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
391+ // Entity Script Related methods
392+
393+ /**jsdoc
394+ * Checks whether an entity has an entity script running.
395+ * @function Script.isEntityScriptRunning
396+ * @param {Uuid} entityID - The ID of the entity.
397+ * @returns {boolean} <code>true</code> if the entity has an entity script running, <code>false</code> if it doesn't.
398+ */
399+ Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID& entityID) { return _manager->isEntityScriptRunning(entityID); }
400+
401+ /**jsdoc
402+ * Manually runs the JavaScript garbage collector which reclaims memory by disposing of objects that are no longer
403+ * reachable.
404+ * @function Script.requestGarbageCollection
405+ */
406+ Q_INVOKABLE void requestGarbageCollection() { _manager->requestGarbageCollection(); }
407+
408+ /**jsdoc
409+ * Prints out current backtrace to the log.
410+ * @function Script.logBacktrace
411+ * @param {string} title - Title added to the printed out backtrace.
412+ */
413+ Q_INVOKABLE void logBacktrace(const QString &title) { _manager->logBacktrace(title); }
414+
415+ /*@jsdoc
416+ * @function Script.loadEntityScript
417+ * @param {Uuid} entityID - Entity ID.
418+ * @param {string} script - Script.
419+ * @param {boolean} forceRedownload - Force re-download.
420+ * @deprecated This function is deprecated and will be removed.
421+ */
422+ Q_INVOKABLE void loadEntityScript(const EntityItemID& entityID, const QString& entityScript, bool forceRedownload) { _manager->loadEntityScript(entityID, entityScript, forceRedownload); }
423+
424+ /**jsdoc
425+ * @function Script.unloadEntityScript
426+ * @param {Uuid} entityID - Entity ID.
427+ * @param {boolean} [shouldRemoveFromMap=false] - Should remove from map.
428+ * @deprecated This function is deprecated and will be removed.
429+ */
430+ Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap = false) { _manager->unloadEntityScript(entityID, shouldRemoveFromMap); }
431+
432+ /**jsdoc
433+ * @function Script.unloadAllEntityScripts
434+ * @param {boolean} [blockingCall=false] - Wait for completion if call moved to another thread.
435+ * @deprecated This function is deprecated and will be removed.
436+ */
437+ Q_INVOKABLE void unloadAllEntityScripts(bool blockingCall = false) { _manager->unloadAllEntityScripts(blockingCall); }
438+
439+ /**jsdoc
440+ * Calls a method in an entity script.
441+ * @function Script.callEntityScriptMethod
442+ * @param {Uuid} entityID - The ID of the entity running the entity script.
443+ * @param {string} methodName - The name of the method to call.
444+ * @param {string[]} [parameters=[]] - The parameters to call the specified method with.
445+ * @param {Uuid} [remoteCallerID=Uuid.NULL] - An ID that identifies the caller.
446+ */
447+ Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
448+ const QStringList& params = QStringList(),
449+ const QUuid& remoteCallerID = QUuid()) { _manager->callEntityScriptMethod(entityID, methodName, params, remoteCallerID); }
450+
451+ /**jsdoc
452+ * Calls a method in an entity script.
453+ * @function Script.callEntityScriptMethod
454+ * @param {Uuid} entityID - Entity ID.
455+ * @param {string} methodName - Method name.
456+ * @param {PointerEvent} event - Pointer event.
457+ * @deprecated This function is deprecated and will be removed.
458+ */
459+ Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const PointerEvent& event) { _manager->callEntityScriptMethod(entityID, methodName, event); }
460+
461+ /**jsdoc
462+ * Calls a method in an entity script.
463+ * @function Script.callEntityScriptMethod
464+ * @param {Uuid} entityID - Entity ID.
465+ * @param {string} methodName - Method name.
466+ * @param {Uuid} otherID - Other entity ID.
467+ * @param {Collision} collision - Collision.
468+ * @deprecated This function is deprecated and will be removed.
469+ */
470+ Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision) { _manager->callEntityScriptMethod(entityID, methodName, otherID, collision);}
471+
472+ /**jsdoc
473+ * @function Script.generateUUID
474+ * @returns {Uuid} A new UUID.
475+ * @deprecated This function is deprecated and will be removed. Use {@link Uuid(0).generate|Uuid.generate} instead.
476+ */
477+ Q_INVOKABLE QUuid generateUUID() { return QUuid::createUuid(); }
478+
479+ /**jsdoc
480+ * Gets the URL for an asset in an external resource bucket. (The location where the bucket is hosted may change over time
481+ * but this method will return the asset's current URL.)
482+ * @function Script.getExternalPath
483+ * @param {Script.ResourceBucket} bucket - The external resource bucket that the asset is in.
484+ * @param {string} path - The path within the external resource bucket where the asset is located.
485+ * <p>Normally, this should start with a path or filename to be appended to the bucket URL.
486+ * Alternatively, it can be a relative path starting with <code>./</code> or <code>../</code>, to navigate within the
487+ * resource bucket's URL.</p>
488+ * @Returns {string} The URL of an external asset.
489+ * @example <caption>Report the URL of a default particle.</caption>
490+ * print(Script.getExternalPath(Script.ExternalPaths.Assets, "Bazaar/Assets/Textures/Defaults/Interface/default_particle.png"));
491+ * @example <caption>Report the root directory where the Vircadia assets are located.</caption>
492+ * print(Script.getExternalPath(Script.ExternalPaths.Assets, "."));
493+ */
494+ Q_INVOKABLE QString getExternalPath(ExternalResource::Bucket bucket, const QString& path) { return _manager->getExternalPath(bucket, path); }
495+
496+signals:
497+
498+ /**jsdoc
499+ * @function Script.scriptLoaded
500+ * @param {string} filename - File name.
501+ * @returns {Signal}
502+ * @deprecated This signal is deprecated and will be removed.
503+ */
504+ void scriptLoaded(const QString& scriptFilename);
505+
506+ /**jsdoc
507+ * @function Script.errorLoadingScript
508+ * @param {string} filename - File name.
509+ * @returns {Signal}
510+ * @deprecated This signal is deprecated and will be removed.
511+ */
512+ void errorLoadingScript(const QString& scriptFilename);
513+
514+ /**jsdoc
515+ * Triggered frequently at a system-determined interval.
516+ * @function Script.update
517+ * @param {number} deltaTime - The time since the last update, in s.
518+ * @returns {Signal}
519+ * @example <caption>Report script update intervals.</caption>
520+ * Script.update.connect(function (deltaTime) {
521+ * print("Update: " + deltaTime);
522+ * });
523+ */
524+ void update(float deltaTime);
525+
526+ /**jsdoc
527+ * Triggered when the script is stopping.
528+ * @function Script.scriptEnding
529+ * @returns {Signal}
530+ * @example <caption>Report when a script is stopping.</caption>
531+ * print("Script started");
532+ *
533+ * Script.scriptEnding.connect(function () {
534+ * print("Script ending");
535+ * });
536+ *
537+ * Script.setTimeout(function () {
538+ * print("Stopping script");
539+ * Script.stop();
540+ * }, 1000);
541+ */
542+ void scriptEnding();
543+
544+ /**jsdoc
545+ * @function Script.finished
546+ * @param {string} filename - File name.
547+ * @param {object} engine - Engine.
548+ * @returns {Signal}
549+ * @deprecated This signal is deprecated and will be removed.
550+ */
551+ void finished(const QString& fileNameString, ScriptManagerPointer);
552+
553+ /**jsdoc
554+ * Triggered when the script prints a message to the program log via {@link print}, {@link Script.print},
555+ * {@link console.log}, {@link console.debug}, {@link console.group}, {@link console.groupEnd}, {@link console.time}, or
556+ * {@link console.timeEnd}.
557+ * @function Script.printedMessage
558+ * @param {string} message - The message.
559+ * @param {string} scriptName - The name of the script that generated the message.
560+ * @returns {Signal}
561+ */
562+ void printedMessage(const QString& message, const QString& scriptName);
563+
564+ /**jsdoc
565+ * Triggered when the script generates an error, {@link console.error} or {@link console.exception} is called, or
566+ * {@link console.assert} is called and fails.
567+ * @function Script.errorMessage
568+ * @param {string} message - The error message.
569+ * @param {string} scriptName - The name of the script that generated the error message.
570+ * @returns {Signal}
571+ */
572+ void errorMessage(const QString& message, const QString& scriptName);
573+
574+ /**jsdoc
575+ * Triggered when the script generates a warning or {@link console.warn} is called.
576+ * @function Script.warningMessage
577+ * @param {string} message - The warning message.
578+ * @param {string} scriptName - The name of the script that generated the warning message.
579+ * @returns {Signal}
580+ */
581+ void warningMessage(const QString& message, const QString& scriptName);
582+
583+ /**jsdoc
584+ * Triggered when the script generates an information message or {@link console.info} is called.
585+ * @function Script.infoMessage
586+ * @param {string} message - The information message.
587+ * @param {string} scriptName - The name of the script that generated the information message.
588+ * @returns {Signal}
589+ */
590+ void infoMessage(const QString& message, const QString& scriptName);
591+
592+ /**jsdoc
593+ * Triggered when the running state of the script changes, e.g., from running to stopping.
594+ * @function Script.runningStateChanged
595+ * @returns {Signal}
596+ */
597+ void runningStateChanged();
598+
599+ /**jsdoc
600+ * @function Script.clearDebugWindow
601+ * @returns {Signal}
602+ * @deprecated This signal is deprecated and will be removed.
603+ */
604+ void clearDebugWindow();
605+
606+ /**jsdoc
607+ * @function Script.loadScript
608+ * @param {string} scriptName - Script name.
609+ * @param {boolean} isUserLoaded - Is user loaded.
610+ * @returns {Signal}
611+ * @deprecated This signal is deprecated and will be removed.
612+ */
613+ void loadScript(const QString& scriptName, bool isUserLoaded);
614+
615+ /**jsdoc
616+ * @function Script.reloadScript
617+ * @param {string} scriptName - Script name.
618+ * @param {boolean} isUserLoaded - Is user loaded.
619+ * @returns {Signal}
620+ * @deprecated This signal is deprecated and will be removed.
621+ */
622+ void reloadScript(const QString& scriptName, bool isUserLoaded);
623+
624+ /**jsdoc
625+ * Triggered when the script has stopped.
626+ * @function Script.doneRunning
627+ * @returns {Signal}
628+ */
629+ void doneRunning();
630+
631+ /**jsdoc
632+ * @function Script.entityScriptDetailsUpdated
633+ * @returns {Signal}
634+ * @deprecated This signal is deprecated and will be removed.
635+ */
636+ // Emitted when an entity script is added or removed, or when the status of an entity
637+ // script is updated (goes from RUNNING to ERROR_RUNNING_SCRIPT, for example)
638+ void entityScriptDetailsUpdated();
639+
640+ /**jsdoc
641+ * Triggered when the script starts for the user. See also, {@link Entities.preload}.
642+ * <p class="availableIn"><strong>Supported Script Types:</strong> Client Entity Scripts &bull; Server Entity Scripts</p>
643+ * @function Script.entityScriptPreloadFinished
644+ * @param {Uuid} entityID - The ID of the entity that the script is running in.
645+ * @returns {Signal}
646+ * @example <caption>Get the ID of the entity that a client entity script is running in.</caption>
647+ * var entityScript = function () {
648+ * this.entityID = Uuid.NULL;
649+ * };
650+ *
651+ * Script.entityScriptPreloadFinished.connect(function (entityID) {
652+ * this.entityID = entityID;
653+ * print("Entity ID: " + this.entityID);
654+ * });
655+ *
656+ * var entityID = Entities.addEntity({
657+ * type: "Box",
658+ * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
659+ * dimensions: { x: 0.5, y: 0.5, z: 0.5 },
660+ * color: { red: 255, green: 0, blue: 0 },
661+ * script: "(" + entityScript + ")", // Could host the script on a Web server instead.
662+ * lifetime: 300 // Delete after 5 minutes.
663+ * });
664+ */
665+ // Emitted when an entity script has finished running preload
666+ void entityScriptPreloadFinished(const EntityItemID& entityID);
667+
668+ /**jsdoc
669+ * Triggered when a script generates an unhandled exception.
670+ * @function Script.unhandledException
671+ * @param {object} exception - The details of the exception.
672+ * @returns {Signal}
673+ * @example <caption>Report the details of an unhandled exception.</caption>
674+ * Script.unhandledException.connect(function (exception) {
675+ * print("Unhandled exception: " + JSON.stringify(exception));
676+ * });
677+ * var properties = JSON.parse("{ x: 1"); // Invalid JSON string.
678+ */
679+ void unhandledException(const ScriptValue& exception);
680+
681+
682+protected:
683+ /**jsdoc
684+ * @function Script.executeOnScriptThread
685+ * @param {function} function - Function.
686+ * @param {ConnectionType} [type=2] - Connection type.
687+ * @deprecated This function is deprecated and will be removed.
688+ */
689+ Q_INVOKABLE void executeOnScriptThread(std::function<void()> function, const Qt::ConnectionType& type = Qt::QueuedConnection ) { _manager->executeOnScriptThread(function, type);}
690+
691+ /**jsdoc
692+ * @function Script._requireResolve
693+ * @param {string} module - Module.
694+ * @param {string} [relativeTo=""] - Relative to.
695+ * @returns {string} Result.
696+ * @deprecated This function is deprecated and will be removed.
697+ */
698+ // note: this is not meant to be called directly, but just to have QMetaObject take care of wiring it up in general;
699+ // then inside of init() we just have to do "Script.require.resolve = Script._requireResolve;"
700+ Q_INVOKABLE QString _requireResolve(const QString& moduleId, const QString& relativeTo = QString()) { return _manager->_requireResolve(moduleId, relativeTo); }
701+
702+ /**jsdoc
703+ * @function Script.entityScriptContentAvailable
704+ * @param {Uuid} entityID - Entity ID.
705+ * @param {string} scriptOrURL - Path.
706+ * @param {string} contents - Contents.
707+ * @param {boolean} isURL - Is a URL.
708+ * @param {boolean} success - Success.
709+ * @param {string} status - Status.
710+ * @deprecated This function is deprecated and will be removed.
711+ */
712+ Q_INVOKABLE void entityScriptContentAvailable(const EntityItemID& entityID, const QString& scriptOrURL, const QString& contents, bool isURL, bool success, const QString& status);
713+
714+
715+private:
716+ ScriptManager *_manager;
717+};