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 
52 static const QString NO_SCRIPT("");
53 
54 static const int SCRIPT_FPS = 60;
55 static const int DEFAULT_MAX_ENTITY_PPS = 9000;
56 static const int DEFAULT_ENTITY_PPS_PER_SCRIPT = 900;
57 
58 class ScriptEngine;
59 class ScriptEngines;
60 class ScriptManager;
61 class ScriptManagerScriptingInterface;
62 
63 using ScriptEnginePointer = std::shared_ptr<ScriptEngine>;
64 using ScriptManagerPointer = std::shared_ptr<ScriptManager>;
65 using ScriptManagerScriptingInterfacePointer = std::shared_ptr<ScriptManagerScriptingInterface>;
66 using ScriptValueList = QList<ScriptValue>;
67 
68 Q_DECLARE_METATYPE(ScriptManagerPointer)
69 
70 const int QTREGISTER_QTimerStar = qRegisterMetaType<QTimer*>();
71 
72 
77 class CallbackData {
78 public:
83  ScriptValue function;
84 
90 
96 };
97 
98 
105 public:
106  EntityItemID entityID;
107  QString entityScript;
108  //bool forceRedownload;
109 };
110 
121 
126  QString scriptOrURL;
127 
132  QString contents;
133 
138  bool isURL;
139 
144  bool success;
145 
150  QString status;
151 };
152 
153 typedef std::unordered_map<EntityItemID, EntityScriptContentAvailable> EntityScriptContentAvailableMap;
154 
155 typedef QList<CallbackData> CallbackList;
156 typedef QHash<QString, CallbackList> RegisteredEventHandlers;
157 
158 
164 public:
165 
170  EntityScriptStatus status { EntityScriptStatus::PENDING };
171 
178  QString errorInfo { "" };
179 
180 
185  QString scriptText { "" };
186 
192 
198  int64_t lastModified { 0 };
199 
206  QUrl definingSandboxURL { QUrl("about:EntityScript") };
207 };
208 
209 // declare a static script initializers
210 #define STATIC_SCRIPT_TYPES_INITIALIZER(init) \
211  static ScriptManager::StaticTypesInitializerNode static_script_types_initializer_(init);
212 
213 #define STATIC_SCRIPT_INITIALIZER(init) \
214  static ScriptManager::StaticInitializerNode static_script_initializer_(init);
215 
216 
217 
218 
281 class ScriptManager : public QObject, public EntitiesScriptEngineProvider, public std::enable_shared_from_this<ScriptManager> {
282  Q_OBJECT
283 public:
284  static const QString SCRIPT_EXCEPTION_FORMAT;
285  static const QString SCRIPT_BACKTRACE_SEP;
286 
291  enum Context {
298 
304 
310 
316 
329  };
330 
335  enum Type {
341 
347 
354 
360 
366 
377  };
378  Q_ENUM(Type);
379 
380  static int processLevelMaxRetries;
381 private:
382  // Constructor is private so that only properly generated shared pointer can be used
383  explicit ScriptManager(Context context, const QString& scriptContents = NO_SCRIPT, const QString& fileNameString = QString("about:ScriptEngine"));
384 public:
385  ~ScriptManager() override;
386 
387  // static initialization support
388  typedef void (*ScriptManagerInitializer)(ScriptManager*);
389  class StaticInitializerNode {
390  public:
391  ScriptManagerInitializer init;
392  StaticInitializerNode* prev;
393  inline explicit StaticInitializerNode(ScriptManagerInitializer&& pInit) : init(std::move(pInit)),prev(nullptr) { registerNewStaticInitializer(this); }
394  };
395  static void registerNewStaticInitializer(StaticInitializerNode* dest);
396 
397  class StaticTypesInitializerNode {
398  public:
399  ScriptManagerInitializer init;
400  StaticTypesInitializerNode* prev;
401  inline explicit StaticTypesInitializerNode(ScriptManagerInitializer&& pInit) : init(std::move(pInit)),prev(nullptr) { registerNewStaticTypesInitializer(this); }
402  };
403  static void registerNewStaticTypesInitializer(StaticTypesInitializerNode* dest);
404 
416  void runInThread();
417 
423  void run();
424 
425 
431  QString getFilename() const;
432 
438  QString getAbsoluteFilename() const;
439 
445  inline ScriptEnginePointer engine() { return _engine; }
446 
447  QList<EntityItemID> getListOfEntityScriptIDs();
448 
459  bool isStopped() const;
460 
461 
469 
476  Q_INVOKABLE void stop(bool marshal = false);
477 
479 
489  void waitTillDoneRunning(bool shutdown = false);
490 
499 
514  void loadURL(const QUrl& scriptURL, bool reload);
515 
524  bool hasValidScriptSuffix(const QString& scriptFileName);
525 
526 
534 
541  Q_INVOKABLE QString getContext() const;
542 
548  Q_INVOKABLE bool isClientScript() const { return _context == CLIENT_SCRIPT; }
549 
555  Q_INVOKABLE bool isDebugMode() const;
556 
562  Q_INVOKABLE bool isEntityClientScript() const { return _context == ENTITY_CLIENT_SCRIPT; }
563 
564 
570  Q_INVOKABLE bool isEntityServerScript() const { return _context == ENTITY_SERVER_SCRIPT; }
571 
577  Q_INVOKABLE bool isAgentScript() const { return _context == AGENT_SCRIPT; }
578 
585  Q_INVOKABLE void registerValue(const QString& valueName, ScriptValue value);
586 
588  // NOTE - these are intended to be public interfaces available to scripts
589 
597  Q_INVOKABLE QString formatException(const ScriptValue& exception, bool includeExtendedDetails);
598 
599 
600 
610  Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, const ScriptValue& handler);
611 
619  Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, const ScriptValue& handler);
620 
621 
632  Q_INVOKABLE void load(const QString& loadfile);
633 
645  Q_INVOKABLE void include(const QStringList& includeFiles, const ScriptValue& callback = ScriptValue());
646 
658  Q_INVOKABLE void include(const QString& includeFile, const ScriptValue& callback = ScriptValue());
659 
661 
662 
663 
665 
666 
672 
681  Q_INVOKABLE ScriptValue require(const QString& moduleId);
682 
689  Q_INVOKABLE void resetModuleCache(bool deleteScriptCache = false);
690 
698 
709  bool registerModuleWithParent(const ScriptValue& module, const ScriptValue& parent);
710 
720  ScriptValue newModule(const QString& modulePath, const ScriptValue& parent = ScriptValue());
721 
736  QVariantMap fetchModuleSource(const QString& modulePath, const bool forceDownload = false);
737 
745  ScriptValue instantiateModule(const ScriptValue& module, const QString& sourceCode);
746 
756  ScriptValue evaluate(const QString& program, const QString& fileName = QString());
757 
767  Q_INVOKABLE QTimer* setInterval(const ScriptValue& function, int intervalMS);
768 
769 
779  Q_INVOKABLE QTimer* setTimeout(const ScriptValue& function, int timeoutMS);
780 
786  Q_INVOKABLE void clearInterval(QTimer* timer) { stopTimer(timer); }
787 
795  Q_INVOKABLE void clearInterval(QVariantMap timer) { ; }
796 
802  Q_INVOKABLE void clearTimeout(QTimer* timer) { stopTimer(timer); }
803 
811  Q_INVOKABLE void clearTimeout(QVariantMap timer) { ; }
812 
813 
819  Q_INVOKABLE void print(const QString& message);
820 
827  Q_INVOKABLE QUrl resolvePath(const QString& path) const;
828 
834  Q_INVOKABLE QUrl resourcesPath() const;
835 
841  Q_INVOKABLE void beginProfileRange(const QString& label) const;
842 
848  Q_INVOKABLE void endProfileRange(const QString& label) const;
849 
850 
852 
854  // Entity Script Related methods
855 
856 
863 
870  Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID& entityID, const QString& scriptURL) {
871  QReadLocker locker { &_entityScriptsLock };
872  auto it = _entityScripts.constFind(entityID);
873  if (it != _entityScripts.constEnd()) {
874  auto it2 = it.value().constFind(scriptURL);
875  return it2 != it.value().constEnd() && it2.value().status == EntityScriptStatus::RUNNING;
876  }
877  return false;
878  }
879 
887  QVariant cloneEntityScriptDetails(const EntityItemID& entityID, const QString& scriptURL);
888 
889 
899  QFuture<QVariant> getLocalEntityScriptDetails(const EntityItemID& entityID, const QString& scriptURL) override;
900 
901 
906  Q_INVOKABLE void requestGarbageCollection();
907 
913  Q_INVOKABLE void logBacktrace(const QString &title);
914 
922  Q_INVOKABLE void loadEntityScript(const EntityItemID& entityID, const QString& entityScript, bool forceRedownload);
923 
931  Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, const QString& scriptURL, bool shouldRemoveFromMap = false); // will call unload method
932 
939  Q_INVOKABLE void unloadAllEntityScriptsForEntity(const EntityItemID& entityID, bool shouldRemoveFromMap = false); // will call unload method
940 
941 
947  Q_INVOKABLE void unloadAllEntityScripts(bool blockingCall = false);
948 
957  Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
958  const QStringList& params = QStringList(),
959  const QUuid& remoteCallerID = QUuid()) override;
960 
970  Q_INVOKABLE void callEntityScriptMethodForScript(const EntityItemID& entityID,
971  const QString& scriptURL,
972  const QString& methodName,
973  const QStringList& params = QStringList(),
974  const QUuid& remoteCallerID = QUuid()) override;
975 
984  Q_INVOKABLE void callEntityScriptMethodForScript(const EntityItemID& entityID,
985  const QString& scriptURL,
986  const QString& methodName,
987  const QString& param);
988 
996  Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const PointerEvent& event);
997 
998 
1007  Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision);
1008 
1009 
1015  void setType(Type type) { _type = type; };
1016 
1022  Type getType() { return _type; };
1023 
1029  QString getTypeAsString() const;
1030 
1038  bool isFinished() const { return _isFinished; } // used by Application and ScriptWidget
1039 
1046  bool isRunning() const { return _isRunning; } // used by ScriptWidget
1047 
1048  // this is used by code in ScriptEngines.cpp during the "reload all" operation
1055  bool isStopping() const { return _isStopping; }
1056 
1064 
1065 
1067 
1068 
1070 
1079  void setUserLoaded(bool isUserLoaded) { _isUserLoaded = isUserLoaded; }
1080 
1090  bool isUserLoaded() const { return _isUserLoaded; }
1091 
1099  void setQuitWhenFinished(const bool quitWhenFinished) { _quitWhenFinished = quitWhenFinished; }
1100 
1109  bool isQuitWhenFinished() const { return _quitWhenFinished; }
1110 
1119  void setEmitScriptUpdatesFunction(std::function<bool()> func) { _emitScriptUpdates = func; }
1120 
1130  void scriptErrorMessage(const QString& message, const QString& fileName, int lineNumber);
1131 
1141  void scriptWarningMessage(const QString& message, const QString& fileName, int lineNumber);
1142 
1152  void scriptInfoMessage(const QString& message, const QString& fileName, int lineNumber);
1153 
1165  void scriptPrintedMessage(const QString& message, const QString& fileName, int lineNumber);
1166 
1173  void clearDebugLogWindow();
1174 
1180  int getNumRunningEntityScripts() const;
1181 
1191  bool getEntityScriptDetails(const EntityItemID& entityID, const QString& scriptURL, EntityScriptDetails &details) const;
1192 
1201  bool hasEntityScriptDetails(const EntityItemID& entityID, const QString& scriptURL) const;
1202 
1213  void setScriptEngines(QSharedPointer<ScriptEngines>& scriptEngines) { _scriptEngines = scriptEngines; }
1214 
1215 
1225  void forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, const ScriptValueList& eventHanderArgs);
1226 
1232  void removeAllEventHandlers(const EntityItemID& entityID);
1233 
1234 
1242  ScriptValue getReturnValue() const { return _returnValue; }
1243 
1244 
1252  Q_INVOKABLE QString getExternalPath(ExternalResource::Bucket bucket, const QString& path);
1253 
1254 
1260  std::shared_ptr<ScriptException> getUncaughtException() const;
1261 
1269  bool getAbortOnUncaughtException() const { return _abortOnUncaughtException; }
1270 
1277  void setAbortOnUncaughtException(bool value) { _abortOnUncaughtException = value; }
1278 
1285  bool isDoneRunning() { return _isDoneRunning; };
1286 
1287 public slots:
1288 
1297  void updateMemoryCost(const qint64 &deltaSize);
1298 
1299 signals:
1300 
1301 
1307 
1313  void scriptLoaded(const QString& scriptFilename);
1314 
1315 
1321  void errorLoadingScript(const QString& scriptFilename);
1322 
1323 
1329  void update(float deltaTime);
1330 
1331 
1332 
1338 
1339 
1340 
1346  void finished(const QString& fileNameString, ScriptManagerPointer);
1347 
1354  void printedMessage(const QString& message, const QString& scriptName);
1355 
1356 
1363  void errorMessage(const QString& message, const QString& scriptName);
1364 
1365 
1366 
1373  void warningMessage(const QString& message, const QString& scriptName);
1374 
1375 
1382  void infoMessage(const QString& message, const QString& scriptName);
1383 
1393  void printedEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
1394 
1395 
1405  void errorEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
1406 
1407 
1408 
1418  void warningEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
1419 
1420 
1430  void infoEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
1431 
1432 
1438 
1439 
1445 
1446 
1453  void loadScript(const QString& scriptName, bool isUserLoaded);
1454 
1455 
1462  void reloadScript(const QString& scriptName, bool isUserLoaded);
1463 
1468  void doneRunning();
1469 
1476 
1483 
1484 
1490  void unhandledException(std::shared_ptr<ScriptException> exception);
1491 
1493 
1501 
1510 
1511 protected:
1512  // Is called by the constructor, bceause all types need to be registered before method discovery with ScriptObjectV8Proxy::investigate()
1513  void initMetaTypes();
1514 
1520  void init();
1521 
1529  Q_INVOKABLE void executeOnScriptThread(std::function<void()> function, const Qt::ConnectionType& type = Qt::QueuedConnection );
1530 
1542  Q_INVOKABLE QString _requireResolve(const QString& moduleId, const QString& relativeTo = QString());
1543 
1553  QString logException(const ScriptValue& exception);
1554  void timerFired();
1555  void stopAllTimers();
1556  void stopAllTimersForEntityScript(const EntityItemID& entityID);
1557  void refreshFileScript(const EntityItemID& entityID, const QString& scriptURL);
1558 
1569  void updateEntityScriptStatus(const EntityItemID& entityID, const QString& scriptURL, const EntityScriptStatus& status, const QString& errorInfo = QString());
1570 
1571 
1579  void setEntityScriptDetails(const EntityItemID& entityID, const QString& scriptURL, const EntityScriptDetails& details);
1580 
1588  void setParentURL(const QString& parentURL) { _parentURL = parentURL; }
1589 
1598  QTimer* setupTimerWithInterval(const ScriptValue& function, int intervalMS, bool isSingleShot);
1599 
1605  void stopTimer(QTimer* timer);
1606 
1607  QHash<EntityItemID, RegisteredEventHandlers> _registeredHandlers;
1608 
1609 
1620  Q_INVOKABLE void entityScriptContentAvailable(const EntityItemID& entityID, const QString& scriptOrURL, const QString& contents, bool isURL, bool success, const QString& status);
1621 
1622  EntityItemID currentEntityIdentifier; // Contains the defining entity script entity id during execution, if any. Empty for interface script execution.
1623  QUrl currentSandboxURL; // The toplevel url string for the entity script that loaded the code being executed, else empty.
1624 
1635  void doWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, std::function<void()> operation);
1636 
1657  void callWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, const ScriptValue& function, const ScriptValue& thisObject, const ScriptValueList& args);
1658 
1659  Context _context;
1660  Type _type;
1661  ScriptEnginePointer _engine;
1662  QString _scriptContents;
1663  QString _parentURL;
1664  std::atomic<bool> _isFinished { false };
1665  std::atomic<bool> _isRunning { false };
1666  std::atomic<bool> _isStopping { false };
1667  std::atomic<bool> _isDoneRunning { false };
1668  bool _areMetaTypesInitialized { false };
1669  bool _isInitialized { false };
1670  QHash<QTimer*, CallbackData> _timerFunctionMap;
1671  QSet<QUrl> _includedURLs;
1672  mutable QReadWriteLock _entityScriptsLock { QReadWriteLock::Recursive };
1673  QHash<EntityItemID, QHash<QString, EntityScriptDetails>> _entityScripts;
1674  EntityScriptContentAvailableMap _contentAvailableQueue;
1675  ScriptValue _returnValue;
1676 
1677  bool _isThreaded { false };
1678  qint64 _lastUpdate;
1679 
1680  QString _fileNameString;
1681  std::shared_ptr<Quat> _quatLibrary;
1682  std::shared_ptr<Vec3> _vec3Library;
1683  std::shared_ptr<Mat4> _mat4Library;
1684  std::shared_ptr<ScriptUUID> _uuidLibrary;
1685  std::shared_ptr<ConsoleScriptingInterface> _consoleScriptingInterface;
1686  std::atomic<bool> _isUserLoaded { false };
1687  bool _isReloading { false };
1688 
1689  std::atomic<bool> _quitWhenFinished;
1690 
1691  std::shared_ptr<AssetScriptingInterface> _assetScriptingInterface;
1692 
1693  std::function<bool()> _emitScriptUpdates{ []() { return true; } };
1694 
1695  std::recursive_mutex _lock;
1696 
1697  std::chrono::microseconds _totalTimerExecution { 0 };
1698 
1699  static const QString _SETTINGS_ENABLE_EXTENDED_EXCEPTIONS;
1700 
1701  Setting::Handle<bool> _enableExtendedJSExceptions { _SETTINGS_ENABLE_EXTENDED_EXCEPTIONS, true };
1702 
1703  QWeakPointer<ScriptEngines> _scriptEngines;
1704 
1705 
1706 
1707  // For debugging performance issues
1708  int _timerCallCounter{ 0 };
1709  double _totalTimeInTimerEvents_s{ 0.0 };
1710 
1711  ScriptManagerScriptingInterfacePointer _scriptingInterface;
1712 
1713  bool _abortOnUncaughtException{ false };
1714 
1715  friend ScriptManagerPointer newScriptManager(Context context, const QString& scriptContents, const QString& fileNameString);
1716  friend class ScriptManagerScriptingInterface;
1717 
1718  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.
1719 };
1720 
1729 ScriptManagerPointer newScriptManager(ScriptManager::Context context,
1730  const QString& scriptContents,
1731  const QString& fileNameString);
1732 
1744 ScriptManagerPointer scriptManagerFactory(ScriptManager::Context context,
1745  const QString& scriptContents,
1746  const QString& fileNameString);
1747 
1748 #endif // hifi_ScriptManager_h
Callback data for addEventHandler.
Definition: ScriptManager.h:77
QUrl definingSandboxURL
Sandbox URL for the script.
Definition: ScriptManager.h:95
EntityItemID definingEntityIdentifier
Entity ID.
Definition: ScriptManager.h:89
DeferredLoadEntity.
Definition: ScriptManager.h:104
Abstract ID for editing model items. Used in EntityItem JS API.
Definition: EntityItemID.h:28
Details about an entity script.
Definition: ScriptManager.h:163
QUrl definingSandboxURL
URL under which the script is allowed to have access.
Definition: ScriptManager.h:206
int64_t lastModified
Last modified time of the underlying script file.
Definition: ScriptManager.h:198
ScriptValue scriptObject
The return value of the script.
Definition: ScriptManager.h:191
QString errorInfo
Error information.
Definition: ScriptManager.h:178
QString scriptText
The source code of the script.
Definition: ScriptManager.h:185
EntityScriptStatus status
Current status.
Definition: ScriptManager.h:170
Represents a 2D or 3D pointer to the scripting engine. Exposed as PointerEvent
Definition: PointerEvent.h:32
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:281
Type
Type of the script.
Definition: ScriptManager.h:335
@ NETWORKLESS_TEST
Test system script.
Definition: ScriptManager.h:376
@ AVATAR
Avatar script.
Definition: ScriptManager.h:365
@ AGENT
Agent script.
Definition: ScriptManager.h:359
@ ENTITY_SERVER
Entity server Receives the update event.
Definition: ScriptManager.h:353
@ CLIENT
Client.
Definition: ScriptManager.h:340
@ ENTITY_CLIENT
Entity client Receives the update event.
Definition: ScriptManager.h:346
Q_INVOKABLE void executeOnScriptThread(std::function< void()> function, const Qt::ConnectionType &type=Qt::QueuedConnection)
executeOnScriptThread
Definition: ScriptManager.cpp:443
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:2666
void setUserLoaded(bool isUserLoaded)
Set whether this script was user-loaded.
Definition: ScriptManager.h:1079
void disconnectNonEssentialSignals()
Disconnect all signals, except essential ones.
Definition: ScriptManager.cpp:402
void setScriptEngines(QSharedPointer< ScriptEngines > &scriptEngines)
Set a shared pointer to the ScriptEngines class.
Definition: ScriptManager.h:1213
Q_INVOKABLE void clearTimeout(QTimer *timer)
Stops a timeout timer.
Definition: ScriptManager.h:802
Q_INVOKABLE void registerValue(const QString &valueName, ScriptValue value)
Registers a global object by name.
Definition: ScriptManager.cpp:874
Q_INVOKABLE void loadEntityScript(const EntityItemID &entityID, const QString &entityScript, bool forceRedownload)
Load an entity script.
Definition: ScriptManager.cpp:2050
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:879
Q_INVOKABLE QTimer * setInterval(const ScriptValue &function, int intervalMS)
Calls a function repeatedly, at a set interval.
Definition: ScriptManager.cpp:1279
Q_INVOKABLE void requestGarbageCollection()
Manually runs the JavaScript garbage collector which reclaims memory by disposing of objects that are...
Definition: ScriptManager.cpp:3012
Q_INVOKABLE void print(const QString &message)
Prints a message to the program log.
Definition: ScriptManager.cpp:1369
bool getEntityScriptDetails(const EntityItemID &entityID, const QString &scriptURL, EntityScriptDetails &details) const
Retrieves the details about an entity script.
Definition: ScriptManager.cpp:2027
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:1378
Q_INVOKABLE QUrl resourcesPath() const
Gets the path to the resources directory for QML files.
Definition: ScriptManager.cpp:1365
Q_INVOKABLE void stop(bool marshal=false)
Stops and unloads the current script.
Definition: ScriptManager.cpp:1191
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:2766
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:2023
bool isDoneRunning()
Returns true after script finished running and doneRunning signal was called.
Definition: ScriptManager.h:1285
void scriptPrintedMessage(const QString &message, const QString &fileName, int lineNumber)
Logs a script printed message and emits an printedMessage event.
Definition: ScriptManager.cpp:647
void entityScriptPreloadFinished(const EntityItemID &entityID)
Emitted when an entity script has finished running preload.
void clearDebugLogWindow()
Clears the debug log window.
Definition: ScriptManager.cpp:661
std::shared_ptr< ScriptException > getUncaughtException() const
Get the uncaught exception from the underlying script engine.
Definition: ScriptManager.cpp:237
void updateMemoryCost(const qint64 &deltaSize)
Script.updateMemoryCost.
Definition: ScriptManager.cpp:1208
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:1925
Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID &entityID, const QString &scriptURL)
Checks whether an entity has an entity script running.
Definition: ScriptManager.h:870
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:1892
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:1971
Type getType()
Returns the script type.
Definition: ScriptManager.h:1022
void scriptErrorMessage(const QString &message, const QString &fileName, int lineNumber)
Logs a script error message and emits an errorMessage event.
Definition: ScriptManager.cpp:611
bool hasValidScriptSuffix(const QString &scriptFileName)
Determines whether a script filename has the right suffix.
Definition: ScriptManager.cpp:568
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:1277
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:2472
bool isStopping() const
Whether this ScriptManager is stopping. Once this is true, it stays true.
Definition: ScriptManager.h:1055
QString logException(const ScriptValue &exception)
Log an exception.
Definition: ScriptManager.cpp:226
Q_INVOKABLE bool isAgentScript() const
Checks whether the script is running as an assignment client script.
Definition: ScriptManager.h:577
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:925
QTimer * setupTimerWithInterval(const ScriptValue &function, int intervalMS, bool isSingleShot)
Creates a timer with the specified interval.
Definition: ScriptManager.cpp:1255
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:2123
Q_INVOKABLE ScriptValue require(const QString &moduleId)
Provides access to methods or objects provided in an external JavaScript or JSON file.
Definition: ScriptManager.cpp:1629
ScriptValue instantiateModule(const ScriptValue &module, const QString &sourceCode)
Evaluate a pending module object using the fetched source code.
Definition: ScriptManager.cpp:1604
ScriptEnginePointer engine()
Underlying scripting engine.
Definition: ScriptManager.h:445
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.
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:2684
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:1321
bool getAbortOnUncaughtException() const
Whether this engine will abort on an uncaught exception.
Definition: ScriptManager.h:1269
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.
Q_INVOKABLE void clearInterval(QTimer *timer)
Stops an interval timer.
Definition: ScriptManager.h:786
Q_INVOKABLE void include(const QStringList &includeFiles, const ScriptValue &callback=ScriptValue())
Includes JavaScript from other files in the current script.
Definition: ScriptManager.cpp:1735
void scriptWarningMessage(const QString &message, const QString &fileName, int lineNumber)
Logs a script warning message and emits an warningMessage event.
Definition: ScriptManager.cpp:623
Q_INVOKABLE QString _requireResolve(const QString &moduleId, const QString &relativeTo=QString())
Script._requireResolve.
Definition: ScriptManager.cpp:1383
void removeAllEventHandlers(const EntityItemID &entityID)
Remove all event handlers for the specified entityID (i.e. the entity is being removed)
Definition: ScriptManager.cpp:910
QString getFilename() const
Get the filename of the running script, without the path.
Definition: ScriptManager.cpp:555
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:2592
int getNumRunningEntityScripts() const
Get the number of running entity scripts.
Definition: ScriptManager.cpp:1950
Q_INVOKABLE void resetModuleCache(bool deleteScriptCache=false)
Resets the module cache.
Definition: ScriptManager.cpp:732
QString getAbsoluteFilename() const
Get the filename of the running script, with absolute path.
Definition: ScriptManager.cpp:564
ScriptValue evaluate(const QString &program, const QString &fileName=QString())
Evaluate a program in the underlying scripting engine.
Definition: ScriptManager.cpp:3008
bool isQuitWhenFinished() const
Whether to quit when finished.
Definition: ScriptManager.h:1109
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:1374
QVariant cloneEntityScriptDetails(const EntityItemID &entityID, const QString &scriptURL)
Clone the details of an entity script.
Definition: ScriptManager.cpp:1981
Q_INVOKABLE bool isEntityClientScript() const
Checks whether the script is running as a client entity script.
Definition: ScriptManager.h:562
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:1119
void removeFromScriptEngines()
Removes shared pointer to script engine from the list of all script engines.
Definition: ScriptManager.cpp:550
Q_INVOKABLE QString getContext() const
Gets the context that the script is running in: Interface/avatar, client entity, server entity,...
Definition: ScriptManager.cpp:358
Q_INVOKABLE bool isDebugMode() const
Checks whether the application was compiled as a debug build.
Definition: ScriptManager.cpp:376
bool registerModuleWithParent(const ScriptValue &module, const ScriptValue &parent)
Replaces or adds "module" to "parent.children[]" array.
Definition: ScriptManager.cpp:1494
void run()
Run the script in the caller's thread, exit when Script.stop() is called.
Definition: ScriptManager.cpp:963
Q_INVOKABLE void logBacktrace(const QString &title)
Prints out current backtrace to the log.
Definition: ScriptManager.cpp:3016
void runInThread()
Run the script in a dedicated thread.
Definition: ScriptManager.cpp:412
bool isFinished() const
Whether the script has finished running.
Definition: ScriptManager.h:1038
void doneRunning()
Triggered when the script has stopped.
Q_INVOKABLE QTimer * setTimeout(const ScriptValue &function, int timeoutMS)
Calls a function once, after a delay.
Definition: ScriptManager.cpp:1295
Q_INVOKABLE QString getExternalPath(ExternalResource::Bucket bucket, const QString &path)
Gets the URL for an asset in an external resource bucket.
Definition: ScriptManager.cpp:2972
Q_INVOKABLE void clearTimeout(QVariantMap timer)
Stops a timeout timer Overloaded version is needed in case the timer has expired.
Definition: ScriptManager.h:811
ScriptValue getReturnValue() const
Return value of the script that finished running.
Definition: ScriptManager.h:1242
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:2526
bool isRunning() const
Whether the script is running.
Definition: ScriptManager.h:1046
bool isUserLoaded() const
Whether the script was user-loaded.
Definition: ScriptManager.h:1090
bool hasEntityScriptDetails(const EntityItemID &entityID, const QString &scriptURL) const
Whether there are script details for a given entity ID.
Definition: ScriptManager.cpp:2041
void setEntityScriptDetails(const EntityItemID &entityID, const QString &scriptURL, const EntityScriptDetails &details)
Set the details for an entity script.
Definition: ScriptManager.cpp:1963
void stopTimer(QTimer *timer)
Stops a timer.
Definition: ScriptManager.cpp:1311
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:1099
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:774
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:574
void reloadScript(const QString &scriptName, bool isUserLoaded)
Script.reloadScript.
Context
Context of the script.
Definition: ScriptManager.h:291
@ ENTITY_CLIENT_SCRIPT
Entity client script.
Definition: ScriptManager.h:303
@ ENTITY_SERVER_SCRIPT
Entity server script.
Definition: ScriptManager.h:309
@ 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:328
@ CLIENT_SCRIPT
Client script. Allowed to access local HTML files on UI created from C++ calls.
Definition: ScriptManager.h:297
@ AGENT_SCRIPT
Agent script.
Definition: ScriptManager.h:315
friend ScriptManagerPointer newScriptManager(Context context, const QString &scriptContents, const QString &fileNameString)
Creates a new ScriptManager.
Definition: ScriptManager.cpp:251
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:2976
void setParentURL(const QString &parentURL)
Set the parent URL, used to resolve relative paths.
Definition: ScriptManager.h:1588
ScriptValue currentModule()
The current parent module from the running JS script.
Definition: ScriptManager.cpp:1473
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:2691
void setType(Type type)
Set the script type.
Definition: ScriptManager.h:1015
Q_INVOKABLE bool isEntityServerScript() const
Checks whether the script is running as a server entity script.
Definition: ScriptManager.h:570
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:353
bool isStopped() const
Whether the ScriptManager is stopped and unable to run scripts.
Definition: ScriptManager.cpp:954
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:455
QVariantMap fetchModuleSource(const QString &modulePath, const bool forceDownload=false)
Synchronously fetch a module's source code.
Definition: ScriptManager.cpp:1546
Q_INVOKABLE bool isClientScript() const
Checks whether the script is running as an Interface or avatar script.
Definition: ScriptManager.h:548
ScriptValue newModule(const QString &modulePath, const ScriptValue &parent=ScriptValue())
creates a new JS "module" Object with default metadata properties
Definition: ScriptManager.cpp:1516
void scriptInfoMessage(const QString &message, const QString &fileName, int lineNumber)
Logs a script info message and emits an infoMessage event.
Definition: ScriptManager.cpp:635
Q_INVOKABLE void clearInterval(QVariantMap timer)
Stops an interval timer.
Definition: ScriptManager.h:795
[ScriptInterface] Provides an engine-independent interface for QScriptValue
Definition: ScriptValue.h:40
Entity with available script contents.
Definition: ScriptManager.h:115
bool isURL
Whether scriptOrURL contains an URL.
Definition: ScriptManager.h:138
EntityItemID entityID
Entity ID.
Definition: ScriptManager.h:120
QString status
Status as text.
Definition: ScriptManager.h:150
QString scriptOrURL
URL to the script, or the actual script if embedded in the URL field.
Definition: ScriptManager.h:126
QString contents
Contents of the script.
Definition: ScriptManager.h:132
bool success
Whether the request has been successful.
Definition: ScriptManager.h:144