mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 02:53:43 +02:00
Merge pull request #9581 from Atlante45/ess-pr
Add log window for the EntityScriptServer in interface.
This commit is contained in:
commit
e329696cc8
21 changed files with 652 additions and 196 deletions
|
@ -27,6 +27,7 @@ public:
|
|||
QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort,
|
||||
quint16 assignmentMonitorPort);
|
||||
~AssignmentClient();
|
||||
|
||||
private slots:
|
||||
void sendAssignmentRequest();
|
||||
void assignmentCompleted();
|
||||
|
|
|
@ -11,9 +11,13 @@
|
|||
|
||||
#include "EntityScriptServer.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <AudioConstants.h>
|
||||
#include <AudioInjectorManager.h>
|
||||
#include <ClientServerUtils.h>
|
||||
#include <EntityScriptingInterface.h>
|
||||
#include <LogHandler.h>
|
||||
#include <MessagesClient.h>
|
||||
#include <plugins/CodecPlugin.h>
|
||||
#include <plugins/PluginManager.h>
|
||||
|
@ -24,12 +28,29 @@
|
|||
#include <UUID.h>
|
||||
#include <WebSocketServerClass.h>
|
||||
|
||||
#include "ClientServerUtils.h"
|
||||
#include "EntityScriptServerLogging.h"
|
||||
#include "../entities/AssignmentParentFinder.h"
|
||||
|
||||
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;
|
||||
|
||||
EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssignment(message) {
|
||||
qInstallMessageHandler(messageHandler);
|
||||
|
||||
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
||||
|
||||
ResourceManager::init();
|
||||
|
@ -57,6 +78,17 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
|||
|
||||
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
|
||||
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
|
||||
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
|
||||
|
||||
static const int LOG_INTERVAL = MSECS_PER_SECOND / 10;
|
||||
auto timer = new QTimer(this);
|
||||
timer->setInterval(LOG_INTERVAL);
|
||||
connect(timer, &QTimer::timeout, this, &EntityScriptServer::pushLogs);
|
||||
timer->start();
|
||||
}
|
||||
|
||||
EntityScriptServer::~EntityScriptServer() {
|
||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||
}
|
||||
|
||||
static const QString ENTITY_SCRIPT_SERVER_LOGGING_NAME = "entity-script-server";
|
||||
|
@ -68,7 +100,7 @@ void EntityScriptServer::handleReloadEntityServerScriptPacket(QSharedPointer<Rec
|
|||
auto entityID = QUuid::fromRfc4122(message->read(NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
if (_entityViewer.getTree() && !_shuttingDown) {
|
||||
qDebug() << "Reloading: " << entityID;
|
||||
qCDebug(entity_script_server) << "Reloading: " << entityID;
|
||||
_entitiesScriptEngine->unloadEntityScript(entityID);
|
||||
checkAndCallPreload(entityID, true);
|
||||
}
|
||||
|
@ -146,6 +178,53 @@ void EntityScriptServer::updateEntityPPS() {
|
|||
qDebug() << QString("Updating entity PPS to: %1 @ %2 PPS per script = %3 PPS").arg(numRunningScripts).arg(_entityPPSPerScript).arg(pps);
|
||||
}
|
||||
|
||||
void EntityScriptServer::handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
// These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them
|
||||
// about each other.
|
||||
bool enable = false;
|
||||
message->readPrimitive(&enable);
|
||||
|
||||
auto senderUUID = senderNode->getUUID();
|
||||
auto it = _logListeners.find(senderUUID);
|
||||
|
||||
if (enable && senderNode->getCanRez()) {
|
||||
if (it == std::end(_logListeners)) {
|
||||
_logListeners.insert(senderUUID);
|
||||
qCInfo(entity_script_server) << "Node" << senderUUID << "subscribed to log stream";
|
||||
}
|
||||
} else {
|
||||
if (it != std::end(_logListeners)) {
|
||||
_logListeners.erase(it);
|
||||
qCInfo(entity_script_server) << "Node" << senderUUID << "unsubscribed from log stream";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::pushLogs() {
|
||||
std::string buffer;
|
||||
{
|
||||
Lock lock(logBufferMutex);
|
||||
std::swap(logBuffer, buffer);
|
||||
}
|
||||
|
||||
if (buffer.empty()) {
|
||||
return;
|
||||
}
|
||||
if (_logListeners.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
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());
|
||||
nodeList->sendPacketList(std::move(packet), *node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::run() {
|
||||
// make sure we request our script once the agent connects to the domain
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
@ -203,9 +282,67 @@ void EntityScriptServer::run() {
|
|||
connect(tree, &EntityTree::entityServerScriptChanging, this, &EntityScriptServer::entityServerScriptChanging, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void EntityScriptServer::cleanupOldKilledListeners() {
|
||||
auto threshold = usecTimestampNow() - 5 * USECS_PER_SECOND;
|
||||
using ValueType = std::pair<QUuid, quint64>;
|
||||
auto it = std::remove_if(std::begin(_killedListeners), std::end(_killedListeners), [&](ValueType value) {
|
||||
return value.second < threshold;
|
||||
});
|
||||
_killedListeners.erase(it, std::end(_killedListeners));
|
||||
}
|
||||
|
||||
void EntityScriptServer::nodeActivated(SharedNodePointer activatedNode) {
|
||||
if (activatedNode->getType() == NodeType::AudioMixer) {
|
||||
negotiateAudioFormat();
|
||||
switch (activatedNode->getType()) {
|
||||
case NodeType::AudioMixer:
|
||||
negotiateAudioFormat();
|
||||
break;
|
||||
case NodeType::Agent: {
|
||||
auto activatedNodeUUID = activatedNode->getUUID();
|
||||
using ValueType = std::pair<QUuid, quint64>;
|
||||
auto it = std::find_if(std::begin(_killedListeners), std::end(_killedListeners), [&](ValueType value) {
|
||||
return value.first == activatedNodeUUID;
|
||||
});
|
||||
if (it != std::end(_killedListeners)) {
|
||||
_killedListeners.erase(it);
|
||||
_logListeners.insert(activatedNodeUUID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::nodeKilled(SharedNodePointer killedNode) {
|
||||
switch (killedNode->getType()) {
|
||||
case NodeType::EntityServer: {
|
||||
if (!_shuttingDown) {
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->unloadAllEntityScripts();
|
||||
_entitiesScriptEngine->stop();
|
||||
}
|
||||
|
||||
resetEntitiesScriptEngine();
|
||||
|
||||
_entityViewer.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NodeType::Agent: {
|
||||
cleanupOldKilledListeners();
|
||||
|
||||
auto killedNodeUUID = killedNode->getUUID();
|
||||
auto it = _logListeners.find(killedNodeUUID);
|
||||
if (it != std::end(_logListeners)) {
|
||||
_logListeners.erase(killedNodeUUID);
|
||||
_killedListeners.emplace_back(killedNodeUUID, usecTimestampNow());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,7 +374,7 @@ void EntityScriptServer::handleSelectedAudioFormat(QSharedPointer<ReceivedMessag
|
|||
void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) {
|
||||
_selectedCodecName = selectedCodecName;
|
||||
|
||||
qDebug() << "Selected Codec:" << _selectedCodecName;
|
||||
qCDebug(entity_script_server) << "Selected Codec:" << _selectedCodecName;
|
||||
|
||||
// release any old codec encoder/decoder first...
|
||||
if (_codec && _encoder) {
|
||||
|
@ -251,7 +388,7 @@ void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) {
|
|||
if (_selectedCodecName == plugin->getName()) {
|
||||
_codec = plugin;
|
||||
_encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO);
|
||||
qDebug() << "Selected Codec Plugin:" << _codec.get();
|
||||
qCDebug(entity_script_server) << "Selected Codec Plugin:" << _codec.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -339,26 +476,13 @@ void EntityScriptServer::checkAndCallPreload(const EntityItemID& entityID, const
|
|||
QString scriptUrl = entity->getServerScripts();
|
||||
if (!scriptUrl.isEmpty()) {
|
||||
scriptUrl = ResourceManager::normalizeURL(scriptUrl);
|
||||
qDebug() << "Loading entity server script" << scriptUrl << "for" << entityID;
|
||||
qCDebug(entity_script_server) << "Loading entity server script" << scriptUrl << "for" << entityID;
|
||||
ScriptEngine::loadEntityScript(_entitiesScriptEngine, entityID, scriptUrl, reload);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::nodeKilled(SharedNodePointer killedNode) {
|
||||
if (!_shuttingDown && killedNode->getType() == NodeType::EntityServer) {
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->unloadAllEntityScripts();
|
||||
_entitiesScriptEngine->stop();
|
||||
}
|
||||
|
||||
resetEntitiesScriptEngine();
|
||||
|
||||
_entityViewer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::sendStatsPacket() {
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,11 @@
|
|||
#ifndef hifi_EntityScriptServer_h
|
||||
#define hifi_EntityScriptServer_h
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include <EntityEditPacketSender.h>
|
||||
#include <EntityTreeHeadlessViewer.h>
|
||||
|
@ -28,6 +32,7 @@ class EntityScriptServer : public ThreadedAssignment {
|
|||
|
||||
public:
|
||||
EntityScriptServer(ReceivedMessage& message);
|
||||
~EntityScriptServer();
|
||||
|
||||
virtual void aboutToFinish() override;
|
||||
|
||||
|
@ -48,6 +53,10 @@ private slots:
|
|||
void handleSettings();
|
||||
void updateEntityPPS();
|
||||
|
||||
void handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
|
||||
void pushLogs();
|
||||
|
||||
private:
|
||||
void negotiateAudioFormat();
|
||||
void selectAudioFormat(const QString& selectedCodecName);
|
||||
|
@ -61,6 +70,8 @@ private:
|
|||
void entityServerScriptChanging(const EntityItemID& entityID, const bool reload);
|
||||
void checkAndCallPreload(const EntityItemID& entityID, const bool reload = false);
|
||||
|
||||
void cleanupOldKilledListeners();
|
||||
|
||||
bool _shuttingDown { false };
|
||||
|
||||
static int _entitiesScriptEngineCount;
|
||||
|
@ -71,6 +82,9 @@ private:
|
|||
int _maxEntityPPS { DEFAULT_MAX_ENTITY_PPS };
|
||||
int _entityPPSPerScript { DEFAULT_ENTITY_PPS_PER_SCRIPT };
|
||||
|
||||
std::set<QUuid> _logListeners;
|
||||
std::vector<std::pair<QUuid, quint64>> _killedListeners;
|
||||
|
||||
QString _selectedCodecName;
|
||||
CodecPluginPointer _codec;
|
||||
Encoder* _encoder { nullptr };
|
||||
|
|
14
assignment-client/src/scripts/EntityScriptServerLogging.cpp
Normal file
14
assignment-client/src/scripts/EntityScriptServerLogging.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// EntityScriptServerLogging.cpp
|
||||
// assignment-client/src/scripts
|
||||
//
|
||||
// Created by Clement on 2/2/17.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "EntityScriptServerLogging.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(entity_script_server, "hifi.entity-script-server")
|
19
assignment-client/src/scripts/EntityScriptServerLogging.h
Normal file
19
assignment-client/src/scripts/EntityScriptServerLogging.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// EntityScriptServerLogging.h
|
||||
// assignment-client/src/scripts
|
||||
//
|
||||
// Created by Clement on 2/2/17.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_EntityScriptServerLogging_h
|
||||
#define hifi_EntityScriptServerLogging_h
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(entity_script_server)
|
||||
|
||||
#endif // hifi_EntityScriptServerLogging_h
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include <QtMultimedia/QMediaPlayer>
|
||||
|
||||
#include <QFontDatabase>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QTemporaryDir>
|
||||
|
||||
|
@ -62,6 +63,7 @@
|
|||
#include <DebugDraw.h>
|
||||
#include <DeferredLightingEffect.h>
|
||||
#include <EntityScriptClient.h>
|
||||
#include <EntityScriptServerLogClient.h>
|
||||
#include <EntityScriptingInterface.h>
|
||||
#include <ErrorDialog.h>
|
||||
#include <FileScriptingInterface.h>
|
||||
|
@ -174,7 +176,6 @@
|
|||
#include "FrameTimingsScriptingInterface.h"
|
||||
#include <GPUIdent.h>
|
||||
#include <gl/GLHelpers.h>
|
||||
#include <EntityScriptClient.h>
|
||||
|
||||
// On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||
// FIXME seems to be broken.
|
||||
|
@ -519,6 +520,7 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
DependencyManager::set<CompositorHelper>();
|
||||
DependencyManager::set<OffscreenQmlSurfaceCache>();
|
||||
DependencyManager::set<EntityScriptClient>();
|
||||
DependencyManager::set<EntityScriptServerLogClient>();
|
||||
return previousSessionCrashed;
|
||||
}
|
||||
|
||||
|
@ -5523,6 +5525,9 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
|||
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
||||
scriptEngine->registerGlobalObject("Recording", recordingInterface.data());
|
||||
|
||||
auto entityScriptServerLog = DependencyManager::get<EntityScriptServerLogClient>();
|
||||
scriptEngine->registerGlobalObject("EntityScriptServerLog", entityScriptServerLog.data());
|
||||
|
||||
// connect this script engines printedMessage signal to the global ScriptEngines these various messages
|
||||
connect(scriptEngine, &ScriptEngine::printedMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onPrintedMessage);
|
||||
connect(scriptEngine, &ScriptEngine::errorMessage, DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onErrorMessage);
|
||||
|
@ -6283,6 +6288,17 @@ void Application::toggleLogDialog() {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::toggleEntityScriptServerLogDialog() {
|
||||
if (! _entityScriptServerLogDialog) {
|
||||
_entityScriptServerLogDialog = new EntityScriptServerLogDialog(nullptr);
|
||||
}
|
||||
|
||||
if (_entityScriptServerLogDialog->isVisible()) {
|
||||
_entityScriptServerLogDialog->hide();
|
||||
} else {
|
||||
_entityScriptServerLogDialog->show();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) {
|
||||
postLambdaEvent([notify, includeAnimated, aspectRatio, this] {
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "scripting/DialogsManagerScriptingInterface.h"
|
||||
#include "ui/ApplicationOverlay.h"
|
||||
#include "ui/BandwidthDialog.h"
|
||||
#include "ui/EntityScriptServerLogDialog.h"
|
||||
#include "ui/LodToolsDialog.h"
|
||||
#include "ui/LogDialog.h"
|
||||
#include "ui/OctreeStatsDialog.h"
|
||||
|
@ -314,6 +315,7 @@ public slots:
|
|||
Q_INVOKABLE void loadDialog();
|
||||
Q_INVOKABLE void loadScriptURLDialog() const;
|
||||
void toggleLogDialog();
|
||||
void toggleEntityScriptServerLogDialog();
|
||||
void toggleRunningScriptsWidget() const;
|
||||
Q_INVOKABLE void showAssetServerWidget(QString filePath = "");
|
||||
|
||||
|
@ -566,6 +568,7 @@ private:
|
|||
NodeToOctreeSceneStats _octreeServerSceneStats;
|
||||
ControllerScriptingInterface* _controllerScriptingInterface{ nullptr };
|
||||
QPointer<LogDialog> _logDialog;
|
||||
QPointer<EntityScriptServerLogDialog> _entityScriptServerLogDialog;
|
||||
|
||||
FileLogger* _logger;
|
||||
|
||||
|
|
|
@ -702,7 +702,14 @@ Menu::Menu() {
|
|||
|
||||
// Developer > Log...
|
||||
addActionToQMenuAndActionHash(developerMenu, MenuOption::Log, Qt::CTRL | Qt::SHIFT | Qt::Key_L,
|
||||
qApp, SLOT(toggleLogDialog()));
|
||||
qApp, SLOT(toggleLogDialog()));
|
||||
auto essLogAction = addActionToQMenuAndActionHash(developerMenu, MenuOption::EntityScriptServerLog, 0,
|
||||
qApp, SLOT(toggleEntityScriptServerLogDialog()));
|
||||
QObject::connect(nodeList.data(), &NodeList::canRezChanged, essLogAction, [essLogAction] {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
essLogAction->setEnabled(nodeList->getThisNodeCanRez());
|
||||
});
|
||||
essLogAction->setEnabled(nodeList->getThisNodeCanRez());
|
||||
|
||||
action = addActionToQMenuAndActionHash(developerMenu, "Script Log (HMD friendly)...");
|
||||
connect(action, &QAction::triggered, [] {
|
||||
|
|
|
@ -98,6 +98,7 @@ namespace MenuOption {
|
|||
const QString EchoServerAudio = "Echo Server Audio";
|
||||
const QString EnableCharacterController = "Enable avatar collisions";
|
||||
const QString EnableInverseKinematics = "Enable Inverse Kinematics";
|
||||
const QString EntityScriptServerLog = "Entity Script Server Log";
|
||||
const QString ExpandMyAvatarSimulateTiming = "Expand /myAvatar/simulation";
|
||||
const QString ExpandMyAvatarTiming = "Expand /myAvatar";
|
||||
const QString ExpandOtherAvatarTiming = "Expand /otherAvatar";
|
||||
|
|
135
interface/src/ui/BaseLogDialog.cpp
Normal file
135
interface/src/ui/BaseLogDialog.cpp
Normal file
|
@ -0,0 +1,135 @@
|
|||
//
|
||||
// BaseLogDialog.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Clement Brisset on 1/31/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "BaseLogDialog.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QLineEdit>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
#include <QSyntaxHighlighter>
|
||||
|
||||
#include <PathUtils.h>
|
||||
|
||||
const int TOP_BAR_HEIGHT = 46;
|
||||
const int INITIAL_WIDTH = 720;
|
||||
const int INITIAL_HEIGHT = 480;
|
||||
const int MINIMAL_WIDTH = 570;
|
||||
const int SEARCH_BUTTON_LEFT = 25;
|
||||
const int SEARCH_BUTTON_WIDTH = 20;
|
||||
const int SEARCH_TEXT_WIDTH = 240;
|
||||
const QColor HIGHLIGHT_COLOR = QColor("#3366CC");
|
||||
|
||||
class KeywordHighlighter : public QSyntaxHighlighter {
|
||||
public:
|
||||
KeywordHighlighter(QTextDocument* parent = nullptr);
|
||||
QString keyword;
|
||||
|
||||
protected:
|
||||
void highlightBlock(const QString& text) override;
|
||||
|
||||
private:
|
||||
QTextCharFormat keywordFormat;
|
||||
|
||||
};
|
||||
|
||||
BaseLogDialog::BaseLogDialog(QWidget* parent) : QDialog(parent, Qt::Window) {
|
||||
setWindowTitle("Base Log");
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QFile styleSheet(PathUtils::resourcesPath() + "styles/log_dialog.qss");
|
||||
if (styleSheet.open(QIODevice::ReadOnly)) {
|
||||
QDir::setCurrent(PathUtils::resourcesPath());
|
||||
setStyleSheet(styleSheet.readAll());
|
||||
}
|
||||
|
||||
initControls();
|
||||
|
||||
resize(INITIAL_WIDTH, INITIAL_HEIGHT);
|
||||
setMinimumWidth(MINIMAL_WIDTH);
|
||||
}
|
||||
|
||||
BaseLogDialog::~BaseLogDialog() {
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void BaseLogDialog::initControls() {
|
||||
_searchButton = new QPushButton(this);
|
||||
// set object name for css styling
|
||||
_searchButton->setObjectName("searchButton");
|
||||
_leftPad = SEARCH_BUTTON_LEFT;
|
||||
_searchButton->setGeometry(_leftPad, ELEMENT_MARGIN, SEARCH_BUTTON_WIDTH, ELEMENT_HEIGHT);
|
||||
_leftPad += SEARCH_BUTTON_WIDTH;
|
||||
_searchButton->show();
|
||||
connect(_searchButton, SIGNAL(clicked()), SLOT(handleSearchButton()));
|
||||
|
||||
_searchTextBox = new QLineEdit(this);
|
||||
// disable blue outline in Mac
|
||||
_searchTextBox->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
_searchTextBox->setGeometry(_leftPad, ELEMENT_MARGIN, SEARCH_TEXT_WIDTH, ELEMENT_HEIGHT);
|
||||
_leftPad += SEARCH_TEXT_WIDTH + CHECKBOX_MARGIN;
|
||||
_searchTextBox->show();
|
||||
connect(_searchTextBox, SIGNAL(textChanged(QString)), SLOT(handleSearchTextChanged(QString)));
|
||||
|
||||
_logTextBox = new QPlainTextEdit(this);
|
||||
_logTextBox->setReadOnly(true);
|
||||
_logTextBox->show();
|
||||
_highlighter = new KeywordHighlighter(_logTextBox->document());
|
||||
|
||||
}
|
||||
|
||||
void BaseLogDialog::showEvent(QShowEvent* event) {
|
||||
showLogData();
|
||||
}
|
||||
|
||||
void BaseLogDialog::resizeEvent(QResizeEvent* event) {
|
||||
_logTextBox->setGeometry(0, TOP_BAR_HEIGHT, width(), height() - TOP_BAR_HEIGHT);
|
||||
}
|
||||
|
||||
void BaseLogDialog::appendLogLine(QString logLine) {
|
||||
if (logLine.contains(_searchTerm, Qt::CaseInsensitive)) {
|
||||
_logTextBox->appendPlainText(logLine.trimmed());
|
||||
}
|
||||
}
|
||||
|
||||
void BaseLogDialog::handleSearchButton() {
|
||||
_searchTextBox->setFocus();
|
||||
}
|
||||
|
||||
void BaseLogDialog::handleSearchTextChanged(QString searchText) {
|
||||
_searchTerm = searchText;
|
||||
_highlighter->keyword = searchText;
|
||||
_highlighter->rehighlight();
|
||||
}
|
||||
|
||||
void BaseLogDialog::showLogData() {
|
||||
_logTextBox->clear();
|
||||
_logTextBox->appendPlainText(getCurrentLog());
|
||||
_logTextBox->ensureCursorVisible();
|
||||
}
|
||||
|
||||
KeywordHighlighter::KeywordHighlighter(QTextDocument* parent) : QSyntaxHighlighter(parent) {
|
||||
keywordFormat.setForeground(HIGHLIGHT_COLOR);
|
||||
}
|
||||
|
||||
void KeywordHighlighter::highlightBlock(const QString& text) {
|
||||
if (keyword.isNull() || keyword.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index = text.indexOf(keyword, 0, Qt::CaseInsensitive);
|
||||
int length = keyword.length();
|
||||
|
||||
while (index >= 0) {
|
||||
setFormat(index, length, keywordFormat);
|
||||
index = text.indexOf(keyword, index + length, Qt::CaseInsensitive);
|
||||
}
|
||||
}
|
60
interface/src/ui/BaseLogDialog.h
Normal file
60
interface/src/ui/BaseLogDialog.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// BaseLogDialog.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Clement Brisset on 1/31/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_BaseLogDialog_h
|
||||
#define hifi_BaseLogDialog_h
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
const int ELEMENT_MARGIN = 7;
|
||||
const int ELEMENT_HEIGHT = 32;
|
||||
const int CHECKBOX_MARGIN = 12;
|
||||
const int CHECKBOX_WIDTH = 140;
|
||||
|
||||
class QPushButton;
|
||||
class QLineEdit;
|
||||
class QPlainTextEdit;
|
||||
class KeywordHighlighter;
|
||||
|
||||
class BaseLogDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BaseLogDialog(QWidget* parent);
|
||||
~BaseLogDialog();
|
||||
|
||||
public slots:
|
||||
void appendLogLine(QString logLine);
|
||||
|
||||
private slots:
|
||||
void handleSearchButton();
|
||||
void handleSearchTextChanged(QString text);
|
||||
|
||||
protected:
|
||||
int _leftPad { 0 };
|
||||
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
void showEvent(QShowEvent* event) override;
|
||||
virtual QString getCurrentLog() = 0;
|
||||
|
||||
private:
|
||||
QPushButton* _searchButton { nullptr };
|
||||
QLineEdit* _searchTextBox { nullptr };
|
||||
QPlainTextEdit* _logTextBox { nullptr };
|
||||
QString _searchTerm;
|
||||
KeywordHighlighter* _highlighter { nullptr };
|
||||
|
||||
void initControls();
|
||||
void showLogData();
|
||||
};
|
||||
|
||||
|
||||
#endif // hifi_BaseLogDialog_h
|
23
interface/src/ui/EntityScriptServerLogDialog.cpp
Normal file
23
interface/src/ui/EntityScriptServerLogDialog.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// EntityScriptServerLogDialog.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Clement Brisset on 1/31/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "EntityScriptServerLogDialog.h"
|
||||
|
||||
#include <EntityScriptServerLogClient.h>
|
||||
|
||||
EntityScriptServerLogDialog::EntityScriptServerLogDialog(QWidget* parent) : BaseLogDialog(parent) {
|
||||
setWindowTitle("Entity Script Server Log");
|
||||
|
||||
|
||||
auto client = DependencyManager::get<EntityScriptServerLogClient>();
|
||||
QObject::connect(client.data(), &EntityScriptServerLogClient::receivedNewLogLines,
|
||||
this, &EntityScriptServerLogDialog::appendLogLine);
|
||||
}
|
27
interface/src/ui/EntityScriptServerLogDialog.h
Normal file
27
interface/src/ui/EntityScriptServerLogDialog.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// EntityScriptServerLogDialog.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Clement Brisset on 1/31/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_EntityScriptServerLogDialog_h
|
||||
#define hifi_EntityScriptServerLogDialog_h
|
||||
|
||||
#include "BaseLogDialog.h"
|
||||
|
||||
class EntityScriptServerLogDialog : public BaseLogDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EntityScriptServerLogDialog(QWidget* parent = nullptr);
|
||||
|
||||
protected:
|
||||
QString getCurrentLog() override { return QString(); };
|
||||
};
|
||||
|
||||
#endif // hifi_EntityScriptServerLogDialog_h
|
|
@ -9,90 +9,21 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion"
|
||||
#endif
|
||||
#include "LogDialog.h"
|
||||
|
||||
#include <QDesktopWidget>
|
||||
#include <QTextBlock>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#include <shared/AbstractLoggerInterface.h>
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ui/LogDialog.h"
|
||||
|
||||
const int TOP_BAR_HEIGHT = 46;
|
||||
const int INITIAL_WIDTH = 720;
|
||||
const int MINIMAL_WIDTH = 570;
|
||||
const int ELEMENT_MARGIN = 7;
|
||||
const int ELEMENT_HEIGHT = 32;
|
||||
const int SEARCH_BUTTON_LEFT = 25;
|
||||
const int SEARCH_BUTTON_WIDTH = 20;
|
||||
const int SEARCH_TEXT_WIDTH = 240;
|
||||
const int CHECKBOX_MARGIN = 12;
|
||||
const int CHECKBOX_WIDTH = 140;
|
||||
const int REVEAL_BUTTON_WIDTH = 122;
|
||||
const float INITIAL_HEIGHT_RATIO = 0.6f;
|
||||
const QString HIGHLIGHT_COLOR = "#3366CC";
|
||||
|
||||
int qTextCursorMeta = qRegisterMetaType<QTextCursor>("QTextCursor");
|
||||
int qTextBlockMeta = qRegisterMetaType<QTextBlock>("QTextBlock");
|
||||
|
||||
LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : QDialog(parent, Qt::Window) {
|
||||
|
||||
LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : BaseLogDialog(parent) {
|
||||
_logger = logger;
|
||||
setWindowTitle("Log");
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QFile styleSheet(PathUtils::resourcesPath() + "styles/log_dialog.qss");
|
||||
if (styleSheet.open(QIODevice::ReadOnly)) {
|
||||
QDir::setCurrent(PathUtils::resourcesPath());
|
||||
setStyleSheet(styleSheet.readAll());
|
||||
}
|
||||
|
||||
initControls();
|
||||
|
||||
QDesktopWidget desktop;
|
||||
QRect screen = desktop.screenGeometry();
|
||||
resize(INITIAL_WIDTH, static_cast<int>(screen.height() * INITIAL_HEIGHT_RATIO));
|
||||
move(screen.center() - rect().center());
|
||||
setMinimumWidth(MINIMAL_WIDTH);
|
||||
|
||||
connect(_logger, SIGNAL(logReceived(QString)), this, SLOT(appendLogLine(QString)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
LogDialog::~LogDialog() {
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void LogDialog::initControls() {
|
||||
|
||||
int left;
|
||||
_searchButton = new QPushButton(this);
|
||||
// set object name for css styling
|
||||
_searchButton->setObjectName("searchButton");
|
||||
left = SEARCH_BUTTON_LEFT;
|
||||
_searchButton->setGeometry(left, ELEMENT_MARGIN, SEARCH_BUTTON_WIDTH, ELEMENT_HEIGHT);
|
||||
left += SEARCH_BUTTON_WIDTH;
|
||||
_searchButton->show();
|
||||
connect(_searchButton, SIGNAL(clicked()), SLOT(handleSearchButton()));
|
||||
|
||||
_searchTextBox = new QLineEdit(this);
|
||||
// disable blue outline in Mac
|
||||
_searchTextBox->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
_searchTextBox->setGeometry(left, ELEMENT_MARGIN, SEARCH_TEXT_WIDTH, ELEMENT_HEIGHT);
|
||||
left += SEARCH_TEXT_WIDTH + CHECKBOX_MARGIN;
|
||||
_searchTextBox->show();
|
||||
connect(_searchTextBox, SIGNAL(textChanged(QString)), SLOT(handleSearchTextChanged(QString)));
|
||||
|
||||
_extraDebuggingBox = new QCheckBox("Extra debugging", this);
|
||||
_extraDebuggingBox->setGeometry(left, ELEMENT_MARGIN, CHECKBOX_WIDTH, ELEMENT_HEIGHT);
|
||||
_extraDebuggingBox->setGeometry(_leftPad, ELEMENT_MARGIN, CHECKBOX_WIDTH, ELEMENT_HEIGHT);
|
||||
if (_logger->extraDebugging()) {
|
||||
_extraDebuggingBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
|
@ -105,72 +36,25 @@ void LogDialog::initControls() {
|
|||
_revealLogButton->show();
|
||||
connect(_revealLogButton, SIGNAL(clicked()), SLOT(handleRevealButton()));
|
||||
|
||||
_logTextBox = new QPlainTextEdit(this);
|
||||
_logTextBox->setReadOnly(true);
|
||||
_logTextBox->show();
|
||||
_highlighter = new KeywordHighlighter(_logTextBox->document());
|
||||
|
||||
connect(_logger, SIGNAL(logReceived(QString)), this, SLOT(appendLogLine(QString)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void LogDialog::showEvent(QShowEvent*) {
|
||||
showLogData();
|
||||
}
|
||||
|
||||
void LogDialog::resizeEvent(QResizeEvent*) {
|
||||
_logTextBox->setGeometry(0, TOP_BAR_HEIGHT, width(), height() - TOP_BAR_HEIGHT);
|
||||
void LogDialog::resizeEvent(QResizeEvent* event) {
|
||||
BaseLogDialog::resizeEvent(event);
|
||||
_revealLogButton->setGeometry(width() - ELEMENT_MARGIN - REVEAL_BUTTON_WIDTH,
|
||||
ELEMENT_MARGIN,
|
||||
REVEAL_BUTTON_WIDTH,
|
||||
ELEMENT_HEIGHT);
|
||||
}
|
||||
|
||||
void LogDialog::appendLogLine(QString logLine) {
|
||||
if (isVisible()) {
|
||||
if (logLine.contains(_searchTerm, Qt::CaseInsensitive)) {
|
||||
_logTextBox->appendPlainText(logLine.trimmed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LogDialog::handleSearchButton() {
|
||||
_searchTextBox->setFocus();
|
||||
}
|
||||
|
||||
void LogDialog::handleRevealButton() {
|
||||
_logger->locateLog();
|
||||
}
|
||||
|
||||
void LogDialog::handleExtraDebuggingCheckbox(const int state) {
|
||||
void LogDialog::handleExtraDebuggingCheckbox(int state) {
|
||||
_logger->setExtraDebugging(state != 0);
|
||||
}
|
||||
|
||||
void LogDialog::handleSearchTextChanged(const QString searchText) {
|
||||
_searchTerm = searchText;
|
||||
_highlighter->keyword = searchText;
|
||||
showLogData();
|
||||
}
|
||||
|
||||
void LogDialog::showLogData() {
|
||||
_logTextBox->clear();
|
||||
_logTextBox->insertPlainText(_logger->getLogData());
|
||||
_logTextBox->ensureCursorVisible();
|
||||
}
|
||||
|
||||
KeywordHighlighter::KeywordHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent), keywordFormat() {
|
||||
keywordFormat.setForeground(QColor(HIGHLIGHT_COLOR));
|
||||
}
|
||||
|
||||
void KeywordHighlighter::highlightBlock(const QString &text) {
|
||||
|
||||
if (keyword.isNull() || keyword.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index = text.indexOf(keyword, 0, Qt::CaseInsensitive);
|
||||
int length = keyword.length();
|
||||
|
||||
while (index >= 0) {
|
||||
setFormat(index, length, keywordFormat);
|
||||
index = text.indexOf(keyword, index + length, Qt::CaseInsensitive);
|
||||
}
|
||||
QString LogDialog::getCurrentLog() {
|
||||
return _logger->getLogData();
|
||||
}
|
||||
|
|
|
@ -12,64 +12,32 @@
|
|||
#ifndef hifi_LogDialog_h
|
||||
#define hifi_LogDialog_h
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMutex>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QCheckBox>
|
||||
#include <QSyntaxHighlighter>
|
||||
#include "BaseLogDialog.h"
|
||||
|
||||
#include <shared/AbstractLoggerInterface.h>
|
||||
class QCheckBox;
|
||||
class QPushButton;
|
||||
class QResizeEvent;
|
||||
class AbstractLoggerInterface;
|
||||
|
||||
class KeywordHighlighter : public QSyntaxHighlighter {
|
||||
class LogDialog : public BaseLogDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KeywordHighlighter(QTextDocument *parent = 0);
|
||||
QString keyword;
|
||||
|
||||
protected:
|
||||
void highlightBlock(const QString &text) override;
|
||||
|
||||
private:
|
||||
QTextCharFormat keywordFormat;
|
||||
|
||||
};
|
||||
|
||||
class LogDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LogDialog(QWidget*, AbstractLoggerInterface*);
|
||||
~LogDialog();
|
||||
|
||||
public slots:
|
||||
void appendLogLine(QString logLine);
|
||||
LogDialog(QWidget* parent, AbstractLoggerInterface* logger);
|
||||
|
||||
private slots:
|
||||
void handleSearchButton();
|
||||
void handleRevealButton();
|
||||
void handleExtraDebuggingCheckbox(const int);
|
||||
void handleSearchTextChanged(const QString);
|
||||
void handleExtraDebuggingCheckbox(int);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent*) override;
|
||||
void showEvent(QShowEvent*) override;
|
||||
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
QString getCurrentLog() override;
|
||||
|
||||
private:
|
||||
QPushButton* _searchButton;
|
||||
QLineEdit* _searchTextBox;
|
||||
QCheckBox* _extraDebuggingBox;
|
||||
QPushButton* _revealLogButton;
|
||||
QPlainTextEdit* _logTextBox;
|
||||
QString _searchTerm;
|
||||
KeywordHighlighter* _highlighter;
|
||||
|
||||
AbstractLoggerInterface* _logger;
|
||||
|
||||
void initControls();
|
||||
void showLogData();
|
||||
};
|
||||
|
||||
#endif // hifi_LogDialog_h
|
||||
|
|
85
libraries/entities/src/EntityScriptServerLogClient.cpp
Normal file
85
libraries/entities/src/EntityScriptServerLogClient.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// EntityScriptServerLogClient.cpp
|
||||
// interface/src
|
||||
//
|
||||
// Created by Clement Brisset on 2/1/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "EntityScriptServerLogClient.h"
|
||||
|
||||
EntityScriptServerLogClient::EntityScriptServerLogClient() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
|
||||
|
||||
QObject::connect(nodeList.data(), &NodeList::nodeActivated, this, &EntityScriptServerLogClient::nodeActivated);
|
||||
QObject::connect(nodeList.data(), &NodeList::nodeKilled, this, &EntityScriptServerLogClient::nodeKilled);
|
||||
|
||||
QObject::connect(nodeList.data(), &NodeList::canRezChanged, this, &EntityScriptServerLogClient::canRezChanged);
|
||||
}
|
||||
|
||||
void EntityScriptServerLogClient::connectNotify(const QMetaMethod& signal) {
|
||||
// This needs to be delayed or "receivers()" will return completely inconsistent values
|
||||
QMetaObject::invokeMethod(this, "connectionsChanged", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void EntityScriptServerLogClient::disconnectNotify(const QMetaMethod& signal) {
|
||||
// This needs to be delayed or "receivers()" will return completely inconsistent values
|
||||
QMetaObject::invokeMethod(this, "connectionsChanged", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void EntityScriptServerLogClient::connectionsChanged() {
|
||||
auto numReceivers = receivers(SIGNAL(receivedNewLogLines(QString)));
|
||||
if (!_subscribed && numReceivers > 0) {
|
||||
enableToEntityServerScriptLog(DependencyManager::get<NodeList>()->getThisNodeCanRez());
|
||||
} else if (_subscribed && numReceivers == 0) {
|
||||
enableToEntityServerScriptLog(false);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServerLogClient::enableToEntityServerScriptLog(bool enable) {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
if (auto node = nodeList->soloNodeOfType(NodeType::EntityScriptServer)) {
|
||||
auto packet = NLPacket::create(PacketType::EntityServerScriptLog, sizeof(bool), true);
|
||||
packet->writePrimitive(enable);
|
||||
nodeList->sendPacket(std::move(packet), *node);
|
||||
|
||||
if (_subscribed != enable) {
|
||||
if (enable) {
|
||||
emit receivedNewLogLines("====================== Subscribded to the Entity Script Server's log ======================");
|
||||
} else {
|
||||
emit receivedNewLogLines("==================== Unsubscribded from the Entity Script Server's log ====================");
|
||||
}
|
||||
}
|
||||
_subscribed = enable;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServerLogClient::handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
emit receivedNewLogLines(QString::fromUtf8(message->readAll()));
|
||||
}
|
||||
|
||||
void EntityScriptServerLogClient::nodeActivated(SharedNodePointer activatedNode) {
|
||||
if (_subscribed && activatedNode->getType() == NodeType::EntityScriptServer) {
|
||||
_subscribed = false;
|
||||
enableToEntityServerScriptLog(DependencyManager::get<NodeList>()->getThisNodeCanRez());
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServerLogClient::nodeKilled(SharedNodePointer killedNode) {
|
||||
if (killedNode->getType() == NodeType::EntityScriptServer) {
|
||||
emit receivedNewLogLines("====================== Connection to the Entity Script Server lost ======================");
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServerLogClient::canRezChanged(bool canRez) {
|
||||
auto numReceivers = receivers(SIGNAL(receivedNewLogLines(QString)));
|
||||
if (numReceivers > 0) {
|
||||
enableToEntityServerScriptLog(canRez);
|
||||
}
|
||||
}
|
46
libraries/entities/src/EntityScriptServerLogClient.h
Normal file
46
libraries/entities/src/EntityScriptServerLogClient.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// EntityScriptServerLogClient.h
|
||||
// interface/src
|
||||
//
|
||||
// Created by Clement Brisset on 2/1/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_EntityScriptServerLogClient_h
|
||||
#define hifi_EntityScriptServerLogClient_h
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <NodeList.h>
|
||||
|
||||
class EntityScriptServerLogClient : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EntityScriptServerLogClient();
|
||||
|
||||
signals:
|
||||
void receivedNewLogLines(QString logLines);
|
||||
|
||||
protected:
|
||||
void connectNotify(const QMetaMethod& signal) override;
|
||||
void disconnectNotify(const QMetaMethod& signal) override;
|
||||
|
||||
private slots:
|
||||
void enableToEntityServerScriptLog(bool enable);
|
||||
void handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
|
||||
void nodeActivated(SharedNodePointer activatedNode);
|
||||
void nodeKilled(SharedNodePointer killedNode);
|
||||
void canRezChanged(bool canRez);
|
||||
|
||||
void connectionsChanged();
|
||||
|
||||
private:
|
||||
bool _subscribed { false };
|
||||
};
|
||||
|
||||
#endif // hifi_EntityScriptServerLogClient_h
|
|
@ -162,4 +162,4 @@ void EntityScriptClient::forceFailureOfPendingRequests(SharedNodePointer node) {
|
|||
messageMapIt->second.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,8 @@ public:
|
|||
EntityScriptGetStatusReply,
|
||||
ReloadEntityServerScript,
|
||||
EntityPhysics,
|
||||
LAST_PACKET_TYPE = EntityPhysics
|
||||
EntityServerScriptLog,
|
||||
LAST_PACKET_TYPE = EntityServerScriptLog
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
|
|||
prefixString.append(QString(" [%1]").arg(_targetName));
|
||||
}
|
||||
|
||||
QString logMessage = QString("%1 %2").arg(prefixString, message.split("\n").join("\n" + prefixString + " "));
|
||||
QString logMessage = QString("%1 %2").arg(prefixString, message.split('\n').join('\n' + prefixString + " "));
|
||||
fprintf(stdout, "%s\n", qPrintable(logMessage));
|
||||
return logMessage;
|
||||
}
|
||||
|
|
28
scripts/developer/debugging/essDebugWindow.js
Normal file
28
scripts/developer/debugging/essDebugWindow.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// essDebugWindow.js
|
||||
//
|
||||
// Created by Clement Brisset on 2/2/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
|
||||
// Set up the qml ui
|
||||
var qml = Script.resolvePath('debugWindow.qml');
|
||||
var window = new OverlayWindow({
|
||||
title: 'Entity Script Server Log Window',
|
||||
source: qml,
|
||||
width: 400, height: 900,
|
||||
});
|
||||
window.setPosition(25, 50);
|
||||
window.closed.connect(function() { Script.stop(); });
|
||||
|
||||
EntityScriptServerLog.receivedNewLogLines.connect(function(message) {
|
||||
window.sendToQml(message.trim());
|
||||
});
|
||||
|
||||
|
||||
}()); // END LOCAL_SCOPE
|
Loading…
Reference in a new issue