Server side entity script messages

This commit is contained in:
ksuprynowicz 2023-12-29 20:28:54 +01:00
parent 274867bc47
commit dfbc1d8865
11 changed files with 252 additions and 75 deletions

View file

@ -44,16 +44,8 @@
using Mutex = std::mutex;
using Lock = std::lock_guard<Mutex>;
static std::mutex logBufferMutex;
static std::string logBuffer;
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
auto logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message);
if (!logMessage.isEmpty()) {
Lock lock(logBufferMutex);
logBuffer.append(logMessage.toStdString() + '\n');
}
}
int EntityScriptServer::_entitiesScriptEngineCount = 0;
@ -217,10 +209,10 @@ void EntityScriptServer::handleEntityServerScriptLogPacket(QSharedPointer<Receiv
}
void EntityScriptServer::pushLogs() {
std::string buffer;
QJsonArray buffer;
{
Lock lock(logBufferMutex);
std::swap(logBuffer, buffer);
Lock lock(_logBufferMutex);
std::swap(_logBuffer, buffer);
}
if (buffer.empty()) {
@ -231,16 +223,25 @@ void EntityScriptServer::pushLogs() {
}
auto nodeList = DependencyManager::get<NodeList>();
QJsonDocument document;
document.setArray(buffer);
QString data(document.toJson());
for (auto uuid : _logListeners) {
auto node = nodeList->nodeWithUUID(uuid);
if (node && node->getActiveSocket()) {
auto packet = NLPacketList::create(PacketType::EntityServerScriptLog, QByteArray(), true, true);
packet->write(buffer.data(), buffer.size());
packet->write(data.toStdString().c_str(), data.size());
nodeList->sendPacketList(std::move(packet), *node);
}
}
}
void EntityScriptServer::addLogEntry(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, ScriptMessage::Severity severity) {
ScriptMessage entry(message, fileName, lineNumber, entityID, ScriptMessage::ScriptType::TYPE_ENTITY_SCRIPT, severity);
Lock lock(_logBufferMutex);
_logBuffer.append(entry.toJson());
}
void EntityScriptServer::handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode) {
if (_entitiesScriptManager && _entityViewer.getTree() && !_shuttingDown) {
@ -469,6 +470,29 @@ void EntityScriptServer::resetEntitiesScriptEngine() {
connect(newManager.get(), &ScriptManager::warningMessage, scriptEngines, &ScriptEngines::onWarningMessage);
connect(newManager.get(), &ScriptManager::infoMessage, scriptEngines, &ScriptEngines::onInfoMessage);
// Make script engine messages available through ScriptDiscoveryService
connect(newManager.get(), &ScriptManager::infoEntityMessage, scriptEngines, &ScriptEngines::infoEntityMessage);
connect(newManager.get(), &ScriptManager::printedEntityMessage, scriptEngines, &ScriptEngines::printedEntityMessage);
connect(newManager.get(), &ScriptManager::errorEntityMessage, scriptEngines, &ScriptEngines::errorEntityMessage);
connect(newManager.get(), &ScriptManager::warningEntityMessage, scriptEngines, &ScriptEngines::warningEntityMessage);
connect(newManager.get(), &ScriptManager::infoEntityMessage,
[this](const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID) {
addLogEntry(message, fileName, lineNumber, entityID, ScriptMessage::Severity::SEVERITY_INFO);
});
connect(newManager.get(), &ScriptManager::printedEntityMessage,
[this](const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID) {
addLogEntry(message, fileName, lineNumber, entityID, ScriptMessage::Severity::SEVERITY_PRINT);
});
connect(newManager.get(), &ScriptManager::errorEntityMessage,
[this](const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID) {
addLogEntry(message, fileName, lineNumber, entityID, ScriptMessage::Severity::SEVERITY_ERROR);
});
connect(newManager.get(), &ScriptManager::warningEntityMessage,
[this](const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID) {
addLogEntry(message, fileName, lineNumber, entityID, ScriptMessage::Severity::SEVERITY_WARNING);
});
connect(newManager.get(), &ScriptManager::update, this, [this] {
_entityViewer.queryOctree();
_entityViewer.getTree()->preUpdate();

View file

@ -27,6 +27,8 @@
#include <SimpleEntitySimulation.h>
#include <ThreadedAssignment.h>
#include <ScriptManager.h>
#include <ScriptMessage.h>
#include <QJsonArray>
#include "../entities/EntityTreeHeadlessViewer.h"
@ -55,10 +57,32 @@ private slots:
void handleSettings();
void updateEntityPPS();
/**
* @brief Handles log subscribe/unsubscribe requests
*
* Clients can subscribe to logs by sending a script log packet. Entity Script Server keeps list of subscribers
* and sends them logs in JSON format.
*/
void handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
/**
* @brief Transmit logs
*
* This is called periodically through a timer to transmit logs from scripts.
*/
void pushLogs();
/**
* @brief Adds log entry to the transmit buffer
*
* This is connected to entity script log events in the script manager and adds script log message to the buffer
* containing messages that will be sent to subscribed clients.
*/
void addLogEntry(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, ScriptMessage::Severity severity);
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
@ -85,6 +109,9 @@ private:
EntityEditPacketSender _entityEditSender;
EntityTreeHeadlessViewer _entityViewer;
QJsonArray _logBuffer;
std::mutex _logBufferMutex;
int _maxEntityPPS { DEFAULT_MAX_ENTITY_PPS };
int _entityPPSPerScript { DEFAULT_ENTITY_PPS_PER_SCRIPT };

View file

@ -232,6 +232,14 @@ void EntityTreeRenderer::resetPersistentEntitiesScriptEngine() {
_persistentEntitiesScriptManager = scriptManagerFactory(ScriptManager::ENTITY_CLIENT_SCRIPT, NO_SCRIPT,
QString("about:Entities %1").arg(++_entitiesScriptEngineCount));
DependencyManager::get<ScriptEngines>()->runScriptInitializers(_persistentEntitiesScriptManager);
// Make script engine messages available through ScriptDiscoveryService
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
connect(_persistentEntitiesScriptManager.get(), &ScriptManager::infoEntityMessage, scriptEngines, &ScriptEngines::infoEntityMessage);
connect(_persistentEntitiesScriptManager.get(), &ScriptManager::printedEntityMessage, scriptEngines, &ScriptEngines::printedEntityMessage);
connect(_persistentEntitiesScriptManager.get(), &ScriptManager::errorEntityMessage, scriptEngines, &ScriptEngines::errorEntityMessage);
connect(_persistentEntitiesScriptManager.get(), &ScriptManager::warningEntityMessage, scriptEngines, &ScriptEngines::warningEntityMessage);
_persistentEntitiesScriptManager->runInThread();
std::shared_ptr<EntitiesScriptEngineProvider> entitiesScriptEngineProvider = _persistentEntitiesScriptManager;
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
@ -255,6 +263,14 @@ void EntityTreeRenderer::resetNonPersistentEntitiesScriptEngine() {
_nonPersistentEntitiesScriptManager = scriptManagerFactory(ScriptManager::ENTITY_CLIENT_SCRIPT, NO_SCRIPT,
QString("about:Entities %1").arg(++_entitiesScriptEngineCount));
DependencyManager::get<ScriptEngines>()->runScriptInitializers(_nonPersistentEntitiesScriptManager);
// Make script engine messages available through ScriptDiscoveryService
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
connect(_nonPersistentEntitiesScriptManager.get(), &ScriptManager::infoEntityMessage, scriptEngines, &ScriptEngines::infoEntityMessage);
connect(_nonPersistentEntitiesScriptManager.get(), &ScriptManager::printedEntityMessage, scriptEngines, &ScriptEngines::printedEntityMessage);
connect(_nonPersistentEntitiesScriptManager.get(), &ScriptManager::errorEntityMessage, scriptEngines, &ScriptEngines::errorEntityMessage);
connect(_nonPersistentEntitiesScriptManager.get(), &ScriptManager::warningEntityMessage, scriptEngines, &ScriptEngines::warningEntityMessage);
_nonPersistentEntitiesScriptManager->runInThread();
std::shared_ptr<EntitiesScriptEngineProvider> entitiesScriptEngineProvider = _nonPersistentEntitiesScriptManager;
DependencyManager::get<EntityScriptingInterface>()->setNonPersistentEntitiesScriptEngine(entitiesScriptEngineProvider);

View file

@ -9,7 +9,11 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <QJsonDocument>
#include <QJsonArray>
#include "EntityScriptServerLogClient.h"
#include "ScriptMessage.h"
#include "ScriptEngines.h"
EntityScriptServerLogClient::EntityScriptServerLogClient() {
auto nodeList = DependencyManager::get<NodeList>();
@ -62,7 +66,59 @@ void EntityScriptServerLogClient::enableToEntityServerScriptLog(bool enable) {
}
void EntityScriptServerLogClient::handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
emit receivedNewLogLines(QString::fromUtf8(message->readAll()));
QString messageText = QString::fromUtf8(message->readAll());
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(messageText.toUtf8(), &error);
emit receivedNewLogLines(messageText);
if(document.isNull()) {
qWarning() << "EntityScriptServerLogClient::handleEntityServerScriptLogPacket: Cannot parse JSON: " << error.errorString()
<< " Contents: " << messageText;
return;
}
// Iterate through contents and emit messages
if(!document.isArray()) {
qWarning() << "EntityScriptServerLogClient::handleEntityServerScriptLogPacket: JSON is not an array: " << messageText;
return;
}
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
auto array = document.array();
for (int n = 0; n < array.size(); n++) {
if (!array[n].isObject()) {
qWarning() << "EntityScriptServerLogClient::handleEntityServerScriptLogPacket: message is not an object: " << messageText;
continue;
}
ScriptMessage scriptMessage;
if (!scriptMessage.fromJson(array[n].toObject())) {
qWarning() << "EntityScriptServerLogClient::handleEntityServerScriptLogPacket: message parsing failed: " << messageText;
continue;
}
switch (scriptMessage.getSeverity()) {
case ScriptMessage::Severity::SEVERITY_INFO:
emit scriptEngines->infoEntityMessage(scriptMessage.getMessage(), scriptMessage.getFileName(),
scriptMessage.getLineNumber(), scriptMessage.getEntityID(), true);
break;
case ScriptMessage::Severity::SEVERITY_PRINT:
emit scriptEngines->printedEntityMessage(scriptMessage.getMessage(), scriptMessage.getFileName(),
scriptMessage.getLineNumber(), scriptMessage.getEntityID(), true);
break;
case ScriptMessage::Severity::SEVERITY_WARNING:
emit scriptEngines->warningEntityMessage(scriptMessage.getMessage(), scriptMessage.getFileName(),
scriptMessage.getLineNumber(), scriptMessage.getEntityID(), true);
break;
case ScriptMessage::Severity::SEVERITY_ERROR:
emit scriptEngines->errorEntityMessage(scriptMessage.getMessage(), scriptMessage.getFileName(),
scriptMessage.getLineNumber(), scriptMessage.getEntityID(), true);
break;
default:
break;
}
}
}
void EntityScriptServerLogClient::nodeActivated(SharedNodePointer activatedNode) {

View file

@ -256,6 +256,57 @@ signals:
*/
void infoMessage(const QString& message, const QString& engineName);
/*@jsdoc
* Triggered when a client side entity 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} fileName - Name of the file in which message was generated. Empty string when no file name is available.
* @param {number} lineNumber - Number of the line on which message was generated. -1 if there line number is not available.
* @param {Uuid} entityID - Entity ID.
* @param {boolean} isServerScript - true if entity script is server-side, false if it is client-side.
* @returns {Signal}
*/
void printedEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
/*@jsdoc
* Triggered when a client side entity 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} fileName - Name of the file in which message was generated. Empty string when no file name is available.
* @param {number} lineNumber - Number of the line on which message was generated. -1 if there line number is not available.
* @param {Uuid} entityID - Entity ID.
* @param {boolean} isServerScript - true if entity script is server-side, false if it is client-side.
* @returns {Signal}
*/
void errorEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
/*@jsdoc
* Triggered when a client side entity script generates a warning or {@link console.warn} is called.
* @function Script.warningMessage
* @param {string} message - The warning message.
* @param {string} fileName - Name of the file in which message was generated. Empty string when no file name is available.
* @param {number} lineNumber - Number of the line on which message was generated. -1 if there line number is not available.
* @param {Uuid} entityID - Entity ID.
* @param {boolean} isServerScript - true if entity script is server-side, false if it is client-side.
* @returns {Signal}
*/
void warningEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
/*@jsdoc
* Triggered when a client side entity script generates an information message or {@link console.info} is called.
* @function Script.infoMessage
* @param {string} message - The information message.
* @param {string} fileName - Name of the file in which message was generated. Empty string when no file name is available.
* @param {number} lineNumber - Number of the line on which message was generated. -1 if there line number is not available.
* @param {Uuid} entityID - Entity ID.
* @param {boolean} isServerScript - true if entity script is server-side, false if it is client-side.
* @returns {Signal}
*/
void infoEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
/*@jsdoc
* @function ScriptDiscoveryService.errorLoadingScript
* @param {string} url - URL.
@ -355,6 +406,10 @@ protected:
bool _defaultScriptsLocationOverridden { false };
QString _debugScriptUrl;
// TODO: remove script managers when shutting them down
QSet<ScriptManagerPointer> _scriptManagersThatRequestedServerEntityMessages;
QMutex _serverEntityMessagesMutex;
// If this is set, defaultScripts.js will not be run if it is in the settings,
// and this will be run instead. This script will not be persisted to settings.
const QUrl _defaultScriptsOverride { };

View file

@ -584,7 +584,7 @@ void ScriptManager::scriptErrorMessage(const QString& message, const QString& fi
qCCritical(scriptengine, "[%s] %s", qUtf8Printable(getFilename()), qUtf8Printable(message));
emit errorMessage(message, getFilename());
if (!currentEntityIdentifier.isInvalidID()) {
emit errorEntityMessage(message, fileName, lineNumber, currentEntityIdentifier);
emit errorEntityMessage(message, fileName, lineNumber, currentEntityIdentifier, isEntityServerScript());
}
}
@ -592,7 +592,7 @@ void ScriptManager::scriptWarningMessage(const QString& message, const QString&
qCWarning(scriptengine, "[%s] %s", qUtf8Printable(getFilename()), qUtf8Printable(message));
emit warningMessage(message, getFilename());
if (!currentEntityIdentifier.isInvalidID()) {
emit warningEntityMessage(message, fileName, lineNumber, currentEntityIdentifier);
emit warningEntityMessage(message, fileName, lineNumber, currentEntityIdentifier, isEntityServerScript());
}
}
@ -600,7 +600,7 @@ void ScriptManager::scriptInfoMessage(const QString& message, const QString& fil
qCInfo(scriptengine, "[%s] %s", qUtf8Printable(getFilename()), qUtf8Printable(message));
emit infoMessage(message, getFilename());
if (!currentEntityIdentifier.isInvalidID()) {
emit infoEntityMessage(message, fileName, lineNumber, currentEntityIdentifier);
emit infoEntityMessage(message, fileName, lineNumber, currentEntityIdentifier, isEntityServerScript());
}
}
@ -608,7 +608,7 @@ void ScriptManager::scriptPrintedMessage(const QString& message, const QString&
qCDebug(scriptengine, "[%s] %s", qUtf8Printable(getFilename()), qUtf8Printable(message));
emit printedMessage(message, getFilename());
if (!currentEntityIdentifier.isInvalidID()) {
emit printedEntityMessage(message, fileName, lineNumber, currentEntityIdentifier);
emit printedEntityMessage(message, fileName, lineNumber, currentEntityIdentifier, isEntityServerScript());
}
}

View file

@ -1336,8 +1336,9 @@ signals:
* @param fileName Name of the file in which message was generated.
* @param lineNumber Number of the line on which message was generated.
* @param entityID
* @param isServerScript true if entity script is server-side, false if it is client-side.
*/
void printedEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID);
void printedEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
/**
@ -1347,8 +1348,9 @@ signals:
* @param fileName Name of the file in which message was generated.
* @param lineNumber Number of the line on which message was generated.
* @param entityID
* @param isServerScript true if entity script is server-side, false if it is client-side.
*/
void errorEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID);
void errorEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
@ -1359,8 +1361,9 @@ signals:
* @param fileName Name of the file in which message was generated.
* @param lineNumber Number of the line on which message was generated.
* @param entityID
* @param isServerScript true if entity script is server-side, false if it is client-side.
*/
void warningEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID);
void warningEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
/**
@ -1370,8 +1373,9 @@ signals:
* @param fileName Name of the file in which message was generated.
* @param lineNumber Number of the line on which message was generated.
* @param entityID
* @param isServerScript true if entity script is server-side, false if it is client-side.
*/
void infoEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID);
void infoEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID, bool isServerScript);
/**

View file

@ -12,6 +12,7 @@
#include "ScriptManager.h"
#include "ScriptManagerScriptingInterface.h"
#include "ScriptEngines.h"
#include "ScriptEngine.h"
#include <QMetaType>
@ -35,10 +36,6 @@
connect(_manager, &ScriptManager::printedMessage, this, &ScriptManagerScriptingInterface::printedMessage);
connect(_manager, &ScriptManager::errorMessage, this, &ScriptManagerScriptingInterface::errorMessage);
connect(_manager, &ScriptManager::warningMessage, this, &ScriptManagerScriptingInterface::warningMessage);
connect(_manager, &ScriptManager::infoEntityMessage, this, &ScriptManagerScriptingInterface::infoEntityMessage);
connect(_manager, &ScriptManager::printedEntityMessage, this, &ScriptManagerScriptingInterface::printedEntityMessage);
connect(_manager, &ScriptManager::errorEntityMessage, this, &ScriptManagerScriptingInterface::errorEntityMessage);
connect(_manager, &ScriptManager::warningEntityMessage, this, &ScriptManagerScriptingInterface::warningEntityMessage);
connect(_manager, &ScriptManager::infoMessage, this, &ScriptManagerScriptingInterface::infoMessage);
connect(_manager, &ScriptManager::runningStateChanged, this, &ScriptManagerScriptingInterface::runningStateChanged);
connect(_manager, &ScriptManager::clearDebugWindow, this, &ScriptManagerScriptingInterface::clearDebugWindow);
@ -92,3 +89,18 @@ void ScriptManagerScriptingInterface::startProfiling() {
void ScriptManagerScriptingInterface::stopProfilingAndSave() {
_manager->engine()->stopProfilingAndSave();
}
void ScriptManagerScriptingInterface::requestServerEntityScriptMessages() {
if (_manager->isEntityServerScript() || _manager->isEntityServerScript() || _manager->isClientScript()) {
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
//TODO;
}
}
void ScriptManagerScriptingInterface::removeServerEntityScriptMessagesRequest() {
if (_manager->isEntityServerScript() || _manager->isEntityServerScript() || _manager->isClientScript()) {
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
//TODO;
}
}

View file

@ -557,7 +557,25 @@ public:
*/
Q_INVOKABLE void stopProfilingAndSave();
signals:
/*@jsdoc
* After calling this function current script engine will start receiving server-side entity script messages
* through signals such as errorEntityMessage. This function can be invoked both from client-side entity scripts
* and from interface scripts.
* @function Script.subscribeToServerEntityScriptMessages
*/
Q_INVOKABLE void requestServerEntityScriptMessages();
/*@jsdoc
* Calling this function signalizes that current script doesn't require stop receiving server-side entity script messages
* through signals such as errorEntityMessage. This function can be invoked both from client-side entity scripts
* and from interface scripts.
* @function Script.unsubscribeFromServerEntityScriptMessages
*/
Q_INVOKABLE void removeServerEntityScriptMessagesRequest();
signals:
/*@jsdoc
* @function Script.scriptLoaded
@ -644,53 +662,6 @@ signals:
*/
void infoMessage(const QString& message, const QString& scriptName);
/*@jsdoc
* Triggered when a client side entity 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} fileName - Name of the file in which message was generated. Empty string when no file name is available.
* @param {number} lineNumber - Number of the line on which message was generated. -1 if there line number is not available.
* @param {Uuid} entityID - Entity ID.
* @returns {Signal}
*/
void printedEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID);
/*@jsdoc
* Triggered when a client side entity 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} fileName - Name of the file in which message was generated. Empty string when no file name is available.
* @param {number} lineNumber - Number of the line on which message was generated. -1 if there line number is not available.
* @param {Uuid} entityID - Entity ID.
* @returns {Signal}
*/
void errorEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID);
/*@jsdoc
* Triggered when a client side entity script generates a warning or {@link console.warn} is called.
* @function Script.warningMessage
* @param {string} message - The warning message.
* @param {string} fileName - Name of the file in which message was generated. Empty string when no file name is available.
* @param {number} lineNumber - Number of the line on which message was generated. -1 if there line number is not available.
* @param {Uuid} entityID - Entity ID.
* @returns {Signal}
*/
void warningEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID);
/*@jsdoc
* Triggered when a client side entity script generates an information message or {@link console.info} is called.
* @function Script.infoMessage
* @param {string} message - The information message.
* @param {string} fileName - Name of the file in which message was generated. Empty string when no file name is available.
* @param {number} lineNumber - Number of the line on which message was generated. -1 if there line number is not available.
* @param {Uuid} entityID - Entity ID.
* @returns {Signal}
*/
void infoEntityMessage(const QString& message, const QString& fileName, int lineNumber, const EntityItemID& entityID);
/*@jsdoc
* Triggered when the running state of the script changes, e.g., from running to stopping.
* @function Script.runningStateChanged

View file

@ -18,6 +18,7 @@ QJsonObject ScriptMessage::toJson() {
object["message"] = _messageContent;
object["lineNumber"] = _lineNumber;
object["fileName"] = _fileName;
object["entityID"] = _entityID.toString();
object["type"] = static_cast<int>(_scriptType);
object["severity"] = static_cast<int>(_severity);
return object;
@ -27,6 +28,7 @@ bool ScriptMessage::fromJson(const QJsonObject &object) {
if (!object["message"].isString()
|| !object["lineNumber"].isDouble()
|| !object["fileName"].isString()
|| !object["entityID"].isString()
|| !object["type"].isDouble()
|| !object["severity"].isDouble()) {
qDebug() << "ScriptMessage::fromJson failed to find required fields in JSON file";
@ -35,6 +37,7 @@ bool ScriptMessage::fromJson(const QJsonObject &object) {
_messageContent = object["message"].toString();
_lineNumber = object["lineNumber"].toInt();
_fileName = object["fileName"].toInt();
_entityID = QUuid::fromString(object["entityID"].toString());
_scriptType = static_cast<ScriptMessage::ScriptType>(object["type"].toInt());
_severity = static_cast<ScriptMessage::Severity>(object["severity"].toInt());
}

View file

@ -18,6 +18,7 @@
#include <QString>
#include <QJsonObject>
#include "EntityItemID.h"
class ScriptMessage {
public:
@ -35,16 +36,24 @@ public:
};
ScriptMessage() {};
ScriptMessage(QString messageContent, QString fileName, int lineNumber, ScriptType scriptType, Severity severity)
: _messageContent(messageContent), _fileName(fileName), _lineNumber(lineNumber), _scriptType(scriptType) {}
ScriptMessage(const QString &messageContent, const QString &fileName, int lineNumber, const EntityItemID& entityID, ScriptType scriptType, Severity severity)
: _messageContent(messageContent), _fileName(fileName), _lineNumber(lineNumber), _entityID(entityID), _scriptType(scriptType), _severity(severity) {}
QJsonObject toJson();
bool fromJson(const QJsonObject &object);
QString getMessage() { return _messageContent; }
QString getFileName() { return _fileName; }
int getLineNumber() { return _lineNumber; }
ScriptType getScriptType() { return _scriptType; }
Severity getSeverity() { return _severity; }
EntityItemID getEntityID() { return _entityID; }
private:
QString _messageContent;
QString _fileName;
int _lineNumber {-1};
EntityItemID _entityID;
ScriptType _scriptType {ScriptType::TYPE_NONE};
Severity _severity {Severity::SEVERITY_NONE};
};