Overte C++ Documentation
ScriptManager.h
1 //
2 // ScriptManager.h
3 // libraries/script-engine/src
4 //
5 // Created by Brad Hefta-Gaub on 12/14/13.
6 // Copyright 2013 High Fidelity, Inc.
7 // Copyright 2020 Vircadia contributors.
8 // Copyright 2022-2023 Overte e.V.
9 //
10 // Distributed under the Apache License, Version 2.0.
11 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
12 // SPDX-License-Identifier: Apache-2.0
13 //
14 
15 #ifndef hifi_ScriptManager_h
16 #define hifi_ScriptManager_h
17 
18 #include <atomic>
19 #include <chrono>
20 #include <functional>
21 #include <memory>
22 #include <unordered_map>
23 #include <mutex>
24 
25 #include <QtCore/QFuture>
26 #include <QtCore/QHash>
27 #include <QtCore/QObject>
28 #include <QtCore/QReadWriteLock>
29 #include <QtCore/QSet>
30 #include <QtCore/QSharedPointer>
31 #include <QtCore/QString>
32 #include <QtCore/QTimer>
33 #include <QtCore/QUrl>
34 #include <QtCore/QVariant>
35 
36 #include "EntityItemID.h"
37 #include "EntitiesScriptEngineProvider.h"
38 #include "EntityScriptUtils.h"
39 #include <ExternalResource.h>
40 #include <SettingHandle.h>
41 
42 #include "AssetScriptingInterface.h"
43 #include "ConsoleScriptingInterface.h"
44 #include "Mat4.h"
45 #include "PointerEvent.h"
46 #include "Quat.h"
47 #include "ScriptUUID.h"
48 #include "ScriptValue.h"
49 #include "ScriptException.h"
50 #include "Vec3.h"
51 #include "ScriptEngine.h"
52 
53 static const QString NO_SCRIPT("");
54 
55 static const int SCRIPT_FPS = 60;
56 static const int DEFAULT_MAX_ENTITY_PPS = 9000;
57 static const int DEFAULT_ENTITY_PPS_PER_SCRIPT = 900;
58 
59 class ScriptEngine;
60 class ScriptEngines;
61 class ScriptManager;
62 class ScriptManagerScriptingInterface;
63 
64 using ScriptEnginePointer = std::shared_ptr<ScriptEngine>;
65 using ScriptManagerPointer = std::shared_ptr<ScriptManager>;
66 using ScriptManagerScriptingInterfacePointer = std::shared_ptr<ScriptManagerScriptingInterface>;
67 using ScriptValueList = QList<ScriptValue>;
68 
69 Q_DECLARE_METATYPE(ScriptManagerPointer)
70 
71 const int QTREGISTER_QTimerStar = qRegisterMetaType<QTimer*>();
72 
73 
78 class CallbackData {
79 public:
84  ScriptValue function;
85 
91 
97 };
98 
99 
106 public:
107  EntityItemID entityID;
108  QString entityScript;
109  //bool forceRedownload;
110 };
111 
122 
127  QString scriptOrURL;
128 
133  QString contents;
134 
139  bool isURL;
140 
145  bool success;
146 
151  QString status;
152 };
153 
154 typedef std::unordered_map<EntityItemID, EntityScriptContentAvailable> EntityScriptContentAvailableMap;
155 
156 typedef QList<CallbackData> CallbackList;
157 typedef QHash<QString, CallbackList> RegisteredEventHandlers;
158 
159 
165 public:
166 
171  EntityScriptStatus status { EntityScriptStatus::PENDING };
172 
179  QString errorInfo { "" };
180 
181 
186  QString scriptText { "" };
187 
193 
199  int64_t lastModified { 0 };
200 
207  QUrl definingSandboxURL { QUrl("about:EntityScript") };
208 };
209 
210 // declare a static script initializers
211 #define STATIC_SCRIPT_TYPES_INITIALIZER(init) \
212  static ScriptManager::StaticTypesInitializerNode static_script_types_initializer_(init);
213 
214 #define STATIC_SCRIPT_INITIALIZER(init) \
215  static ScriptManager::StaticInitializerNode static_script_initializer_(init);
216 
217 
218 
219 
282 class ScriptManager : public QObject, public EntitiesScriptEngineProvider, public std::enable_shared_from_this<ScriptManager> {
283  Q_OBJECT
284 public:
285  static const QString SCRIPT_EXCEPTION_FORMAT;
286  static const QString SCRIPT_BACKTRACE_SEP;
287 
292  enum Context {
299 
305 
311 
317 
330  };
331 
336  enum Type {
342 
348 
355 
361 
367 
378  };
379  Q_ENUM(Type);
380 
381  static int processLevelMaxRetries;
382 private:
383  // Constructor is private so that only properly generated shared pointer can be used
384  explicit ScriptManager(Context context, const QString& scriptContents = NO_SCRIPT, const QString& fileNameString = QString("about:ScriptEngine"));
385 public:
386  ~ScriptManager() override;
387 
388  // static initialization support
389  typedef void (*ScriptManagerInitializer)(ScriptManager*);
390  class StaticInitializerNode {
391  public:
392  ScriptManagerInitializer init;
393  StaticInitializerNode* prev;
394  inline explicit StaticInitializerNode(ScriptManagerInitializer&& pInit) : init(std::move(pInit)),prev(nullptr) { registerNewStaticInitializer(this); }
395  };
396  static void registerNewStaticInitializer(StaticInitializerNode* dest);
397 
398  class StaticTypesInitializerNode {
399  public:
400  ScriptManagerInitializer init;
401  StaticTypesInitializerNode* prev;
402  inline explicit StaticTypesInitializerNode(ScriptManagerInitializer&& pInit) : init(std::move(pInit)),prev(nullptr) { registerNewStaticTypesInitializer(this); }
403  };
404  static void registerNewStaticTypesInitializer(StaticTypesInitializerNode* dest);
405 
417  void runInThread();
418 
424  void run();
425 
426 
432  QString getFilename() const;
433 
439  QString getAbsoluteFilename() const;
440 
446  inline ScriptEnginePointer engine() { return _engine; }
447 
448  QList<EntityItemID> getListOfEntityScriptIDs();
449 
460  bool isStopped() const;
461 
462 
470 
477  Q_INVOKABLE void stop(bool marshal = false);
478 
480 
490  void waitTillDoneRunning(bool shutdown = false);
491 
500 
515  void loadURL(const QUrl& scriptURL, bool reload);
516 
525  bool hasValidScriptSuffix(const QString& scriptFileName);
526 
527 
535 
542  Q_INVOKABLE QString getContext() const;
543 
549  Q_INVOKABLE bool isClientScript() const { return _context == CLIENT_SCRIPT; }
550 
556  Q_INVOKABLE bool isDebugMode() const;
557 
563  Q_INVOKABLE bool isEntityClientScript() const { return _context == ENTITY_CLIENT_SCRIPT; }
564 
565 
571  Q_INVOKABLE bool isEntityServerScript() const { return _context == ENTITY_SERVER_SCRIPT; }
572 
578  Q_INVOKABLE bool isAgentScript() const { return _context == AGENT_SCRIPT; }
579 
586  Q_INVOKABLE void registerValue(const QString& valueName, ScriptValue value);
587 
589  // NOTE - these are intended to be public interfaces available to scripts
590 
598  Q_INVOKABLE QString formatException(const ScriptValue& exception, bool includeExtendedDetails);
599 
600 
601 
611  Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, const ScriptValue& handler);
612 
620  Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, const ScriptValue& handler);
621 
622 
633  Q_INVOKABLE void load(const QString& loadfile);
634 
646  Q_INVOKABLE void include(const QStringList& includeFiles, const ScriptValue& callback = ScriptValue());
647 
659  Q_INVOKABLE void include(const QString& includeFile, const ScriptValue& callback = ScriptValue());
660 
662 
663 
664 
666 
667 
673 
682  Q_INVOKABLE ScriptValue require(const QString& moduleId);
683 
690  Q_INVOKABLE void resetModuleCache(bool deleteScriptCache = false);
691 
699 
710  bool registerModuleWithParent(const ScriptValue& module, const ScriptValue& parent);
711 
721  ScriptValue newModule(const QString& modulePath, const ScriptValue& parent = ScriptValue());
722 
737  QVariantMap fetchModuleSource(const QString& modulePath, const bool forceDownload = false);
738 
746  ScriptValue instantiateModule(const ScriptValue& module, const QString& sourceCode);
747 
757  ScriptValue evaluate(const QString& program, const QString& fileName = QString());
758 
768  Q_INVOKABLE int setInterval(const ScriptValue& function, int intervalMS);
769 
770 
780  Q_INVOKABLE int setTimeout(const ScriptValue& function, int timeoutMS);
781 
787  Q_INVOKABLE void clearInterval(int timer) { stopTimer(timer); }
788 
794  Q_INVOKABLE void clearTimeout(int timer) { stopTimer(timer); }
795 
796 
802  Q_INVOKABLE void print(const QString& message);
803 
810  Q_INVOKABLE QUrl resolvePath(const QString& path) const;
811 
817  Q_INVOKABLE QUrl resourcesPath() const;
818 
824  Q_INVOKABLE void beginProfileRange(const QString& label) const;
825 
831  Q_INVOKABLE void endProfileRange(const QString& label) const;
832 
833 
835 
837  // Entity Script Related methods
838 
839 
846 
853  Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID& entityID, const QString& scriptURL) {
854  QReadLocker locker { &_entityScriptsLock };
855  auto it = _entityScripts.constFind(entityID);
856  if (it != _entityScripts.constEnd()) {
857  auto it2 = it.value().constFind(scriptURL);
858  return it2 != it.value().constEnd() && it2.value().status == EntityScriptStatus::RUNNING;
859  }
860  return false;
861  }
862 
870  QVariant cloneEntityScriptDetails(const EntityItemID& entityID, const QString& scriptURL);
871 
872 
882  QFuture<QVariant> getLocalEntityScriptDetails(const EntityItemID& entityID, const QString& scriptURL) override;
883 
884 
889  Q_INVOKABLE void requestGarbageCollection();
890 
896  Q_INVOKABLE void logBacktrace(const QString &title);
897 
905  Q_INVOKABLE void loadEntityScript(const EntityItemID& entityID, const QString& entityScript, bool forceRedownload);
906 
914  Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, const QString& scriptURL, bool shouldRemoveFromMap = false); // will call unload method
915 
922  Q_INVOKABLE void unloadAllEntityScriptsForEntity(const EntityItemID& entityID, bool shouldRemoveFromMap = false); // will call unload method
923 
924 
930  Q_INVOKABLE void unloadAllEntityScripts(bool blockingCall = false);
931 
940  Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
941  const QStringList& params = QStringList(),
942  const QUuid& remoteCallerID = QUuid()) override;
943 
953  Q_INVOKABLE void callEntityScriptMethodForScript(const EntityItemID& entityID,
954  const QString& scriptURL,
955  const QString& methodName,
956  const QStringList& params = QStringList(),
957  const QUuid& remoteCallerID = QUuid()) override;
958 
967  Q_INVOKABLE void callEntityScriptMethodForScript(const EntityItemID& entityID,
968  const QString& scriptURL,
969  const QString& methodName,
970  const QString& param);
971 
979  Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const PointerEvent& event);
980 
981 
990  Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision);
991 
992 
998  void setType(Type type) { _type = type; };
999 
1005  Type getType() { return _type; };
1006 
1012  QString getTypeAsString() const;
1013 
1021  bool isFinished() const { return _isFinished; } // used by Application and ScriptWidget
1022 
1029  bool isRunning() const { return _isRunning; } // used by ScriptWidget
1030 
1031  // this is used by code in ScriptEngines.cpp during the "reload all" operation
1038  bool isStopping() const { return _isStopping; }
1039 
1047 
1048 
1050 
1051 
1053 
1062  void setUserLoaded(bool isUserLoaded) { _isUserLoaded = isUserLoaded; }
1063 
1073  bool isUserLoaded() const { return _isUserLoaded; }
1074 
1082  void setQuitWhenFinished(const bool quitWhenFinished) { _quitWhenFinished = quitWhenFinished; }
1083 
1092  bool isQuitWhenFinished() const { return _quitWhenFinished; }
1093 
1102  void setEmitScriptUpdatesFunction(std::function<bool()> func) { _emitScriptUpdates = func; }
1103 
1113  void scriptErrorMessage(const QString& message, const QString& fileName, int lineNumber);
1114 
1124  void scriptWarningMessage(const QString& message, const QString& fileName, int lineNumber);
1125 
1135  void scriptInfoMessage(const QString& message, const QString& fileName, int lineNumber);
1136 
1148  void scriptPrintedMessage(const QString& message, const QString& fileName, int lineNumber);
1149 
1156  void clearDebugLogWindow();
1157 
1163  int getNumRunningEntityScripts() const;
1164 
1174  bool getEntityScriptDetails(const EntityItemID& entityID, const QString& scriptURL, EntityScriptDetails &details) const;
1175 
1184  bool hasEntityScriptDetails(const EntityItemID& entityID, const QString& scriptURL) const;
1185 
1196  void setScriptEngines(QSharedPointer<ScriptEngines>& scriptEngines) { _scriptEngines = scriptEngines; }
1197 
1198 
1208  void forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, const ScriptValueList& eventHanderArgs);
1209 
1215  void removeAllEventHandlers(const EntityItemID& entityID);
1216 
1217 
1225  ScriptValue getReturnValue() const { return _returnValue; }
1226 
1227 
1235  Q_INVOKABLE QString getExternalPath(ExternalResource::Bucket bucket, const QString& path);
1236 
1237 
1243  std::shared_ptr<ScriptException> getUncaughtException() const;
1244 
1252  bool getAbortOnUncaughtException() const { return _abortOnUncaughtException; }
1253 
1260  void setAbortOnUncaughtException(bool value) { _abortOnUncaughtException = value; }
1261 
1268  bool isDoneRunning() { return _isDoneRunning; };
1269 
1279 
1280 public slots:
1281 
1290  void updateMemoryCost(const qint64 &deltaSize);
1291 
1292 signals:
1293 
1294 
1300 
1306  void scriptLoaded(const QString& scriptFilename);
1307 
1308 
1314  void errorLoadingScript(const QString& scriptFilename);
1315 
1316 
1322  void update(float deltaTime);
1323 
1324 
1325 
1331 
1332 
1333 
1339  void finished(const QString& fileNameString, ScriptManagerPointer);
1340 
1347  void printedMessage(const QString& message, const QString& scriptName);
1348 
1349 
1356  void errorMessage(const QString& message, const QString& scriptName);
1357 
1358 
1359 
1366  void warningMessage(const QString& message, const QString& scriptName);
1367 
1368 
1375  void infoMessage(const QString& message, const QString& scriptName);
1376 
1386  void printedEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
1387 
1388 
1398  void errorEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
1399 
1400 
1401 
1411  void warningEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
1412 
1413 
1423  void infoEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
1424 
1425 
1431 
1432 
1438 
1439 
1446  void loadScript(const QString& scriptName, bool isUserLoaded);
1447 
1448 
1455  void reloadScript(const QString& scriptName, bool isUserLoaded);
1456 
1461  void doneRunning();
1462 
1469 
1476 
1477 
1483  void unhandledException(std::shared_ptr<ScriptException> exception);
1484 
1486 
1494 
1503 
1504 protected:
1505  // Is called by the constructor, bceause all types need to be registered before method discovery with ScriptObjectV8Proxy::investigate()
1506  void initMetaTypes();
1507 
1513  void init();
1514 
1522  Q_INVOKABLE void executeOnScriptThread(std::function<void()> function, const Qt::ConnectionType& type = Qt::QueuedConnection );
1523 
1535  Q_INVOKABLE QString _requireResolve(const QString& moduleId, const QString& relativeTo = QString());
1536 
1546  QString logException(const ScriptValue& exception);
1547  void timerFired(int timer);
1548  void stopAllTimers();
1549  void stopAllTimersForEntityScript(const EntityItemID& entityID);
1550  void refreshFileScript(const EntityItemID& entityID, const QString& scriptURL);
1551 
1562  void updateEntityScriptStatus(const EntityItemID& entityID, const QString& scriptURL, const EntityScriptStatus& status, const QString& errorInfo = QString());
1563 
1564 
1572  void setEntityScriptDetails(const EntityItemID& entityID, const QString& scriptURL, const EntityScriptDetails& details);
1573 
1581  void setParentURL(const QString& parentURL) { _parentURL = parentURL; }
1582 
1591  int setupTimerWithInterval(const ScriptValue& function, int intervalMS, bool isSingleShot);
1592 
1598  void stopTimer(int timer);
1599 
1600  QHash<EntityItemID, RegisteredEventHandlers> _registeredHandlers;
1601 
1602 
1613  Q_INVOKABLE void entityScriptContentAvailable(const EntityItemID& entityID, const QString& scriptOrURL, const QString& contents, bool isURL, bool success, const QString& status);
1614 
1615  EntityItemID currentEntityIdentifier; // Contains the defining entity script entity id during execution, if any. Empty for interface script execution.
1616  QUrl currentSandboxURL; // The toplevel url string for the entity script that loaded the code being executed, else empty.
1617 
1628  void doWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, std::function<void()> operation);
1629 
1650  void callWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, const ScriptValue& function, const ScriptValue& thisObject, const ScriptValueList& args);
1651 
1652  Context _context;
1653  Type _type;
1654  ScriptEnginePointer _engine;
1655  QString _scriptContents;
1656  QString _parentURL;
1657  std::atomic<bool> _isFinished { false };
1658  std::atomic<bool> _isRunning { false };
1659  std::atomic<bool> _isStopping { false };
1660  std::atomic<bool> _isDoneRunning { false };
1661  bool _areMetaTypesInitialized { false };
1662  bool _isInitialized { false };
1663  std::map<int, std::pair<std::unique_ptr<QTimer>, CallbackData>> _timerFunctionMap;
1664  int _timerHandleCounter { 1 };
1665  QSet<QUrl> _includedURLs;
1666  mutable QReadWriteLock _entityScriptsLock { QReadWriteLock::Recursive };
1667  QHash<EntityItemID, QHash<QString, EntityScriptDetails>> _entityScripts;
1668  EntityScriptContentAvailableMap _contentAvailableQueue;
1669  ScriptValue _returnValue;
1670 
1671  bool _isThreaded { false };
1672  qint64 _lastUpdate;
1673 
1674  QString _fileNameString;
1675  std::shared_ptr<Quat> _quatLibrary;
1676  std::shared_ptr<Vec3> _vec3Library;
1677  std::shared_ptr<Mat4> _mat4Library;
1678  std::shared_ptr<ScriptUUID> _uuidLibrary;
1679  std::shared_ptr<ConsoleScriptingInterface> _consoleScriptingInterface;
1680  std::atomic<bool> _isUserLoaded { false };
1681  bool _isReloading { false };
1682  bool _refreshRecurseGuard { false };
1683 
1684  std::atomic<bool> _quitWhenFinished;
1685 
1686  std::shared_ptr<AssetScriptingInterface> _assetScriptingInterface;
1687 
1688  std::function<bool()> _emitScriptUpdates{ []() { return true; } };
1689 
1690  std::recursive_mutex _lock;
1691 
1692  std::chrono::microseconds _totalTimerExecution { 0 };
1693 
1694  static const QString _SETTINGS_ENABLE_EXTENDED_EXCEPTIONS;
1695 
1696  Setting::Handle<bool> _enableExtendedJSExceptions { _SETTINGS_ENABLE_EXTENDED_EXCEPTIONS, true };
1697 
1698  QWeakPointer<ScriptEngines> _scriptEngines;
1699 
1700 
1701 
1702  // For debugging performance issues
1703  int _timerCallCounter{ 0 };
1704  double _totalTimeInTimerEvents_s{ 0.0 };
1705 
1706  ScriptManagerScriptingInterfacePointer _scriptingInterface;
1707 
1708  bool _abortOnUncaughtException{ false };
1709 
1710  friend ScriptManagerPointer newScriptManager(Context context, const QString& scriptContents, const QString& fileNameString);
1711  friend class ScriptManagerScriptingInterface;
1712 
1713  std::atomic<bool> _isDeleted {false}; // This is used for debugging use-after-delete. It happens quite often, so I'm keeping it here for now.
1714 };
1715 
1724 ScriptManagerPointer newScriptManager(ScriptManager::Context context,
1725  const QString& scriptContents,
1726  const QString& fileNameString);
1727 
1739 ScriptManagerPointer scriptManagerFactory(ScriptManager::Context context,
1740  const QString& scriptContents,
1741  const QString& fileNameString);
1742 
1743 #endif // hifi_ScriptManager_h
Callback data for addEventHandler.
Definition: ScriptManager.h:78
QUrl definingSandboxURL
Sandbox URL for the script.
Definition: ScriptManager.h:96
EntityItemID definingEntityIdentifier
Entity ID.
Definition: ScriptManager.h:90
DeferredLoadEntity.
Definition: ScriptManager.h:105
Abstract ID for editing model items. Used in EntityItem JS API.
Definition: EntityItemID.h:28
Details about an entity script.
Definition: ScriptManager.h:164
QUrl definingSandboxURL
URL under which the script is allowed to have access.
Definition: ScriptManager.h:207
int64_t lastModified
Last modified time of the underlying script file.
Definition: ScriptManager.h:199
ScriptValue scriptObject
The return value of the script.
Definition: ScriptManager.h:192
QString errorInfo
Error information.
Definition: ScriptManager.h:179
QString scriptText
The source code of the script.
Definition: ScriptManager.h:186
EntityScriptStatus status
Current status.
Definition: ScriptManager.h:171
Represents a 2D or 3D pointer to the scripting engine. Exposed as PointerEvent
Definition: PointerEvent.h:32
Class used as a base for script engine-specific thread safety guards.
Definition: ScriptEngine.h:197
Provides an engine-independent interface for a scripting engine.
Definition: ScriptEngine.h:93
Provides the ScriptDiscoveryService scripting interface.
Definition: ScriptEngines.h:59
Manages a single scripting engine.
Definition: ScriptManager.h:282
Type
Type of the script.
Definition: ScriptManager.h:336
@ NETWORKLESS_TEST
Test system script.
Definition: ScriptManager.h:377
@ AVATAR
Avatar script.
Definition: ScriptManager.h:366
@ AGENT
Agent script.
Definition: ScriptManager.h:360
@ ENTITY_SERVER
Entity server Receives the update event.
Definition: ScriptManager.h:354
@ CLIENT
Client.
Definition: ScriptManager.h:341
@ ENTITY_CLIENT
Entity client Receives the update event.
Definition: ScriptManager.h:347
Q_INVOKABLE void clearTimeout(int timer)
Stops a timeout timer.
Definition: ScriptManager.h:794
Q_INVOKABLE void executeOnScriptThread(std::function< void()> function, const Qt::ConnectionType &type=Qt::QueuedConnection)
executeOnScriptThread
Definition: ScriptManager.cpp:458
void doWithEnvironment(const EntityItemID &entityID, const QUrl &sandboxURL, std::function< void()> operation)
Execute operation in the appropriate context for (the possibly empty) entityID. Even if entityID is s...
Definition: ScriptManager.cpp:2678
void setUserLoaded(bool isUserLoaded)
Set whether this script was user-loaded.
Definition: ScriptManager.h:1062
void disconnectNonEssentialSignals()
Disconnect all signals, except essential ones.
Definition: ScriptManager.cpp:417
void setScriptEngines(QSharedPointer< ScriptEngines > &scriptEngines)
Set a shared pointer to the ScriptEngines class.
Definition: ScriptManager.h:1196
Q_INVOKABLE void registerValue(const QString &valueName, ScriptValue value)
Registers a global object by name.
Definition: ScriptManager.cpp:884
Q_INVOKABLE void loadEntityScript(const EntityItemID &entityID, const QString &entityScript, bool forceRedownload)
Load an entity script.
Definition: ScriptManager.cpp:2062
Q_INVOKABLE void removeEventHandler(const EntityItemID &entityID, const QString &eventName, const ScriptValue &handler)
Removes a function from the list of functions called when an entity event occurs on a particular enti...
Definition: ScriptManager.cpp:889
Q_INVOKABLE void requestGarbageCollection()
Manually runs the JavaScript garbage collector which reclaims memory by disposing of objects that are...
Definition: ScriptManager.cpp:3024
Q_INVOKABLE void print(const QString &message)
Prints a message to the program log.
Definition: ScriptManager.cpp:1381
bool getEntityScriptDetails(const EntityItemID &entityID, const QString &scriptURL, EntityScriptDetails &details) const
Retrieves the details about an entity script.
Definition: ScriptManager.cpp:2039
void scriptLoaded(const QString &scriptFilename)
Script.scriptLoaded.
Q_INVOKABLE void endProfileRange(const QString &label) const
Finishes timing a section of code in order to send usage data about it to Overte. Shouldn't be used o...
Definition: ScriptManager.cpp:1390
Q_INVOKABLE QUrl resourcesPath() const
Gets the path to the resources directory for QML files.
Definition: ScriptManager.cpp:1377
Q_INVOKABLE void stop(bool marshal=false)
Stops and unloads the current script.
Definition: ScriptManager.cpp:1185
Q_INVOKABLE void callEntityScriptMethodForScript(const EntityItemID &entityID, const QString &scriptURL, const QString &methodName, const QStringList &params=QStringList(), const QUuid &remoteCallerID=QUuid()) override
Call a method on an entity script.
Definition: ScriptManager.cpp:2778
void attachDefaultEventHandlers()
Triggered once before the first call to Script.addEventHandler happens on this ScriptManager connecti...
QFuture< QVariant > getLocalEntityScriptDetails(const EntityItemID &entityID, const QString &scriptURL) override
Get the details of a local entity script.
Definition: ScriptManager.cpp:2035
bool isDoneRunning()
Returns true after script finished running and doneRunning signal was called.
Definition: ScriptManager.h:1268
void scriptPrintedMessage(const QString &message, const QString &fileName, int lineNumber)
Logs a script printed message and emits an printedMessage event.
Definition: ScriptManager.cpp:665
void entityScriptPreloadFinished(const EntityItemID &entityID)
Emitted when an entity script has finished running preload.
void clearDebugLogWindow()
Clears the debug log window.
Definition: ScriptManager.cpp:679
std::shared_ptr< ScriptException > getUncaughtException() const
Get the uncaught exception from the underlying script engine.
Definition: ScriptManager.cpp:238
void updateMemoryCost(const qint64 &deltaSize)
Script.updateMemoryCost.
Definition: ScriptManager.cpp:1202
void clearDebugWindow()
Script.clearDebugWindow.
void forwardHandlerCall(const EntityItemID &entityID, const QString &eventName, const ScriptValueList &eventHanderArgs)
Call all the registered event handlers on an entity for the specified name.
Definition: ScriptManager.cpp:1937
Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID &entityID, const QString &scriptURL)
Checks whether an entity has an entity script running.
Definition: ScriptManager.h:853
Q_INVOKABLE void load(const QString &loadfile)
Starts running another script in Interface, if it isn't already running. The script is not automatica...
Definition: ScriptManager.cpp:1904
void updateEntityScriptStatus(const EntityItemID &entityID, const QString &scriptURL, const EntityScriptStatus &status, const QString &errorInfo=QString())
Updates the status of an entity script.
Definition: ScriptManager.cpp:1983
Type getType()
Returns the script type.
Definition: ScriptManager.h:1005
void scriptErrorMessage(const QString &message, const QString &fileName, int lineNumber)
Logs a script error message and emits an errorMessage event.
Definition: ScriptManager.cpp:629
bool hasValidScriptSuffix(const QString &scriptFileName)
Determines whether a script filename has the right suffix.
Definition: ScriptManager.cpp:586
void entityScriptDetailsUpdated()
Emitted when an entity script is added or removed, or when the status of an entity script is updated ...
void setAbortOnUncaughtException(bool value)
Whether to abort on an uncaught exception.
Definition: ScriptManager.h:1260
void errorEntityMessage(const QString &message, const QString &fileName, int lineNumber, const EntityItemID &entityID, bool isServerScript)
Triggered when a client side entity script generates an error.
void loadScript(const QString &scriptName, bool isUserLoaded)
Script.loadScript.
Q_INVOKABLE void unloadEntityScript(const EntityItemID &entityID, const QString &scriptURL, bool shouldRemoveFromMap=false)
Unload an entity script.
Definition: ScriptManager.cpp:2484
bool isStopping() const
Whether this ScriptManager is stopping. Once this is true, it stays true.
Definition: ScriptManager.h:1038
QString logException(const ScriptValue &exception)
Log an exception.
Definition: ScriptManager.cpp:227
Q_INVOKABLE bool isAgentScript() const
Checks whether the script is running as an assignment client script.
Definition: ScriptManager.h:578
Q_INVOKABLE void addEventHandler(const EntityItemID &entityID, const QString &eventName, const ScriptValue &handler)
Adds a function to the list of functions called when a particular event occurs on a particular entity...
Definition: ScriptManager.cpp:935
void printedEntityMessage(const QString &message, const QString &fileName, int lineNumber, const EntityItemID &entityID, bool isServerScript)
Triggered when a client side entity script prints a message to the program log.
Q_INVOKABLE void entityScriptContentAvailable(const EntityItemID &entityID, const QString &scriptOrURL, const QString &contents, bool isURL, bool success, const QString &status)
Script.entityScriptContentAvailable.
Definition: ScriptManager.cpp:2135
Q_INVOKABLE ScriptValue require(const QString &moduleId)
Provides access to methods or objects provided in an external JavaScript or JSON file.
Definition: ScriptManager.cpp:1641
ScriptValue instantiateModule(const ScriptValue &module, const QString &sourceCode)
Evaluate a pending module object using the fetched source code.
Definition: ScriptManager.cpp:1616
ScriptEnginePointer engine()
Underlying scripting engine.
Definition: ScriptManager.h:446
void errorMessage(const QString &message, const QString &scriptName)
Triggered when the script generates an error.
void printedMessage(const QString &message, const QString &scriptName)
Triggered when the script prints a message to the program log.
Q_INVOKABLE void clearInterval(int timer)
Stops an interval timer.
Definition: ScriptManager.h:787
void callWithEnvironment(const EntityItemID &entityID, const QUrl &sandboxURL, const ScriptValue &function, const ScriptValue &thisObject, const ScriptValueList &args)
Execute operation in the appropriate context for (the possibly empty) entityID.
Definition: ScriptManager.cpp:2696
Q_INVOKABLE QUrl resolvePath(const QString &path) const
Resolves a relative path to an absolute path. The relative path is relative to the script's location.
Definition: ScriptManager.cpp:1333
bool getAbortOnUncaughtException() const
Whether this engine will abort on an uncaught exception.
Definition: ScriptManager.h:1252
void infoEntityMessage(const QString &message, const QString &fileName, int lineNumber, const EntityItemID &entityID, bool isServerScript)
Triggered when a client side entity script generates an information message.
int setupTimerWithInterval(const ScriptValue &function, int intervalMS, bool isSingleShot)
Creates a timer with the specified interval.
Definition: ScriptManager.cpp:1259
Q_INVOKABLE void include(const QStringList &includeFiles, const ScriptValue &callback=ScriptValue())
Includes JavaScript from other files in the current script.
Definition: ScriptManager.cpp:1747
void scriptWarningMessage(const QString &message, const QString &fileName, int lineNumber)
Logs a script warning message and emits an warningMessage event.
Definition: ScriptManager.cpp:641
Q_INVOKABLE QString _requireResolve(const QString &moduleId, const QString &relativeTo=QString())
Script._requireResolve.
Definition: ScriptManager.cpp:1395
void removeAllEventHandlers(const EntityItemID &entityID)
Remove all event handlers for the specified entityID (i.e. the entity is being removed)
Definition: ScriptManager.cpp:920
QString getFilename() const
Get the filename of the running script, without the path.
Definition: ScriptManager.cpp:573
void infoMessage(const QString &message, const QString &scriptName)
Triggered when the script generates an information message.
Q_INVOKABLE void unloadAllEntityScripts(bool blockingCall=false)
Unload all entity scripts.
Definition: ScriptManager.cpp:2604
int getNumRunningEntityScripts() const
Get the number of running entity scripts.
Definition: ScriptManager.cpp:1962
Q_INVOKABLE void resetModuleCache(bool deleteScriptCache=false)
Resets the module cache.
Definition: ScriptManager.cpp:750
QString getAbsoluteFilename() const
Get the filename of the running script, with absolute path.
Definition: ScriptManager.cpp:582
void registerConsoleScriptingInterface(ScriptEngine::ScriptEngineScopeGuard *scopeGuard, ScriptEngine *scriptEngine)
Adds console namespace with functions such as console.log.
Definition: ScriptManager.cpp:242
ScriptValue evaluate(const QString &program, const QString &fileName=QString())
Evaluate a program in the underlying scripting engine.
Definition: ScriptManager.cpp:3020
bool isQuitWhenFinished() const
Whether to quit when finished.
Definition: ScriptManager.h:1092
void warningEntityMessage(const QString &message, const QString &fileName, int lineNumber, const EntityItemID &entityID, bool isServerScript)
Triggered when a client side entity script generates a warning.
Q_INVOKABLE void beginProfileRange(const QString &label) const
Starts timing a section of code in order to send usage data about it to Overte. Shouldn't be used out...
Definition: ScriptManager.cpp:1386
void stopTimer(int timer)
Stops a timer.
Definition: ScriptManager.cpp:1325
QVariant cloneEntityScriptDetails(const EntityItemID &entityID, const QString &scriptURL)
Clone the details of an entity script.
Definition: ScriptManager.cpp:1993
Q_INVOKABLE bool isEntityClientScript() const
Checks whether the script is running as a client entity script.
Definition: ScriptManager.h:563
void errorLoadingScript(const QString &scriptFilename)
Script.errorLoadingScript.
void setEmitScriptUpdatesFunction(std::function< bool()> func)
Set a function that determines whether to emit update events.
Definition: ScriptManager.h:1102
void removeFromScriptEngines()
Removes shared pointer to script engine from the list of all script engines.
Definition: ScriptManager.cpp:568
Q_INVOKABLE QString getContext() const
Gets the context that the script is running in: Interface/avatar, client entity, server entity,...
Definition: ScriptManager.cpp:373
Q_INVOKABLE bool isDebugMode() const
Checks whether the application was compiled as a debug build.
Definition: ScriptManager.cpp:391
bool registerModuleWithParent(const ScriptValue &module, const ScriptValue &parent)
Replaces or adds "module" to "parent.children[]" array.
Definition: ScriptManager.cpp:1506
void run()
Run the script in the caller's thread, exit when Script.stop() is called.
Definition: ScriptManager.cpp:973
Q_INVOKABLE int setTimeout(const ScriptValue &function, int timeoutMS)
Calls a function once, after a delay.
Definition: ScriptManager.cpp:1309
Q_INVOKABLE void logBacktrace(const QString &title)
Prints out current backtrace to the log.
Definition: ScriptManager.cpp:3028
void runInThread()
Run the script in a dedicated thread.
Definition: ScriptManager.cpp:427
bool isFinished() const
Whether the script has finished running.
Definition: ScriptManager.h:1021
void doneRunning()
Triggered when the script has stopped.
Q_INVOKABLE QString getExternalPath(ExternalResource::Bucket bucket, const QString &path)
Gets the URL for an asset in an external resource bucket.
Definition: ScriptManager.cpp:2984
ScriptValue getReturnValue() const
Return value of the script that finished running.
Definition: ScriptManager.h:1225
void scriptEnding()
Triggered when the script is stopping.
Q_INVOKABLE void unloadAllEntityScriptsForEntity(const EntityItemID &entityID, bool shouldRemoveFromMap=false)
Unloads all entity script for an entity.
Definition: ScriptManager.cpp:2538
Q_INVOKABLE int setInterval(const ScriptValue &function, int intervalMS)
Calls a function repeatedly, at a set interval.
Definition: ScriptManager.cpp:1293
bool isRunning() const
Whether the script is running.
Definition: ScriptManager.h:1029
bool isUserLoaded() const
Whether the script was user-loaded.
Definition: ScriptManager.h:1073
bool hasEntityScriptDetails(const EntityItemID &entityID, const QString &scriptURL) const
Whether there are script details for a given entity ID.
Definition: ScriptManager.cpp:2053
void setEntityScriptDetails(const EntityItemID &entityID, const QString &scriptURL, const EntityScriptDetails &details)
Set the details for an entity script.
Definition: ScriptManager.cpp:1975
void unhandledException(std::shared_ptr< ScriptException > exception)
Triggered when a script generates an unhandled exception.
void setQuitWhenFinished(const bool quitWhenFinished)
Set whether to quit when finished.
Definition: ScriptManager.h:1082
void releaseEntityPacketSenderMessages(bool wait)
Triggered repeatedly in the scripting loop to ensure entity edit messages get processed properly conn...
void init()
Initializes the underlying scripting engine.
Definition: ScriptManager.cpp:792
void finished(const QString &fileNameString, ScriptManagerPointer)
Script.finished.
void loadURL(const QUrl &scriptURL, bool reload)
Load a script from a given URL.
Definition: ScriptManager.cpp:592
void reloadScript(const QString &scriptName, bool isUserLoaded)
Script.reloadScript.
Context
Context of the script.
Definition: ScriptManager.h:292
@ ENTITY_CLIENT_SCRIPT
Entity client script.
Definition: ScriptManager.h:304
@ ENTITY_SERVER_SCRIPT
Entity server script.
Definition: ScriptManager.h:310
@ NETWORKLESS_TEST_SCRIPT
Network-less test system context. This is used for the QTest self-tests, and minimizes the API that i...
Definition: ScriptManager.h:329
@ CLIENT_SCRIPT
Client script. Allowed to access local HTML files on UI created from C++ calls.
Definition: ScriptManager.h:298
@ AGENT_SCRIPT
Agent script.
Definition: ScriptManager.h:316
friend ScriptManagerPointer newScriptManager(Context context, const QString &scriptContents, const QString &fileNameString)
Creates a new ScriptManager.
Definition: ScriptManager.cpp:266
void update(float deltaTime)
Triggered frequently at a system-determined interval.
Q_INVOKABLE QString formatException(const ScriptValue &exception, bool includeExtendedDetails)
Format an exception and return it as a string.
Definition: ScriptManager.cpp:2988
void setParentURL(const QString &parentURL)
Set the parent URL, used to resolve relative paths.
Definition: ScriptManager.h:1581
ScriptValue currentModule()
The current parent module from the running JS script.
Definition: ScriptManager.cpp:1485
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID &entityID, const QString &methodName, const QStringList &params=QStringList(), const QUuid &remoteCallerID=QUuid()) override
Call a method on all of an entity's scripts.
Definition: ScriptManager.cpp:2703
void setType(Type type)
Set the script type.
Definition: ScriptManager.h:998
Q_INVOKABLE bool isEntityServerScript() const
Checks whether the script is running as a server entity script.
Definition: ScriptManager.h:571
void runningStateChanged()
Triggered when the running state of the script changes, e.g., from running to stopping.
QString getTypeAsString() const
Returns the type of the script as a string.
Definition: ScriptManager.cpp:368
bool isStopped() const
Whether the ScriptManager is stopped and unable to run scripts.
Definition: ScriptManager.cpp:964
void warningMessage(const QString &message, const QString &scriptName)
Triggered when the script generates a warning.
void waitTillDoneRunning(bool shutdown=false)
Stop any evaluating scripts and wait for the scripting thread to finish.
Definition: ScriptManager.cpp:470
QVariantMap fetchModuleSource(const QString &modulePath, const bool forceDownload=false)
Synchronously fetch a module's source code.
Definition: ScriptManager.cpp:1558
Q_INVOKABLE bool isClientScript() const
Checks whether the script is running as an Interface or avatar script.
Definition: ScriptManager.h:549
ScriptValue newModule(const QString &modulePath, const ScriptValue &parent=ScriptValue())
creates a new JS "module" Object with default metadata properties
Definition: ScriptManager.cpp:1528
void scriptInfoMessage(const QString &message, const QString &fileName, int lineNumber)
Logs a script info message and emits an infoMessage event.
Definition: ScriptManager.cpp:653
[ScriptInterface] Provides an engine-independent interface for QScriptValue
Definition: ScriptValue.h:40
Entity with available script contents.
Definition: ScriptManager.h:116
bool isURL
Whether scriptOrURL contains an URL.
Definition: ScriptManager.h:139
EntityItemID entityID
Entity ID.
Definition: ScriptManager.h:121
QString status
Status as text.
Definition: ScriptManager.h:151
QString scriptOrURL
URL to the script, or the actual script if embedded in the URL field.
Definition: ScriptManager.h:127
QString contents
Contents of the script.
Definition: ScriptManager.h:133
bool success
Whether the request has been successful.
Definition: ScriptManager.h:145