From f230eeadabe7e4584ee43bd7f3f1c8758329d65a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 13 Nov 2013 12:37:40 -0800 Subject: [PATCH 1/4] added decodeOctCode to voxel-edit --- voxel-edit/src/main.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/voxel-edit/src/main.cpp b/voxel-edit/src/main.cpp index 5787caabac..5f67a46163 100644 --- a/voxel-edit/src/main.cpp +++ b/voxel-edit/src/main.cpp @@ -272,7 +272,30 @@ int main(int argc, const char * argv[]) } else { qDebug() << "Unexpected number of parameters for getOctCode\n"; } + return 0; + } + + const char* DECODE_OCTCODE = "--decodeOctCode"; + const char* decodeParam = getCmdOption(argc, argv, DECODE_OCTCODE); + if (decodeParam) { + + QString decodeParamsString(decodeParam); + unsigned char* octalCodeToDecode = hexStringToOctalCode(decodeParamsString); + + VoxelPositionSize details; + voxelDetailsForCode(octalCodeToDecode, details); + + delete[] octalCodeToDecode; + + qDebug() << "octal code to decode: " << decodeParamsString << "\n"; + qDebug() << "Details for Octal Code:\n"; + qDebug() << " x:" << details.x << "[" << details.x * TREE_SCALE << "]" << "\n"; + qDebug() << " y:" << details.y << "[" << details.y * TREE_SCALE << "]" << "\n"; + qDebug() << " z:" << details.z << "[" << details.z * TREE_SCALE << "]" << "\n"; + qDebug() << " s:" << details.s << "[" << details.s * TREE_SCALE << "]" << "\n"; + return 0; } + // Handles taking and SVO and splitting it into multiple SVOs based on // jurisdiction details From 73c1ef99972bb8ffad6657ec2af6ca007d1ccb7d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 17 Nov 2013 00:01:32 -0800 Subject: [PATCH 2/4] fix macos menu placement for About, Preferences, and Quit --- interface/src/Menu.cpp | 14 ++++++++++---- interface/src/Menu.h | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 69ea9d010e..12eef18b96 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -72,7 +72,8 @@ Menu::Menu() : MenuOption::AboutApp, 0, this, - SLOT(aboutApp())); + SLOT(aboutApp()), + QAction::AboutRole); #endif (addActionToQMenuAndActionHash(fileMenu, @@ -120,7 +121,9 @@ Menu::Menu() : MenuOption::Quit, Qt::CTRL | Qt::Key_Q, appInstance, - SLOT(quit())); + SLOT(quit()), + QAction::QuitRole); + QMenu* editMenu = addMenu("Edit"); @@ -128,7 +131,8 @@ Menu::Menu() : MenuOption::Preferences, Qt::CTRL | Qt::Key_Comma, this, - SLOT(editPreferences())); + SLOT(editPreferences()), + QAction::PreferencesRole); addDisabledActionAndSeparator(editMenu, "Voxels"); @@ -679,7 +683,8 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu, const QString actionName, const QKeySequence& shortcut, const QObject* receiver, - const char* member) { + const char* member, + QAction::MenuRole role) { QAction* action; if (receiver && member) { @@ -688,6 +693,7 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu, action = destinationMenu->addAction(actionName); action->setShortcut(shortcut); } + action->setMenuRole(role); _actionHash.insert(actionName, action); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index dd1789689b..928a5dfc58 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -113,7 +113,9 @@ private: const QString actionName, const QKeySequence& shortcut = 0, const QObject* receiver = NULL, - const char* member = NULL); + const char* member = NULL, + QAction::MenuRole role = QAction::NoRole); + QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, const QString actionName, const QKeySequence& shortcut = 0, From 6881d9fb363457cd60a243e8f808b93942bf24b8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 19 Nov 2013 22:57:42 -0800 Subject: [PATCH 3/4] fix to crash in client side VoxelSceneStats crash --- interface/src/Application.cpp | 22 +---- interface/src/Application.h | 3 + interface/src/ui/VoxelStatsDialog.cpp | 3 + libraries/voxels/src/VoxelSceneStats.cpp | 115 +++++++++++++++++++++++ libraries/voxels/src/VoxelSceneStats.h | 6 ++ 5 files changed, 132 insertions(+), 17 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 628a91c69b..385e7bc8af 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4188,9 +4188,11 @@ void Application::nodeKilled(Node* node) { } // also clean up scene stats for that server + _voxelSceneStatsLock.lockForWrite(); if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) { _voxelServerSceneStats.erase(nodeUUID); } + _voxelSceneStatsLock.unlock(); } else if (node->getLinkedData() == _lookatTargetAvatar) { _lookatTargetAvatar = NULL; } @@ -4211,27 +4213,13 @@ int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLeng QUuid nodeUUID = voxelServer->getUUID(); // now that we know the node ID, let's add these stats to the stats for that node... + _voxelSceneStatsLock.lockForWrite(); if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) { - VoxelSceneStats& oldStats = _voxelServerSceneStats[nodeUUID]; - - // this if construct is a little strange because we aren't quite using it yet. But - // we want to keep this logic in here for now because we plan to use it soon to determine - // additional network optimization states and better rate control - if (!oldStats.isMoving() && temp.isMoving()) { - // we think we are starting to move - _voxelServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength); - } else if (oldStats.isMoving() && !temp.isMoving()) { - // we think we are done moving - _voxelServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength); - } else if (!oldStats.isMoving() && !temp.isMoving()) { - // we think we are still not moving - } else { - // we think we are still moving - } - + _voxelServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength); } else { _voxelServerSceneStats[nodeUUID] = temp; } + _voxelSceneStatsLock.unlock(); VoxelPositionSize rootDetails; voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails); diff --git a/interface/src/Application.h b/interface/src/Application.h index 78530ecea2..21e3479288 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -136,6 +136,8 @@ public: Swatch* getSwatch() { return &_swatch; } QMainWindow* getWindow() { return _window; } NodeToVoxelSceneStats* getVoxelSceneStats() { return &_voxelServerSceneStats; } + void lockVoxelSceneStats() { _voxelSceneStatsLock.lockForRead(); } + void unlockVoxelSceneStats() { _voxelSceneStatsLock.unlock(); } QNetworkAccessManager* getNetworkAccessManager() { return _networkAccessManager; } GeometryCache* getGeometryCache() { return &_geometryCache; } @@ -454,6 +456,7 @@ private: NodeToJurisdictionMap _voxelServerJurisdictions; NodeToVoxelSceneStats _voxelServerSceneStats; + QReadWriteLock _voxelSceneStatsLock; std::vector _voxelFades; }; diff --git a/interface/src/ui/VoxelStatsDialog.cpp b/interface/src/ui/VoxelStatsDialog.cpp index ab1371f53f..ff082e4b02 100644 --- a/interface/src/ui/VoxelStatsDialog.cpp +++ b/interface/src/ui/VoxelStatsDialog.cpp @@ -154,6 +154,8 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) { unsigned long totalNodes = 0; unsigned long totalInternal = 0; unsigned long totalLeaves = 0; + + Application::getInstance()->lockVoxelSceneStats(); NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getVoxelSceneStats(); for(NodeToVoxelSceneStatsIterator i = sceneStats->begin(); i != sceneStats->end(); i++) { //const QUuid& uuid = i->first; @@ -176,6 +178,7 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) { sendingMode << "S"; } } + Application::getInstance()->unlockVoxelSceneStats(); sendingMode << " - " << serverCount << " servers"; if (movingServerCount > 0) { sendingMode << " "; diff --git a/libraries/voxels/src/VoxelSceneStats.cpp b/libraries/voxels/src/VoxelSceneStats.cpp index cce7d7d7b3..fa5968a6e3 100644 --- a/libraries/voxels/src/VoxelSceneStats.cpp +++ b/libraries/voxels/src/VoxelSceneStats.cpp @@ -28,6 +28,97 @@ VoxelSceneStats::VoxelSceneStats() : _isStarted = false; } +// copy constructor +VoxelSceneStats::VoxelSceneStats(const VoxelSceneStats& other) : +_jurisdictionRoot(NULL) { + copyFromOther(other); +} + +// copy assignment +VoxelSceneStats& VoxelSceneStats::operator=(const VoxelSceneStats& other) { + copyFromOther(other); + return *this; +} + +void VoxelSceneStats::copyFromOther(const VoxelSceneStats& other) { + _totalEncodeTime = other._totalEncodeTime; + _encodeStart = other._encodeStart; + + _packets = other._packets; + _bytes = other._bytes; + _passes = other._passes; + + _totalVoxels = other._totalVoxels; + _totalInternal = other._totalInternal; + _totalLeaves = other._totalLeaves; + + _traversed = other._traversed; + _internal = other._internal; + _leaves = other._leaves; + + _skippedDistance = other._skippedDistance; + _internalSkippedDistance = other._internalSkippedDistance; + _leavesSkippedDistance = other._leavesSkippedDistance; + + _skippedOutOfView = other._skippedOutOfView; + _internalSkippedOutOfView = other._internalSkippedOutOfView; + _leavesSkippedOutOfView = other._leavesSkippedOutOfView; + + _skippedWasInView = other._skippedWasInView; + _internalSkippedWasInView = other._internalSkippedWasInView; + _leavesSkippedWasInView = other._leavesSkippedWasInView; + + _skippedNoChange = other._skippedNoChange; + _internalSkippedNoChange = other._internalSkippedNoChange; + _leavesSkippedNoChange = other._leavesSkippedNoChange; + + _skippedOccluded = other._skippedOccluded; + _internalSkippedOccluded = other._internalSkippedOccluded; + _leavesSkippedOccluded = other._leavesSkippedOccluded; + + _colorSent = other._colorSent; + _internalColorSent = other._internalColorSent; + _leavesColorSent = other._leavesColorSent; + + _didntFit = other._didntFit; + _internalDidntFit = other._internalDidntFit; + _leavesDidntFit = other._leavesDidntFit; + + _colorBitsWritten = other._colorBitsWritten; + _existsBitsWritten = other._existsBitsWritten; + _existsInPacketBitsWritten = other._existsInPacketBitsWritten; + _treesRemoved = other._treesRemoved; + + // before copying the jurisdictions, delete any current values... + if (_jurisdictionRoot) { + delete[] _jurisdictionRoot; + _jurisdictionRoot = NULL; + } + for (int i=0; i < _jurisdictionEndNodes.size(); i++) { + if (_jurisdictionEndNodes[i]) { + delete[] _jurisdictionEndNodes[i]; + } + } + _jurisdictionEndNodes.clear(); + + // Now copy the values from the other + if (other._jurisdictionRoot) { + int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(other._jurisdictionRoot)); + _jurisdictionRoot = new unsigned char[bytes]; + memcpy(_jurisdictionRoot, other._jurisdictionRoot, bytes); + } + for (int i=0; i < other._jurisdictionEndNodes.size(); i++) { + unsigned char* endNodeCode = other._jurisdictionEndNodes[i]; + if (endNodeCode) { + int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode)); + unsigned char* endNodeCodeCopy = new unsigned char[bytes]; + memcpy(endNodeCodeCopy, endNodeCode, bytes); + _jurisdictionEndNodes.push_back(endNodeCodeCopy); + } + } +} + + VoxelSceneStats::~VoxelSceneStats() { reset(); } @@ -48,6 +139,15 @@ void VoxelSceneStats::sceneStarted(bool isFullScene, bool isMoving, VoxelNode* r delete[] _jurisdictionRoot; _jurisdictionRoot = NULL; } + // clear existing endNodes before copying new ones... + for (int i=0; i < _jurisdictionEndNodes.size(); i++) { + if (_jurisdictionEndNodes[i]) { + delete[] _jurisdictionEndNodes[i]; + } + } + _jurisdictionEndNodes.clear(); + + // setup jurisdictions if (jurisdictionMap) { unsigned char* jurisdictionRoot = jurisdictionMap->getRootOctalCode(); if (jurisdictionRoot) { @@ -56,6 +156,7 @@ void VoxelSceneStats::sceneStarted(bool isFullScene, bool isMoving, VoxelNode* r memcpy(_jurisdictionRoot, jurisdictionRoot, bytes); } + // copy new endNodes... for (int i=0; i < jurisdictionMap->getEndNodeCount(); i++) { unsigned char* endNodeCode = jurisdictionMap->getEndNodeOctalCode(i); if (endNodeCode) { @@ -436,6 +537,20 @@ int VoxelSceneStats::unpackFromMessage(unsigned char* sourceBuffer, int availabl memcpy(&_treesRemoved, sourceBuffer, sizeof(_treesRemoved)); sourceBuffer += sizeof(_treesRemoved); + // before allocating new juridiction, clean up existing ones + if (_jurisdictionRoot) { + delete[] _jurisdictionRoot; + _jurisdictionRoot = NULL; + } + + // clear existing endNodes before copying new ones... + for (int i=0; i < _jurisdictionEndNodes.size(); i++) { + if (_jurisdictionEndNodes[i]) { + delete[] _jurisdictionEndNodes[i]; + } + } + _jurisdictionEndNodes.clear(); + // read the root jurisdiction int bytes = 0; memcpy(&bytes, sourceBuffer, sizeof(bytes)); diff --git a/libraries/voxels/src/VoxelSceneStats.h b/libraries/voxels/src/VoxelSceneStats.h index c93633fea7..245fe430dd 100644 --- a/libraries/voxels/src/VoxelSceneStats.h +++ b/libraries/voxels/src/VoxelSceneStats.h @@ -27,6 +27,9 @@ public: ~VoxelSceneStats(); void reset(); + VoxelSceneStats(const VoxelSceneStats& other); // copy constructor + VoxelSceneStats& operator= (const VoxelSceneStats& other); // copy assignment + /// Call when beginning the computation of a scene. Initializes internal structures void sceneStarted(bool fullScene, bool moving, VoxelNode* root, JurisdictionMap* jurisdictionMap); @@ -144,6 +147,9 @@ public: unsigned long getTotalLeaves() const { return _totalLeaves; } private: + + void copyFromOther(const VoxelSceneStats& other); + bool _isReadyToSend; unsigned char _statsMessage[MAX_PACKET_SIZE]; int _statsMessageLength; From cb56ad2e2f3710f2ad2b34d3e23ca37ae790a27d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 21 Nov 2013 10:43:40 -0800 Subject: [PATCH 4/4] fix a couple of bugs in display of voxel stats on server status --- .../voxel-server-library/src/VoxelServer.cpp | 31 ++++++++++++------- .../src/VoxelServerPacketProcessor.h | 4 +-- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index 16a2c38c3a..cf650117f2 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -189,17 +189,22 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { // display voxel file load time if (theServer->isInitialLoadComplete()) { - tm* voxelsLoadedAtLocal = localtime(theServer->getLoadCompleted()); - const int MAX_TIME_LENGTH = 128; - char buffer[MAX_TIME_LENGTH]; - strftime(buffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", voxelsLoadedAtLocal); - mg_printf(connection, "Voxels Loaded At: %s", buffer); + time_t* loadCompleted = theServer->getLoadCompleted(); + if (loadCompleted) { + tm* voxelsLoadedAtLocal = localtime(loadCompleted); + const int MAX_TIME_LENGTH = 128; + char buffer[MAX_TIME_LENGTH]; + strftime(buffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", voxelsLoadedAtLocal); + mg_printf(connection, "Voxels Loaded At: %s", buffer); - // Convert now to tm struct for UTC - tm* voxelsLoadedAtUTM = gmtime(theServer->getLoadCompleted()); - if (gmtm != NULL) { - strftime(buffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", voxelsLoadedAtUTM); - mg_printf(connection, " [%s UTM] ", buffer); + // Convert now to tm struct for UTC + tm* voxelsLoadedAtUTM = gmtime(theServer->getLoadCompleted()); + if (gmtm != NULL) { + strftime(buffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", voxelsLoadedAtUTM); + mg_printf(connection, " [%s UTM] ", buffer); + } + } else { + mg_printf(connection, "%s", "Voxel Persist Disabled...\r\n"); } mg_printf(connection, "%s", "\r\n"); @@ -259,7 +264,7 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { // display inbound packet stats mg_printf(connection, "%s", "Voxel Edit Statistics... [RESET]\r\n"); - uint64_t averageTransitTimePerPacket = theServer->_voxelServerPacketProcessor->getAverateTransitTimePerPacket(); + uint64_t averageTransitTimePerPacket = theServer->_voxelServerPacketProcessor->getAverageTransitTimePerPacket(); uint64_t averageProcessTimePerPacket = theServer->_voxelServerPacketProcessor->getAverageProcessTimePerPacket(); uint64_t averageLockWaitTimePerPacket = theServer->_voxelServerPacketProcessor->getAverageLockWaitTimePerPacket(); uint64_t averageProcessTimePerVoxel = theServer->_voxelServerPacketProcessor->getAverageProcessTimePerVoxel(); @@ -297,7 +302,7 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { mg_printf(connection, "\r\n Stats for sender %d uuid: %s\r\n", senderNumber, senderID.toString().toLocal8Bit().constData()); - averageTransitTimePerPacket = senderStats.getAverateTransitTimePerPacket(); + averageTransitTimePerPacket = senderStats.getAverageTransitTimePerPacket(); averageProcessTimePerPacket = senderStats.getAverageProcessTimePerPacket(); averageLockWaitTimePerPacket = senderStats.getAverageLockWaitTimePerPacket(); averageProcessTimePerVoxel = senderStats.getAverageProcessTimePerVoxel(); @@ -305,6 +310,8 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { totalVoxelsProcessed = senderStats.getTotalVoxelsProcessed(); totalPacketsProcessed = senderStats.getTotalPacketsProcessed(); + averageVoxelsPerPacket = totalPacketsProcessed == 0 ? 0 : totalVoxelsProcessed / totalPacketsProcessed; + mg_printf(connection, " Total Inbound Packets: %s packets\r\n", locale.toString((uint)totalPacketsProcessed).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData()); mg_printf(connection, " Total Inbound Voxels: %s voxels\r\n", diff --git a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h index 108e101417..2408e0dd60 100644 --- a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h +++ b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h @@ -20,7 +20,7 @@ class SingleSenderStats { public: SingleSenderStats(); - uint64_t getAverateTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; } + uint64_t getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; } uint64_t getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; } uint64_t getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; } uint64_t getTotalVoxelsProcessed() const { return _totalVoxelsInPacket; } @@ -48,7 +48,7 @@ class VoxelServerPacketProcessor : public ReceivedPacketProcessor { public: VoxelServerPacketProcessor(VoxelServer* myServer); - uint64_t getAverateTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; } + uint64_t getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; } uint64_t getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; } uint64_t getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; } uint64_t getTotalVoxelsProcessed() const { return _totalVoxelsInPacket; }