mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 15:33:10 +02:00
commit
8c49803319
9 changed files with 2029 additions and 546 deletions
|
@ -5,6 +5,7 @@
|
|||
// Created by Brad Hefta-Gaub on 12/14/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
// Copyright 2020 Vircadia contributors.
|
||||
// Copyright 2023 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -44,49 +45,226 @@ template <typename T>
|
|||
inline T scriptvalue_cast(const ScriptValue& value);
|
||||
|
||||
|
||||
/// [ScriptInterface] Provides an engine-independent interface for QScriptEngine
|
||||
/**
|
||||
* @brief Provides an engine-independent interface for a scripting engine
|
||||
*
|
||||
* Each script engine is strictly single threaded.
|
||||
*
|
||||
* This class only provides an interface to the underlying scripting engine, and doesn't
|
||||
* provide the full environment needed to execute scripts.
|
||||
*
|
||||
* To execute scripts that have access to the API, use ScriptManager.
|
||||
*/
|
||||
class ScriptEngine {
|
||||
public:
|
||||
typedef ScriptValue (*FunctionSignature)(ScriptContext*, ScriptEngine*);
|
||||
typedef ScriptValue (*MarshalFunction)(ScriptEngine*, const void*);
|
||||
typedef bool (*DemarshalFunction)(const ScriptValue&, QVariant &dest);
|
||||
|
||||
/**
|
||||
* @brief Who owns a given object
|
||||
*
|
||||
*/
|
||||
enum ValueOwnership {
|
||||
/**
|
||||
* @brief Object is managed by Qt
|
||||
*
|
||||
*/
|
||||
QtOwnership = 0,
|
||||
|
||||
/**
|
||||
* @brief Object is managed by the script
|
||||
*
|
||||
*/
|
||||
ScriptOwnership = 1,
|
||||
|
||||
/**
|
||||
* @brief Ownership is determined automatically
|
||||
*
|
||||
*/
|
||||
AutoOwnership = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Which part of an object is exposed to the script
|
||||
*
|
||||
*/
|
||||
enum QObjectWrapOption {
|
||||
//ExcludeChildObjects = 0x0001, // The script object will not expose child objects as properties.
|
||||
ExcludeSuperClassMethods = 0x0002, // The script object will not expose signals and slots inherited from the superclass.
|
||||
ExcludeSuperClassProperties = 0x0004, // The script object will not expose properties inherited from the superclass.
|
||||
|
||||
/**
|
||||
* @brief The script object will not expose child objects as properties.
|
||||
*
|
||||
*/
|
||||
//ExcludeChildObjects = 0x0001,
|
||||
|
||||
/**
|
||||
* @brief The script object will not expose signals and slots inherited from the superclass.
|
||||
*
|
||||
*/
|
||||
ExcludeSuperClassMethods = 0x0002,
|
||||
|
||||
/**
|
||||
* @brief The script object will not expose properties inherited from the superclass.
|
||||
*
|
||||
*/
|
||||
ExcludeSuperClassProperties = 0x0004,
|
||||
|
||||
/**
|
||||
* @brief The script object will not expose the QObject::deleteLater() slot.
|
||||
*
|
||||
*/
|
||||
ExcludeSuperClassContents = ExcludeSuperClassMethods | ExcludeSuperClassProperties,
|
||||
//ExcludeDeleteLater = 0x0010, // The script object will not expose the QObject::deleteLater() slot.
|
||||
ExcludeSlots = 0x0020, // The script object will not expose the QObject's slots.
|
||||
AutoCreateDynamicProperties = 0x0100, // Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object.
|
||||
PreferExistingWrapperObject = 0x0200, // If a wrapper object with the requested configuration already exists, return that object.
|
||||
SkipMethodsInEnumeration = 0x0008, // Don't include methods (signals and slots) when enumerating the object's properties.
|
||||
|
||||
//ExcludeDeleteLater = 0x0010,
|
||||
|
||||
/**
|
||||
* @brief The script object will not expose the QObject's slots.
|
||||
*
|
||||
*/
|
||||
ExcludeSlots = 0x0020,
|
||||
|
||||
/**
|
||||
* @brief Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object.
|
||||
*
|
||||
*/
|
||||
AutoCreateDynamicProperties = 0x0100,
|
||||
|
||||
/**
|
||||
* @brief If a wrapper object with the requested configuration already exists, return that object.
|
||||
*
|
||||
*/
|
||||
PreferExistingWrapperObject = 0x0200,
|
||||
|
||||
/**
|
||||
* @brief Don't include methods (signals and slots) when enumerating the object's properties.
|
||||
*
|
||||
*/
|
||||
SkipMethodsInEnumeration = 0x0008,
|
||||
};
|
||||
Q_DECLARE_FLAGS(QObjectWrapOptions, QObjectWrapOption);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Stops the currently running script
|
||||
*
|
||||
*/
|
||||
virtual void abortEvaluation() = 0;
|
||||
|
||||
/**
|
||||
* @brief Clears uncaughtException and related
|
||||
*
|
||||
*/
|
||||
virtual void clearExceptions() = 0;
|
||||
|
||||
/**
|
||||
* @brief Creates a clone of the current exception
|
||||
*
|
||||
* @param detail Additional text to add to the report
|
||||
* @return ScriptValue Result
|
||||
*/
|
||||
virtual ScriptValue cloneUncaughtException(const QString& detail = QString()) = 0;
|
||||
|
||||
/**
|
||||
* @brief Context of the currently running script
|
||||
*
|
||||
* This allows getting a backtrace, the local variables of the currently running function, etc.
|
||||
*
|
||||
* @return ScriptContext*
|
||||
*/
|
||||
virtual ScriptContext* currentContext() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Runs a script
|
||||
*
|
||||
* This may be called several times during the lifetime of a scripting engine, with the
|
||||
* side effects accumulating.
|
||||
*
|
||||
* @param program Code to run
|
||||
* @param fileName Name of the script, for informational purposes
|
||||
* @return ScriptValue Return value of the script when it finishes running.
|
||||
*/
|
||||
virtual ScriptValue evaluate(const QString& program, const QString& fileName = QString()) = 0;
|
||||
|
||||
/**
|
||||
* @brief Evaluates a pre-compiled program
|
||||
*
|
||||
* @param program Program to evaluaate
|
||||
* @return ScriptValue
|
||||
*/
|
||||
virtual ScriptValue evaluate(const ScriptProgramPointer &program) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Evaluate a script in a separate environment
|
||||
*
|
||||
* Used for evaluating included scripts
|
||||
*
|
||||
* @param locals Local variables available to the script
|
||||
* @param program Code to run
|
||||
* @return ScriptValue
|
||||
*/
|
||||
virtual ScriptValue evaluateInClosure(const ScriptValue& locals, const ScriptProgramPointer& program) = 0;
|
||||
|
||||
/**
|
||||
* @brief Global object which holds all the functions and variables available everywhere
|
||||
*
|
||||
* This is a JavaScript concept, https://javascript.info/global-object
|
||||
*
|
||||
* @note This may not belong in the base class.
|
||||
* @return ScriptValue Global Object
|
||||
*/
|
||||
virtual ScriptValue globalObject() {
|
||||
Q_ASSERT(false);
|
||||
return ScriptValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether the script has an uncaught exception
|
||||
*
|
||||
* @return true There is an uncaught exception
|
||||
* @return false There's no exception
|
||||
*/
|
||||
virtual bool hasUncaughtException() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Whether a script is currently being evaluated
|
||||
*
|
||||
* @return true A script is currently being evaluated
|
||||
* @return false No script is being evaluated
|
||||
*/
|
||||
virtual bool isEvaluating() const = 0;
|
||||
//virtual ScriptValue lintScript(const QString& sourceCode, const QString& fileName, const int lineNumber = 1) = 0;
|
||||
virtual ScriptValue checkScriptSyntax(ScriptProgramPointer program) = 0;
|
||||
|
||||
/**
|
||||
* @brief Check a program for syntax errors
|
||||
*
|
||||
* Returns an object with at least the following properties:
|
||||
* * fileName
|
||||
* * lineNumber
|
||||
* * stack
|
||||
* * formatted
|
||||
*
|
||||
* @param program Program to check
|
||||
* @return ScriptValue Result
|
||||
*
|
||||
* @note It could be a good improvement to redo this to return a struct instead.
|
||||
*/
|
||||
virtual ScriptValue checkScriptSyntax(ScriptProgramPointer program) = 0;
|
||||
|
||||
/**
|
||||
* @brief Creates a ScriptValue that contains an error
|
||||
*
|
||||
* @param other
|
||||
* @param type
|
||||
* @return ScriptValue
|
||||
*/
|
||||
virtual ScriptValue makeError(const ScriptValue& other = ScriptValue(), const QString& type = "Error") = 0;
|
||||
|
||||
/**
|
||||
* @brief Pointer to the ScriptManager that controls this scripting engine
|
||||
*
|
||||
* @return ScriptManager* ScriptManager
|
||||
*/
|
||||
virtual ScriptManager* manager() const = 0;
|
||||
virtual bool maybeEmitUncaughtException(const QString& debugHint = QString()) = 0;
|
||||
virtual ScriptValue newArray(uint length = 0) = 0;
|
||||
|
@ -107,6 +285,15 @@ public:
|
|||
virtual ScriptValue newValue(const char* value) = 0;
|
||||
virtual ScriptValue newVariant(const QVariant& value) = 0;
|
||||
virtual ScriptValue nullValue() = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Causes an exception to be raised in the currently executing script
|
||||
*
|
||||
* @param exception
|
||||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
virtual bool raiseException(const ScriptValue& exception) = 0;
|
||||
virtual void registerEnum(const QString& enumName, QMetaEnum newEnum) = 0;
|
||||
virtual void registerFunction(const QString& name, FunctionSignature fun, int numArguments = -1) = 0;
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "ScriptProgram.h"
|
||||
#include "ScriptValueIterator.h"
|
||||
#include "ScriptValueUtils.h"
|
||||
#include "ScriptManagerScriptingInterface.h"
|
||||
|
||||
#include <Profile.h>
|
||||
|
||||
|
@ -270,6 +271,8 @@ ScriptManager::ScriptManager(Context context, const QString& scriptContents, con
|
|||
break;
|
||||
}
|
||||
|
||||
_scriptingInterface = std::make_shared<ScriptManagerScriptingInterface>(this);
|
||||
|
||||
if (isEntityServerScript()) {
|
||||
qCDebug(scriptengine) << "isEntityServerScript() -- limiting maxRetries to 1";
|
||||
processLevelMaxRetries = 1;
|
||||
|
@ -683,7 +686,7 @@ void ScriptManager::init() {
|
|||
// NOTE: You do not want to end up creating new instances of singletons here. They will be on the ScriptManager thread
|
||||
// and are likely to be unusable if we "reset" the ScriptManager by creating a new one (on a whole new thread).
|
||||
|
||||
scriptEngine->registerGlobalObject("Script", this);
|
||||
scriptEngine->registerGlobalObject("Script", _scriptingInterface.get());
|
||||
|
||||
{
|
||||
// set up Script.require.resolve and Script.require.cache
|
||||
|
@ -827,7 +830,7 @@ void ScriptManager::run() {
|
|||
// (because we're a client script)
|
||||
hifi::scripting::setLocalAccessSafeThread(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//_engine->enterIsolateOnThisThread();
|
||||
|
||||
|
@ -1878,32 +1881,6 @@ void ScriptManager::loadEntityScript(const EntityItemID& entityID, const QString
|
|||
}, forceRedownload);
|
||||
}
|
||||
|
||||
/*@jsdoc
|
||||
* Triggered when the script starts for a user. See also, {@link Script.entityScriptPreloadFinished}.
|
||||
* <p>Note: Can only be connected to via <code>this.preload = function (...) { ... }</code> in the entity script.</p>
|
||||
* <p class="availableIn"><strong>Supported Script Types:</strong> Client Entity Scripts • Server Entity Scripts</p>
|
||||
* @function Entities.preload
|
||||
* @param {Uuid} entityID - The ID of the entity that the script is running in.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Get the ID of the entity that a client entity script is running in.</caption>
|
||||
* var entityScript = (function () {
|
||||
* this.entityID = Uuid.NULL;
|
||||
*
|
||||
* this.preload = function (entityID) {
|
||||
* this.entityID = entityID;
|
||||
* print("Entity ID: " + this.entityID);
|
||||
* };
|
||||
* });
|
||||
*
|
||||
* var entityID = Entities.addEntity({
|
||||
* type: "Box",
|
||||
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
|
||||
* dimensions: { x: 0.5, y: 0.5, z: 0.5 },
|
||||
* color: { red: 255, green: 0, blue: 0 },
|
||||
* script: "(" + entityScript + ")", // Could host the script on a Web server instead.
|
||||
* lifetime: 300 // Delete after 5 minutes.
|
||||
* });
|
||||
*/
|
||||
// The JSDoc is for the callEntityScriptMethod() call in this method.
|
||||
// since all of these operations can be asynch we will always do the actual work in the response handler
|
||||
// for the download
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// ScriptManagerScriptingInterface.h
|
||||
// libraries/script-engine/src
|
||||
//
|
||||
// Created by Dale Glass on 24/02/2023.
|
||||
// Copyright 2023 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ScriptManager.h"
|
||||
#include "ScriptManagerScriptingInterface.h"
|
||||
|
||||
|
||||
ScriptManagerScriptingInterface::ScriptManagerScriptingInterface(ScriptManager *parent): QObject(parent), _manager(parent) {
|
||||
connect(_manager, &ScriptManager::scriptLoaded, this, &ScriptManagerScriptingInterface::scriptLoaded);
|
||||
connect(_manager, &ScriptManager::errorLoadingScript, this, &ScriptManagerScriptingInterface::errorLoadingScript);
|
||||
connect(_manager, &ScriptManager::update, this, &ScriptManagerScriptingInterface::update);
|
||||
connect(_manager, &ScriptManager::scriptEnding, this, &ScriptManagerScriptingInterface::scriptEnding);
|
||||
connect(_manager, &ScriptManager::finished, this, &ScriptManagerScriptingInterface::finished);
|
||||
connect(_manager, &ScriptManager::printedMessage, this, &ScriptManagerScriptingInterface::printedMessage);
|
||||
connect(_manager, &ScriptManager::errorMessage, this, &ScriptManagerScriptingInterface::errorMessage);
|
||||
connect(_manager, &ScriptManager::warningMessage, this, &ScriptManagerScriptingInterface::warningMessage);
|
||||
connect(_manager, &ScriptManager::infoMessage, this, &ScriptManagerScriptingInterface::infoMessage);
|
||||
connect(_manager, &ScriptManager::runningStateChanged, this, &ScriptManagerScriptingInterface::runningStateChanged);
|
||||
connect(_manager, &ScriptManager::clearDebugWindow, this, &ScriptManagerScriptingInterface::clearDebugWindow);
|
||||
connect(_manager, &ScriptManager::loadScript, this, &ScriptManagerScriptingInterface::loadScript);
|
||||
connect(_manager, &ScriptManager::doneRunning, this, &ScriptManagerScriptingInterface::doneRunning);
|
||||
connect(_manager, &ScriptManager::entityScriptDetailsUpdated, this, &ScriptManagerScriptingInterface::entityScriptDetailsUpdated);
|
||||
connect(_manager, &ScriptManager::entityScriptPreloadFinished, this, &ScriptManagerScriptingInterface::entityScriptPreloadFinished);
|
||||
connect(_manager, &ScriptManager::unhandledException, this, &ScriptManagerScriptingInterface::unhandledException);
|
||||
}
|
703
libraries/script-engine/src/ScriptManagerScriptingInterface.h
Normal file
703
libraries/script-engine/src/ScriptManagerScriptingInterface.h
Normal file
|
@ -0,0 +1,703 @@
|
|||
//
|
||||
// ScriptManagerScriptingInterface.h
|
||||
// libraries/script-engine/src
|
||||
//
|
||||
// Created by Dale Glass on 24/02/2023.
|
||||
// Copyright 2023 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include "ScriptManager.h"
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* The <code>Script</code> API provides facilities for working with scripts.
|
||||
*
|
||||
* @namespace Script
|
||||
*
|
||||
* @hifi-interface
|
||||
* @hifi-client-entity
|
||||
* @hifi-avatar
|
||||
* @hifi-server-entity
|
||||
* @hifi-assignment-client
|
||||
*
|
||||
* @property {string} context - The context that the script is running in:
|
||||
* <ul>
|
||||
* <li><code>"client"</code>: An Interface or avatar script.</li>
|
||||
* <li><code>"entity_client"</code>: A client entity script.</li>
|
||||
* <li><code>"entity_server"</code>: A server entity script.</li>
|
||||
* <li><code>"agent"</code>: An assignment client script.</li>
|
||||
* </ul>
|
||||
* <em>Read-only.</em>
|
||||
* @property {string} type - The type of script that is running:
|
||||
* <ul>
|
||||
* <li><code>"client"</code>: An Interface script.</li>
|
||||
* <li><code>"entity_client"</code>: A client entity script.</li>
|
||||
* <li><code>"avatar"</code>: An avatar script.</li>
|
||||
* <li><code>"entity_server"</code>: A server entity script.</li>
|
||||
* <li><code>"agent"</code>: An assignment client script.</li>
|
||||
* </ul>
|
||||
* <em>Read-only.</em>
|
||||
* @property {string} filename - The filename of the script file.
|
||||
* <em>Read-only.</em>
|
||||
* @property {Script.ResourceBuckets} ExternalPaths - External resource buckets.
|
||||
*/
|
||||
|
||||
class ScriptManagerScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScriptManagerScriptingInterface(ScriptManager *parent);
|
||||
|
||||
virtual ~ScriptManagerScriptingInterface() {
|
||||
|
||||
}
|
||||
/**jsdoc
|
||||
* Stops and unloads the current script.
|
||||
* <p><strong>Warning:</strong> If an assignment client script, the script gets restarted after stopping.</p>
|
||||
* @function Script.stop
|
||||
* @param {boolean} [marshal=false] - Marshal.
|
||||
* <p class="important">Deprecated: This parameter is deprecated and will be removed.</p>
|
||||
* @example <caption>Stop a script after 5s.</caption>
|
||||
* Script.setInterval(function () {
|
||||
* print("Hello");
|
||||
* }, 1000);
|
||||
*
|
||||
* Script.setTimeout(function () {
|
||||
* Script.stop(true);
|
||||
* }, 5000);
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts
|
||||
Q_INVOKABLE void stop(bool marshal = false) { _manager->stop(marshal); }
|
||||
|
||||
/**jsdoc
|
||||
* Gets the context that the script is running in: Interface/avatar, client entity, server entity, or assignment client.
|
||||
* @function Script.getContext
|
||||
* @returns {string} The context that the script is running in:
|
||||
* <ul>
|
||||
* <li><code>"client"</code>: An Interface or avatar script.</li>
|
||||
* <li><code>"entity_client"</code>: A client entity script.</li>
|
||||
* <li><code>"entity_server"</code>: A server entity script.</li>
|
||||
* <li><code>"agent"</code>: An assignment client script.</li>
|
||||
* </ul>
|
||||
*/
|
||||
Q_INVOKABLE QString getContext() const { return _manager->getContext(); }
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Checks whether the script is running as an Interface or avatar script.
|
||||
* @function Script.isClientScript
|
||||
* @returns {boolean} <code>true</code> if the script is running as an Interface or avatar script, <code>false</code> if it
|
||||
* isn't.
|
||||
*/
|
||||
Q_INVOKABLE bool isClientScript() const { return _manager->isClientScript(); }
|
||||
|
||||
/**jsdoc
|
||||
* Checks whether the application was compiled as a debug build.
|
||||
* @function Script.isDebugMode
|
||||
* @returns {boolean} <code>true</code> if the application was compiled as a debug build, <code>false</code> if it was
|
||||
* compiled as a release build.
|
||||
*/
|
||||
Q_INVOKABLE bool isDebugMode() const { return _manager->isDebugMode(); }
|
||||
|
||||
/**jsdoc
|
||||
* Checks whether the script is running as a client entity script.
|
||||
* @function Script.isEntityClientScript
|
||||
* @returns {boolean} <code>true</code> if the script is running as a client entity script, <code>false</code> if it isn't.
|
||||
*/
|
||||
Q_INVOKABLE bool isEntityClientScript() const { return _manager->isEntityClientScript(); }
|
||||
|
||||
/**jsdoc
|
||||
* Checks whether the script is running as a server entity script.
|
||||
* @function Script.isEntityServerScript
|
||||
* @returns {boolean} <code>true</code> if the script is running as a server entity script, <code>false</code> if it isn't.
|
||||
*/
|
||||
Q_INVOKABLE bool isEntityServerScript() const { return _manager->isEntityServerScript(); }
|
||||
|
||||
/**jsdoc
|
||||
* Checks whether the script is running as an assignment client script.
|
||||
* @function Script.isAgentScript
|
||||
* @returns {boolean} <code>true</code> if the script is running as an assignment client script, <code>false</code> if it
|
||||
* isn't.
|
||||
*/
|
||||
Q_INVOKABLE bool isAgentScript() const { return _manager->isAgentScript(); }
|
||||
|
||||
/*@jsdoc
|
||||
* registers a global object by name.
|
||||
* @function Script.registerValue
|
||||
* @param {string} valueName
|
||||
* @param {value} value
|
||||
*/
|
||||
/// registers a global object by name
|
||||
Q_INVOKABLE void registerValue(const QString& valueName, ScriptValue value) { _manager->registerValue(valueName, value); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE - these are intended to be public interfaces available to scripts
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.formatExecption
|
||||
* @param {object} exception - Exception.
|
||||
* @param {boolean} inludeExtendeDetails - Include extended details.
|
||||
* @returns {string} String.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE QString formatException(const ScriptValue& exception, bool includeExtendedDetails) { return _manager->formatException(exception, includeExtendedDetails); }
|
||||
|
||||
/**jsdoc
|
||||
* Adds a function to the list of functions called when a particular event occurs on a particular entity.
|
||||
* <p>See also, the {@link Entities} API.</p>
|
||||
* @function Script.addEventHandler
|
||||
* @param {Uuid} entityID - The ID of the entity.
|
||||
* @param {Script.EntityEvent} eventName - The name of the event.
|
||||
* @param {Script~entityEventCallback|Script~pointerEventCallback|Script~collisionEventCallback} handler - The function to
|
||||
* call when the event occurs on the entity. It can be either the name of a function or an in-line definition.
|
||||
* @example <caption>Report when a mouse press occurs on a particular entity.</caption>
|
||||
* var entityID = Entities.addEntity({
|
||||
* type: "Box",
|
||||
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
|
||||
* dimensions: { x: 0.5, y: 0.5, z: 0.5 },
|
||||
* lifetime: 300 // Delete after 5 minutes.
|
||||
* });
|
||||
*
|
||||
* function reportMousePress(entityID, event) {
|
||||
* print("Mouse pressed on entity: " + JSON.stringify(event));
|
||||
* }
|
||||
*
|
||||
* Script.addEventHandler(entityID, "mousePressOnEntity", reportMousePress);
|
||||
*/
|
||||
Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, const ScriptValue& handler) { _manager->addEventHandler(entityID, eventName, handler); }
|
||||
|
||||
/**jsdoc
|
||||
* Removes a function from the list of functions called when an entity event occurs on a particular entity.
|
||||
* <p>See also, the {@link Entities} API.</p>
|
||||
* @function Script.removeEventHandler
|
||||
* @param {Uuid} entityID - The ID of the entity.
|
||||
* @param {Script.EntityEvent} eventName - The name of the entity event.
|
||||
* @param {function} handler - The name of the function to no longer call when the entity event occurs on the entity.
|
||||
*/
|
||||
Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, const ScriptValue& handler) { _manager->removeEventHandler(entityID, eventName, handler); }
|
||||
|
||||
/**jsdoc
|
||||
* Starts running another script in Interface, if it isn't already running. The script is not automatically loaded next
|
||||
* time Interface starts.
|
||||
* <p class="availableIn"><strong>Supported Script Types:</strong> Interface Scripts • Avatar Scripts</p>
|
||||
* <p>See also, {@link ScriptDiscoveryService.loadScript}.</p>
|
||||
* @function Script.load
|
||||
* @param {string} filename - The URL of the script to load. This can be relative to the current script's URL.
|
||||
* @example <caption>Load a script from another script.</caption>
|
||||
* // First file: scriptA.js
|
||||
* print("This is script A");
|
||||
*
|
||||
* // Second file: scriptB.js
|
||||
* print("This is script B");
|
||||
* Script.load("scriptA.js");
|
||||
*
|
||||
* // If you run scriptB.js you should see both scripts in the Running Scripts dialog.
|
||||
* // And you should see the following output:
|
||||
* // This is script B
|
||||
* // This is script A
|
||||
*/
|
||||
Q_INVOKABLE void load(const QString& loadfile) { _manager->load(loadfile); }
|
||||
|
||||
/**jsdoc
|
||||
* Includes JavaScript from other files in the current script. If a callback is specified, the files are loaded and
|
||||
* included asynchronously, otherwise they are included synchronously (i.e., script execution blocks while the files are
|
||||
* included).
|
||||
* @function Script.include
|
||||
* @variation 0
|
||||
* @param {string[]} filenames - The URLs of the scripts to include. Each can be relative to the current script.
|
||||
* @param {function} [callback=null] - The function to call back when the scripts have been included. It can be either the
|
||||
* name of a function or an in-line definition.
|
||||
*/
|
||||
Q_INVOKABLE void include(const QStringList& includeFiles, const ScriptValue& callback = ScriptValue()) { _manager->include(includeFiles, callback);};
|
||||
|
||||
/**jsdoc
|
||||
* Includes JavaScript from another file in the current script. If a callback is specified, the file is loaded and included
|
||||
* asynchronously, otherwise it is included synchronously (i.e., script execution blocks while the file is included).
|
||||
* @function Script.include
|
||||
* @param {string} filename - The URL of the script to include. It can be relative to the current script.
|
||||
* @param {function} [callback=null] - The function to call back when the script has been included. It can be either the
|
||||
* name of a function or an in-line definition.
|
||||
* @example <caption>Include a script file asynchronously.</caption>
|
||||
* // First file: scriptA.js
|
||||
* print("This is script A");
|
||||
*
|
||||
* // Second file: scriptB.js
|
||||
* print("This is script B");
|
||||
* Script.include("scriptA.js", function () {
|
||||
* print("Script A has been included");
|
||||
* });
|
||||
*
|
||||
* // If you run scriptB.js you should see only scriptB.js in the running scripts list.
|
||||
* // And you should see the following output:
|
||||
* // This is script B
|
||||
* // This is script A
|
||||
* // Script A has been included
|
||||
*/
|
||||
Q_INVOKABLE void include(const QString& includeFile, const ScriptValue& callback = ScriptValue()) { _manager->include( includeFile, callback); };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MODULE related methods
|
||||
|
||||
/**jsdoc
|
||||
* Provides access to methods or objects provided in an external JavaScript or JSON file.
|
||||
* See {@link https://docs.overte.org/script/js-tips.html} for further details.
|
||||
* @function Script.require
|
||||
* @param {string} module - The module to use. May be a JavaScript file, a JSON file, or the name of a system module such
|
||||
* as <code>"appUi"</code> (i.e., the "appUi.js" system module JavaScript file).
|
||||
* @returns {object|array} The value assigned to <code>module.exports</code> in the JavaScript file, or the value defined
|
||||
* in the JSON file.
|
||||
*/
|
||||
Q_INVOKABLE ScriptValue require(const QString& moduleId) { return _manager->require(moduleId); }
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.resetModuleCache
|
||||
* @param {boolean} [deleteScriptCache=false] - Delete script cache.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void resetModuleCache(bool deleteScriptCache = false) { _manager->resetModuleCache(deleteScriptCache);}
|
||||
|
||||
/**jsdoc
|
||||
* Calls a function repeatedly, at a set interval.
|
||||
* @function Script.setInterval
|
||||
* @param {function} function - The function to call. This can be either the name of a function or an in-line definition.
|
||||
* @param {number} interval - The interval at which to call the function, in ms.
|
||||
* @returns {object} A handle to the interval timer. This can be used in {@link Script.clearInterval}.
|
||||
* @example <caption>Print a message every second.</caption>
|
||||
* Script.setInterval(function () {
|
||||
* print("Interval timer fired");
|
||||
* }, 1000);
|
||||
*/
|
||||
Q_INVOKABLE QTimer* setInterval(const ScriptValue& function, int intervalMS) { return _manager->setInterval(function, intervalMS); }
|
||||
|
||||
/**jsdoc
|
||||
* Calls a function once, after a delay.
|
||||
* @function Script.setTimeout
|
||||
* @param {function} function - The function to call. This can be either the name of a function or an in-line definition.
|
||||
* @param {number} timeout - The delay after which to call the function, in ms.
|
||||
* @returns {object} A handle to the timeout timer. This can be used in {@link Script.clearTimeout}.
|
||||
* @example <caption>Print a message once, after a second.</caption>
|
||||
* Script.setTimeout(function () {
|
||||
* print("Timeout timer fired");
|
||||
* }, 1000);
|
||||
*/
|
||||
Q_INVOKABLE QTimer* setTimeout(const ScriptValue& function, int timeoutMS) { return _manager->setTimeout(function, timeoutMS); };
|
||||
|
||||
/**jsdoc
|
||||
* Stops an interval timer set by {@link Script.setInterval|setInterval}.
|
||||
* @function Script.clearInterval
|
||||
* @param {object} timer - The interval timer to stop.
|
||||
* @example <caption>Stop an interval timer.</caption>
|
||||
* // Print a message every second.
|
||||
* var timer = Script.setInterval(function () {
|
||||
* print("Interval timer fired");
|
||||
* }, 1000);
|
||||
*
|
||||
* // Stop the timer after 10 seconds.
|
||||
* Script.setTimeout(function () {
|
||||
* print("Stop interval timer");
|
||||
* Script.clearInterval(timer);
|
||||
* }, 10000);
|
||||
*/
|
||||
Q_INVOKABLE void clearInterval(QTimer* timer) { _manager->clearInterval(timer); }
|
||||
|
||||
// Overloaded version is needed in case the timer has expired
|
||||
Q_INVOKABLE void clearInterval(QVariantMap timer) { ; }
|
||||
|
||||
/**jsdoc
|
||||
* Stops a timeout timer set by {@link Script.setTimeout|setTimeout}.
|
||||
* @function Script.clearTimeout
|
||||
* @param {object} timer - The timeout timer to stop.
|
||||
* @example <caption>Stop a timeout timer.</caption>
|
||||
* // Print a message after two seconds.
|
||||
* var timer = Script.setTimeout(function () {
|
||||
* print("Timer fired");
|
||||
* }, 2000);
|
||||
*
|
||||
* // Uncomment the following line to stop the timer from firing.
|
||||
* //Script.clearTimeout(timer);
|
||||
*/
|
||||
Q_INVOKABLE void clearTimeout(QTimer* timer) { _manager->clearTimeout(timer); }
|
||||
|
||||
// Overloaded version is needed in case the timer has expired
|
||||
Q_INVOKABLE void clearTimeout(QVariantMap timer) { ; }
|
||||
|
||||
/**jsdoc
|
||||
* Prints a message to the program log and emits {@link Script.printedMessage}.
|
||||
* <p>Alternatively, you can use {@link print} or one of the {@link console} API methods.</p>
|
||||
* @function Script.print
|
||||
* @param {string} message - The message to print.
|
||||
*/
|
||||
Q_INVOKABLE void print(const QString& message) { _manager->print(message); }
|
||||
|
||||
/**jsdoc
|
||||
* Resolves a relative path to an absolute path. The relative path is relative to the script's location.
|
||||
* @function Script.resolvePath
|
||||
* @param {string} path - The relative path to resolve.
|
||||
* @returns {string} The absolute path.
|
||||
* @example <caption>Report the directory and filename of the running script.</caption>
|
||||
* print(Script.resolvePath(""));
|
||||
* @example <caption>Report the directory of the running script.</caption>
|
||||
* print(Script.resolvePath("."));
|
||||
* @example <caption>Report the path to a file located relative to the running script.</caption>
|
||||
* print(Script.resolvePath("../assets/sounds/hello.wav"));
|
||||
*/
|
||||
Q_INVOKABLE QUrl resolvePath(const QString& path) const { return _manager->resolvePath(path);}
|
||||
|
||||
/**jsdoc
|
||||
* Gets the path to the resources directory for QML files.
|
||||
* @function Script.resourcesPath
|
||||
* @returns {string} The path to the resources directory for QML files.
|
||||
*/
|
||||
Q_INVOKABLE QUrl resourcesPath() const { return _manager->resourcesPath(); }
|
||||
|
||||
/**jsdoc
|
||||
* Starts timing a section of code in order to send usage data about it to Vircadia. Shouldn't be used outside of the
|
||||
* standard scripts.
|
||||
* @function Script.beginProfileRange
|
||||
* @param {string} label - A name that identifies the section of code.
|
||||
*/
|
||||
Q_INVOKABLE void beginProfileRange(const QString& label) const { _manager->beginProfileRange(label); }
|
||||
|
||||
/**jsdoc
|
||||
* Finishes timing a section of code in order to send usage data about it to Vircadia. Shouldn't be used outside of
|
||||
* the standard scripts.
|
||||
* @function Script.endProfileRange
|
||||
* @param {string} label - A name that identifies the section of code.
|
||||
*/
|
||||
Q_INVOKABLE void endProfileRange(const QString& label) const { _manager->endProfileRange(label); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Entity Script Related methods
|
||||
|
||||
/**jsdoc
|
||||
* Checks whether an entity has an entity script running.
|
||||
* @function Script.isEntityScriptRunning
|
||||
* @param {Uuid} entityID - The ID of the entity.
|
||||
* @returns {boolean} <code>true</code> if the entity has an entity script running, <code>false</code> if it doesn't.
|
||||
*/
|
||||
Q_INVOKABLE bool isEntityScriptRunning(const EntityItemID& entityID) { return _manager->isEntityScriptRunning(entityID); }
|
||||
|
||||
/**jsdoc
|
||||
* Manually runs the JavaScript garbage collector which reclaims memory by disposing of objects that are no longer
|
||||
* reachable.
|
||||
* @function Script.requestGarbageCollection
|
||||
*/
|
||||
Q_INVOKABLE void requestGarbageCollection() { _manager->requestGarbageCollection(); }
|
||||
|
||||
/**jsdoc
|
||||
* Prints out current backtrace to the log.
|
||||
* @function Script.logBacktrace
|
||||
* @param {string} title - Title added to the printed out backtrace.
|
||||
*/
|
||||
Q_INVOKABLE void logBacktrace(const QString &title) { _manager->logBacktrace(title); }
|
||||
|
||||
/*@jsdoc
|
||||
* @function Script.loadEntityScript
|
||||
* @param {Uuid} entityID - Entity ID.
|
||||
* @param {string} script - Script.
|
||||
* @param {boolean} forceRedownload - Force re-download.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void loadEntityScript(const EntityItemID& entityID, const QString& entityScript, bool forceRedownload) { _manager->loadEntityScript(entityID, entityScript, forceRedownload); }
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.unloadEntityScript
|
||||
* @param {Uuid} entityID - Entity ID.
|
||||
* @param {boolean} [shouldRemoveFromMap=false] - Should remove from map.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap = false) { _manager->unloadEntityScript(entityID, shouldRemoveFromMap); }
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.unloadAllEntityScripts
|
||||
* @param {boolean} [blockingCall=false] - Wait for completion if call moved to another thread.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void unloadAllEntityScripts(bool blockingCall = false) { _manager->unloadAllEntityScripts(blockingCall); }
|
||||
|
||||
/**jsdoc
|
||||
* Calls a method in an entity script.
|
||||
* @function Script.callEntityScriptMethod
|
||||
* @param {Uuid} entityID - The ID of the entity running the entity script.
|
||||
* @param {string} methodName - The name of the method to call.
|
||||
* @param {string[]} [parameters=[]] - The parameters to call the specified method with.
|
||||
* @param {Uuid} [remoteCallerID=Uuid.NULL] - An ID that identifies the caller.
|
||||
*/
|
||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName,
|
||||
const QStringList& params = QStringList(),
|
||||
const QUuid& remoteCallerID = QUuid()) { _manager->callEntityScriptMethod(entityID, methodName, params, remoteCallerID); }
|
||||
|
||||
/**jsdoc
|
||||
* Calls a method in an entity script.
|
||||
* @function Script.callEntityScriptMethod
|
||||
* @param {Uuid} entityID - Entity ID.
|
||||
* @param {string} methodName - Method name.
|
||||
* @param {PointerEvent} event - Pointer event.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const PointerEvent& event) { _manager->callEntityScriptMethod(entityID, methodName, event); }
|
||||
|
||||
/**jsdoc
|
||||
* Calls a method in an entity script.
|
||||
* @function Script.callEntityScriptMethod
|
||||
* @param {Uuid} entityID - Entity ID.
|
||||
* @param {string} methodName - Method name.
|
||||
* @param {Uuid} otherID - Other entity ID.
|
||||
* @param {Collision} collision - Collision.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision) { _manager->callEntityScriptMethod(entityID, methodName, otherID, collision);}
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.generateUUID
|
||||
* @returns {Uuid} A new UUID.
|
||||
* @deprecated This function is deprecated and will be removed. Use {@link Uuid(0).generate|Uuid.generate} instead.
|
||||
*/
|
||||
Q_INVOKABLE QUuid generateUUID() { return QUuid::createUuid(); }
|
||||
|
||||
/**jsdoc
|
||||
* Gets the URL for an asset in an external resource bucket. (The location where the bucket is hosted may change over time
|
||||
* but this method will return the asset's current URL.)
|
||||
* @function Script.getExternalPath
|
||||
* @param {Script.ResourceBucket} bucket - The external resource bucket that the asset is in.
|
||||
* @param {string} path - The path within the external resource bucket where the asset is located.
|
||||
* <p>Normally, this should start with a path or filename to be appended to the bucket URL.
|
||||
* Alternatively, it can be a relative path starting with <code>./</code> or <code>../</code>, to navigate within the
|
||||
* resource bucket's URL.</p>
|
||||
* @Returns {string} The URL of an external asset.
|
||||
* @example <caption>Report the URL of a default particle.</caption>
|
||||
* print(Script.getExternalPath(Script.ExternalPaths.Assets, "Bazaar/Assets/Textures/Defaults/Interface/default_particle.png"));
|
||||
* @example <caption>Report the root directory where the Vircadia assets are located.</caption>
|
||||
* print(Script.getExternalPath(Script.ExternalPaths.Assets, "."));
|
||||
*/
|
||||
Q_INVOKABLE QString getExternalPath(ExternalResource::Bucket bucket, const QString& path) { return _manager->getExternalPath(bucket, path); }
|
||||
|
||||
signals:
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.scriptLoaded
|
||||
* @param {string} filename - File name.
|
||||
* @returns {Signal}
|
||||
* @deprecated This signal is deprecated and will be removed.
|
||||
*/
|
||||
void scriptLoaded(const QString& scriptFilename);
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.errorLoadingScript
|
||||
* @param {string} filename - File name.
|
||||
* @returns {Signal}
|
||||
* @deprecated This signal is deprecated and will be removed.
|
||||
*/
|
||||
void errorLoadingScript(const QString& scriptFilename);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered frequently at a system-determined interval.
|
||||
* @function Script.update
|
||||
* @param {number} deltaTime - The time since the last update, in s.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report script update intervals.</caption>
|
||||
* Script.update.connect(function (deltaTime) {
|
||||
* print("Update: " + deltaTime);
|
||||
* });
|
||||
*/
|
||||
void update(float deltaTime);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script is stopping.
|
||||
* @function Script.scriptEnding
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report when a script is stopping.</caption>
|
||||
* print("Script started");
|
||||
*
|
||||
* Script.scriptEnding.connect(function () {
|
||||
* print("Script ending");
|
||||
* });
|
||||
*
|
||||
* Script.setTimeout(function () {
|
||||
* print("Stopping script");
|
||||
* Script.stop();
|
||||
* }, 1000);
|
||||
*/
|
||||
void scriptEnding();
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.finished
|
||||
* @param {string} filename - File name.
|
||||
* @param {object} engine - Engine.
|
||||
* @returns {Signal}
|
||||
* @deprecated This signal is deprecated and will be removed.
|
||||
*/
|
||||
void finished(const QString& fileNameString, ScriptManagerPointer);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script prints a message to the program log via {@link print}, {@link Script.print},
|
||||
* {@link console.log}, {@link console.debug}, {@link console.group}, {@link console.groupEnd}, {@link console.time}, or
|
||||
* {@link console.timeEnd}.
|
||||
* @function Script.printedMessage
|
||||
* @param {string} message - The message.
|
||||
* @param {string} scriptName - The name of the script that generated the message.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void printedMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script generates an error, {@link console.error} or {@link console.exception} is called, or
|
||||
* {@link console.assert} is called and fails.
|
||||
* @function Script.errorMessage
|
||||
* @param {string} message - The error message.
|
||||
* @param {string} scriptName - The name of the script that generated the error message.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void errorMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script generates a warning or {@link console.warn} is called.
|
||||
* @function Script.warningMessage
|
||||
* @param {string} message - The warning message.
|
||||
* @param {string} scriptName - The name of the script that generated the warning message.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void warningMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script generates an information message or {@link console.info} is called.
|
||||
* @function Script.infoMessage
|
||||
* @param {string} message - The information message.
|
||||
* @param {string} scriptName - The name of the script that generated the information message.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void infoMessage(const QString& message, const QString& scriptName);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the running state of the script changes, e.g., from running to stopping.
|
||||
* @function Script.runningStateChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void runningStateChanged();
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.clearDebugWindow
|
||||
* @returns {Signal}
|
||||
* @deprecated This signal is deprecated and will be removed.
|
||||
*/
|
||||
void clearDebugWindow();
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.loadScript
|
||||
* @param {string} scriptName - Script name.
|
||||
* @param {boolean} isUserLoaded - Is user loaded.
|
||||
* @returns {Signal}
|
||||
* @deprecated This signal is deprecated and will be removed.
|
||||
*/
|
||||
void loadScript(const QString& scriptName, bool isUserLoaded);
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.reloadScript
|
||||
* @param {string} scriptName - Script name.
|
||||
* @param {boolean} isUserLoaded - Is user loaded.
|
||||
* @returns {Signal}
|
||||
* @deprecated This signal is deprecated and will be removed.
|
||||
*/
|
||||
void reloadScript(const QString& scriptName, bool isUserLoaded);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script has stopped.
|
||||
* @function Script.doneRunning
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void doneRunning();
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.entityScriptDetailsUpdated
|
||||
* @returns {Signal}
|
||||
* @deprecated This signal is deprecated and will be removed.
|
||||
*/
|
||||
// Emitted when an entity script is added or removed, or when the status of an entity
|
||||
// script is updated (goes from RUNNING to ERROR_RUNNING_SCRIPT, for example)
|
||||
void entityScriptDetailsUpdated();
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script starts for the user. See also, {@link Entities.preload}.
|
||||
* <p class="availableIn"><strong>Supported Script Types:</strong> Client Entity Scripts • Server Entity Scripts</p>
|
||||
* @function Script.entityScriptPreloadFinished
|
||||
* @param {Uuid} entityID - The ID of the entity that the script is running in.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Get the ID of the entity that a client entity script is running in.</caption>
|
||||
* var entityScript = function () {
|
||||
* this.entityID = Uuid.NULL;
|
||||
* };
|
||||
*
|
||||
* Script.entityScriptPreloadFinished.connect(function (entityID) {
|
||||
* this.entityID = entityID;
|
||||
* print("Entity ID: " + this.entityID);
|
||||
* });
|
||||
*
|
||||
* var entityID = Entities.addEntity({
|
||||
* type: "Box",
|
||||
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
|
||||
* dimensions: { x: 0.5, y: 0.5, z: 0.5 },
|
||||
* color: { red: 255, green: 0, blue: 0 },
|
||||
* script: "(" + entityScript + ")", // Could host the script on a Web server instead.
|
||||
* lifetime: 300 // Delete after 5 minutes.
|
||||
* });
|
||||
*/
|
||||
// Emitted when an entity script has finished running preload
|
||||
void entityScriptPreloadFinished(const EntityItemID& entityID);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when a script generates an unhandled exception.
|
||||
* @function Script.unhandledException
|
||||
* @param {object} exception - The details of the exception.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report the details of an unhandled exception.</caption>
|
||||
* Script.unhandledException.connect(function (exception) {
|
||||
* print("Unhandled exception: " + JSON.stringify(exception));
|
||||
* });
|
||||
* var properties = JSON.parse("{ x: 1"); // Invalid JSON string.
|
||||
*/
|
||||
void unhandledException(const ScriptValue& exception);
|
||||
|
||||
|
||||
protected:
|
||||
/**jsdoc
|
||||
* @function Script.executeOnScriptThread
|
||||
* @param {function} function - Function.
|
||||
* @param {ConnectionType} [type=2] - Connection type.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void executeOnScriptThread(std::function<void()> function, const Qt::ConnectionType& type = Qt::QueuedConnection ) { _manager->executeOnScriptThread(function, type);}
|
||||
|
||||
/**jsdoc
|
||||
* @function Script._requireResolve
|
||||
* @param {string} module - Module.
|
||||
* @param {string} [relativeTo=""] - Relative to.
|
||||
* @returns {string} Result.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
// note: this is not meant to be called directly, but just to have QMetaObject take care of wiring it up in general;
|
||||
// then inside of init() we just have to do "Script.require.resolve = Script._requireResolve;"
|
||||
Q_INVOKABLE QString _requireResolve(const QString& moduleId, const QString& relativeTo = QString()) { return _manager->_requireResolve(moduleId, relativeTo); }
|
||||
|
||||
/**jsdoc
|
||||
* @function Script.entityScriptContentAvailable
|
||||
* @param {Uuid} entityID - Entity ID.
|
||||
* @param {string} scriptOrURL - Path.
|
||||
* @param {string} contents - Contents.
|
||||
* @param {boolean} isURL - Is a URL.
|
||||
* @param {boolean} success - Success.
|
||||
* @param {string} status - Status.
|
||||
* @deprecated This function is deprecated and will be removed.
|
||||
*/
|
||||
Q_INVOKABLE void entityScriptContentAvailable(const EntityItemID& entityID, const QString& scriptOrURL, const QString& contents, bool isURL, bool success, const QString& status)
|
||||
{ _manager->entityScriptContentAvailable(entityID, scriptOrURL, contents, isURL, success, status); }
|
||||
|
||||
|
||||
private:
|
||||
ScriptManager *_manager;
|
||||
};
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Created by Heather Anderson on 5/2/21.
|
||||
// Copyright 2021 Vircadia contributors.
|
||||
// Copyright 2023 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
@ -22,32 +23,93 @@ class ScriptSyntaxCheckResult;
|
|||
using ScriptProgramPointer = std::shared_ptr<ScriptProgram>;
|
||||
using ScriptSyntaxCheckResultPointer = std::shared_ptr<ScriptSyntaxCheckResult>;
|
||||
|
||||
/// [ScriptInterface] Provides an engine-independent interface for QScriptProgram
|
||||
/**
|
||||
* @brief Engine-independent representation of a script program
|
||||
*
|
||||
* This is an analog of QScriptProgram from Qt5.
|
||||
*
|
||||
* It's used to pre-compile scripts, and to check their syntax.
|
||||
*
|
||||
*/
|
||||
class ScriptProgram {
|
||||
public:
|
||||
virtual ScriptSyntaxCheckResultPointer checkSyntax() = 0; //It cannot be const anymore because V8 doesn't have separate syntax checking function
|
||||
|
||||
/**
|
||||
* @brief Returns the filename associated with this program.
|
||||
*
|
||||
* @return QString
|
||||
*/
|
||||
virtual QString fileName() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the source code of this program.
|
||||
*
|
||||
* @return QString
|
||||
*/
|
||||
virtual QString sourceCode() const = 0;
|
||||
|
||||
protected:
|
||||
~ScriptProgram() {} // prevent explicit deletion of base class
|
||||
};
|
||||
|
||||
/// [ScriptInterface] Provides an engine-independent interface for QScriptSyntaxCheckResult
|
||||
|
||||
/**
|
||||
* @brief Engine-independent representation of a script syntax check
|
||||
*
|
||||
* This is an analog of QScriptSyntaxCheckResult from Qt5.
|
||||
*
|
||||
*
|
||||
*/
|
||||
class ScriptSyntaxCheckResult {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief State of the syntax check
|
||||
*
|
||||
*/
|
||||
enum State
|
||||
{
|
||||
Error = 0,
|
||||
Intermediate = 1,
|
||||
Valid = 2
|
||||
Error = 0, /** The program contains a syntax error. */
|
||||
Intermediate = 1, /** The program is incomplete. */
|
||||
Valid = 2 /** The program is a syntactically correct program. */
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Returns the error column number of this ScriptSyntaxCheckResult, or -1 if there is no error.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
virtual int errorColumnNumber() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the error line number of this ScriptSyntaxCheckResult, or -1 if there is no error.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
virtual int errorLineNumber() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the error message of this ScriptSyntaxCheckResult, or an empty string if there is no error.
|
||||
*
|
||||
* @return QString
|
||||
*/
|
||||
virtual QString errorMessage() const = 0;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @return QString
|
||||
*/
|
||||
virtual QString errorBacktrace() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the state of this ScriptSyntaxCheckResult.
|
||||
*
|
||||
* @return State
|
||||
*/
|
||||
virtual State state() const = 0;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include "ScriptEngineV8.h"
|
||||
#include "V8Types.h"
|
||||
|
||||
|
||||
// V8TODO: This class is likely unnecessary, and it'd be enough
|
||||
// to just use a non-abstract version of ScriptSyntaxCheckResult instead.
|
||||
class ScriptSyntaxCheckResultV8Wrapper final : public ScriptSyntaxCheckResult {
|
||||
public: // construction
|
||||
inline ScriptSyntaxCheckResultV8Wrapper() : _errorColumnNumber(0), _errorLineNumber(0), _errorMessage("Not compiled"), _state(ScriptSyntaxCheckResult::Error) {}
|
||||
|
|
|
@ -102,4 +102,6 @@ void ScriptEngineTests::scriptTest() {
|
|||
//ac->shutdownScripting();
|
||||
|
||||
|
||||
|
||||
//TODO: Add a test for Script.require(JSON)
|
||||
}
|
||||
|
|
|
@ -973,7 +973,12 @@ EXCLUDE_SYMLINKS = NO
|
|||
# Note that the wildcards are matched against the file with absolute path, so to
|
||||
# exclude all test directories for example use the pattern */test/*
|
||||
|
||||
EXCLUDE_PATTERNS =
|
||||
|
||||
# The ScriptingInterface files are a JS interface, and documented in JSDoc
|
||||
# instead of Doxygen.
|
||||
|
||||
EXCLUDE_PATTERNS = *ScriptingInterface.h \
|
||||
*ScriptingInterface.cpp
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||
|
@ -2354,7 +2359,7 @@ DIA_PATH =
|
|||
# and usage relations if the target is undocumented or is not a class.
|
||||
# The default value is: YES.
|
||||
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HIDE_UNDOC_RELATIONS = NO
|
||||
|
||||
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
||||
# available from the path. This tool is part of Graphviz (see:
|
||||
|
@ -2363,7 +2368,7 @@ HIDE_UNDOC_RELATIONS = YES
|
|||
# set to NO
|
||||
# The default value is: NO.
|
||||
|
||||
HAVE_DOT = NO
|
||||
HAVE_DOT = YES
|
||||
|
||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
||||
# to run in parallel. When set to 0 doxygen will base this on the number of
|
||||
|
@ -2545,7 +2550,7 @@ DIRECTORY_GRAPH = YES
|
|||
# The default value is: png.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_IMAGE_FORMAT = svg
|
||||
|
||||
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
|
||||
# enable generation of interactive SVG images that allow zooming and panning.
|
||||
|
@ -2557,7 +2562,7 @@ DOT_IMAGE_FORMAT = png
|
|||
# The default value is: NO.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
INTERACTIVE_SVG = NO
|
||||
INTERACTIVE_SVG = YES
|
||||
|
||||
# The DOT_PATH tag can be used to specify the path where the dot tool can be
|
||||
# found. If left blank, it is assumed the dot tool can be found in the path.
|
||||
|
|
Loading…
Reference in a new issue