mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
First draft for entity script server log streaming
This commit is contained in:
parent
74f10a1e7f
commit
fcb74bce10
7 changed files with 155 additions and 12 deletions
|
@ -27,6 +27,7 @@ public:
|
|||
QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort,
|
||||
quint16 assignmentMonitorPort);
|
||||
~AssignmentClient();
|
||||
|
||||
private slots:
|
||||
void sendAssignmentRequest();
|
||||
void assignmentCompleted();
|
||||
|
|
|
@ -27,9 +27,30 @@
|
|||
#include "ClientServerUtils.h"
|
||||
#include "../entities/AssignmentParentFinder.h"
|
||||
|
||||
|
||||
#include <LogHandler.h>
|
||||
#include <mutex>
|
||||
|
||||
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,18 @@ 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 / 50;
|
||||
auto timer = new QTimer(this);
|
||||
timer->setTimerType(Qt::PreciseTimer);
|
||||
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";
|
||||
|
@ -146,6 +179,60 @@ 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.
|
||||
if (senderNode->getCanRez() || senderNode->getCanRezTmp()) {
|
||||
bool enable = false;
|
||||
message->readPrimitive(&enable);
|
||||
qInfo() << "======== Got log packet:" << enable;
|
||||
|
||||
if (enable) {
|
||||
_logListeners.insert(senderNode->getUUID());
|
||||
} else {
|
||||
_logListeners.erase(senderNode->getUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::pushLogs() {
|
||||
std::string buffer;
|
||||
{
|
||||
Lock lock(logBufferMutex);
|
||||
std::swap(logBuffer, buffer);
|
||||
}
|
||||
|
||||
if (buffer.empty()) {
|
||||
return;
|
||||
}
|
||||
if (_logListeners.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto packet = NLPacket::create(PacketType::EntityServerScriptLog, buffer.size(), true);
|
||||
packet->write(buffer.data(), buffer.size());
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
auto last = --std::end(_logListeners);
|
||||
for (auto it = std::begin(_logListeners); it != last; ++it) {
|
||||
auto node = nodeList->nodeWithUUID(*it);
|
||||
if (node && node->getActiveSocket()) {
|
||||
auto copy = NLPacket::createCopy(*packet);
|
||||
nodeList->sendPacket(std::move(copy), *node);
|
||||
} else {
|
||||
qWarning() << "Node not found";
|
||||
}
|
||||
}
|
||||
|
||||
auto node = nodeList->nodeWithUUID(*last);
|
||||
if (node && node->getActiveSocket()) {
|
||||
nodeList->sendPacket(std::move(packet), *node);
|
||||
} else {
|
||||
qWarning() << "Node not found";
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::run() {
|
||||
// make sure we request our script once the agent connects to the domain
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
@ -347,15 +434,27 @@ void EntityScriptServer::checkAndCallPreload(const EntityItemID& entityID, const
|
|||
}
|
||||
|
||||
void EntityScriptServer::nodeKilled(SharedNodePointer killedNode) {
|
||||
if (!_shuttingDown && killedNode->getType() == NodeType::EntityServer) {
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->unloadAllEntityScripts();
|
||||
_entitiesScriptEngine->stop();
|
||||
switch (killedNode->getType()) {
|
||||
case NodeType::EntityServer: {
|
||||
if (!_shuttingDown) {
|
||||
if (_entitiesScriptEngine) {
|
||||
_entitiesScriptEngine->unloadAllEntityScripts();
|
||||
_entitiesScriptEngine->stop();
|
||||
}
|
||||
|
||||
resetEntitiesScriptEngine();
|
||||
|
||||
_entityViewer.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
resetEntitiesScriptEngine();
|
||||
|
||||
_entityViewer.clear();
|
||||
case NodeType::Agent: {
|
||||
_logListeners.erase(killedNode->getUUID());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,10 @@
|
|||
#ifndef hifi_EntityScriptServer_h
|
||||
#define hifi_EntityScriptServer_h
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include <EntityEditPacketSender.h>
|
||||
#include <EntityTreeHeadlessViewer.h>
|
||||
|
@ -28,6 +31,7 @@ class EntityScriptServer : public ThreadedAssignment {
|
|||
|
||||
public:
|
||||
EntityScriptServer(ReceivedMessage& message);
|
||||
~EntityScriptServer();
|
||||
|
||||
virtual void aboutToFinish() override;
|
||||
|
||||
|
@ -48,6 +52,10 @@ private slots:
|
|||
void handleSettings();
|
||||
void updateEntityPPS();
|
||||
|
||||
void handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
|
||||
void pushLogs();
|
||||
|
||||
private:
|
||||
void negotiateAudioFormat();
|
||||
void selectAudioFormat(const QString& selectedCodecName);
|
||||
|
@ -71,6 +79,8 @@ private:
|
|||
int _maxEntityPPS { DEFAULT_MAX_ENTITY_PPS };
|
||||
int _entityPPSPerScript { DEFAULT_ENTITY_PPS_PER_SCRIPT };
|
||||
|
||||
std::set<QUuid> _logListeners;
|
||||
|
||||
QString _selectedCodecName;
|
||||
CodecPluginPointer _codec;
|
||||
Encoder* _encoder { nullptr };
|
||||
|
|
|
@ -46,6 +46,9 @@ int qTextBlockMeta = qRegisterMetaType<QTextBlock>("QTextBlock");
|
|||
|
||||
LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : QDialog(parent, Qt::Window) {
|
||||
|
||||
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
|
||||
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
|
||||
|
||||
_logger = logger;
|
||||
setWindowTitle("Log");
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
@ -64,7 +67,7 @@ LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : QDialog
|
|||
move(screen.center() - rect().center());
|
||||
setMinimumWidth(MINIMAL_WIDTH);
|
||||
|
||||
connect(_logger, SIGNAL(logReceived(QString)), this, SLOT(appendLogLine(QString)), Qt::QueuedConnection);
|
||||
//connect(_logger, SIGNAL(logReceived(QString)), this, SLOT(appendLogLine(QString)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
LogDialog::~LogDialog() {
|
||||
|
@ -97,7 +100,8 @@ void LogDialog::initControls() {
|
|||
_extraDebuggingBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
_extraDebuggingBox->show();
|
||||
connect(_extraDebuggingBox, SIGNAL(stateChanged(int)), SLOT(handleExtraDebuggingCheckbox(int)));
|
||||
//connect(_extraDebuggingBox, SIGNAL(stateChanged(int)), SLOT(handleExtraDebuggingCheckbox(int)));
|
||||
connect(_extraDebuggingBox, &QCheckBox::stateChanged, this, &LogDialog::enableToEntityServerScriptLog);
|
||||
|
||||
_revealLogButton = new QPushButton("Reveal log file", this);
|
||||
// set object name for css styling
|
||||
|
@ -156,6 +160,31 @@ void LogDialog::showLogData() {
|
|||
_logTextBox->ensureCursorVisible();
|
||||
}
|
||||
|
||||
|
||||
void LogDialog::enableToEntityServerScriptLog(bool enable) {
|
||||
qDebug() << Q_FUNC_INFO << 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 (enable) {
|
||||
appendLogLine("====================== Subscribded to the Entity Script Server's log ======================");
|
||||
} else {
|
||||
appendLogLine("==================== Unsubscribded from the Entity Script Server's log ====================");
|
||||
}
|
||||
} else {
|
||||
qWarning() << "Entity Script Server not found";
|
||||
}
|
||||
}
|
||||
|
||||
void LogDialog::handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
auto lines = QString::fromUtf8(message->readAll());
|
||||
QMetaObject::invokeMethod(this, "appendLogLine", Q_ARG(QString, lines));
|
||||
}
|
||||
|
||||
KeywordHighlighter::KeywordHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent), keywordFormat() {
|
||||
keywordFormat.setForeground(QColor(HIGHLIGHT_COLOR));
|
||||
}
|
||||
|
|
|
@ -53,6 +53,9 @@ private slots:
|
|||
void handleExtraDebuggingCheckbox(const int);
|
||||
void handleSearchTextChanged(const QString);
|
||||
|
||||
void enableToEntityServerScriptLog(bool enable);
|
||||
void handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent*) override;
|
||||
void showEvent(QShowEvent*) override;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue