diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cf865ce299..ff320340bf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -174,6 +174,12 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : listenPort = atoi(portStr); } + // start the nodeThread so its event loop is running + _nodeThread->start(); + + // make sure the node thread is given highest priority + _nodeThread->setPriority(QThread::TimeCriticalPriority); + // put the NodeList and datagram processing on the node thread NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort); @@ -182,12 +188,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), _datagramProcessor, SLOT(processDatagrams())); - - // make sure the node thread is given highest priority - _nodeThread->setPriority(QThread::TimeCriticalPriority); - - // start the nodeThread so its event loop is running - _nodeThread->start(); // put the audio processing on a separate thread QThread* audioThread = new QThread(this); @@ -236,7 +236,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : nodeList->setNodeTypesOfInterest(nodeTypesOfInterest, sizeof(nodeTypesOfInterest)); // move the silentNodeTimer to the _nodeThread - QTimer* silentNodeTimer = new QTimer(this); + QTimer* silentNodeTimer = new QTimer(); connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); silentNodeTimer->moveToThread(_nodeThread); silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); @@ -282,17 +282,35 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : Application::~Application() { qInstallMessageHandler(NULL); - + // make sure we don't call the idle timer any more delete idleTimer; + Menu::getInstance()->saveSettings(); + + _rearMirrorTools->saveSettings(_settings); + _settings->sync(); + + // let the avatar mixer know we're out + NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1); + // ask the datagram processing thread to quit and wait until it is done - _nodeThread->thread()->quit(); - _nodeThread->thread()->wait(); - + _nodeThread->quit(); + _nodeThread->wait(); + // ask the audio thread to quit and wait until it is done _audio.thread()->quit(); _audio.thread()->wait(); + + _voxelProcessor.terminate(); + _voxelHideShowThread.terminate(); + _voxelEditSender.terminate(); + _particleEditSender.terminate(); + if (_persistThread) { + _persistThread->terminate(); + _persistThread->deleteLater(); + _persistThread = NULL; + } storeSizeAndPosition(); saveScripts(); @@ -377,9 +395,6 @@ void Application::initializeGL() { qDebug("Voxel parsing thread created."); } - // call terminate before exiting - connect(this, SIGNAL(aboutToQuit()), SLOT(terminate())); - // call our timer function every second QTimer* timer = new QTimer(this); connect(timer, SIGNAL(timeout()), SLOT(timer())); @@ -1412,28 +1427,6 @@ void Application::idle() { } } -void Application::terminate() { - // Close serial port - // close(serial_fd); - - Menu::getInstance()->saveSettings(); - _rearMirrorTools->saveSettings(_settings); - _settings->sync(); - - // let the avatar mixer know we're out - NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1); - - _voxelProcessor.terminate(); - _voxelHideShowThread.terminate(); - _voxelEditSender.terminate(); - _particleEditSender.terminate(); - if (_persistThread) { - _persistThread->terminate(); - _persistThread->deleteLater(); - _persistThread = NULL; - } -} - void Application::checkBandwidthMeterClick() { // ... to be called upon button release diff --git a/interface/src/Application.h b/interface/src/Application.h index 514591e1df..ba25db928f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -230,7 +230,6 @@ private slots: void timer(); void idle(); - void terminate(); void setFullscreen(bool fullscreen); void setEnable3DTVMode(bool enable3DTVMode); diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 65993cb275..6bb582fcd5 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -236,7 +236,11 @@ int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, node->setLastHeardMicrostamp(usecTimestampNow()); if (!senderSockAddr.isNull()) { - activateSocketFromNodeCommunication(senderSockAddr); + if (senderSockAddr == node->getPublicSocket()) { + node->activatePublicSocket(); + } else if (senderSockAddr == node->getLocalSocket()) { + node->activateLocalSocket(); + } } if (node->getActiveSocket() || senderSockAddr.isNull()) { @@ -754,7 +758,7 @@ unsigned NodeList::broadcastToNodes(unsigned char* broadcastData, size_t dataByt } void NodeList::pingInactiveNodes() { - foreach (const SharedNodePointer& node, _nodeHash) { + foreach (const SharedNodePointer& node, getNodeHash()) { if (!node->getActiveSocket()) { // we don't have an active link to this node, ping it to set that up pingPublicAndLocalSocketsForInactiveNode(node.data()); @@ -791,7 +795,7 @@ void NodeList::activateSocketFromNodeCommunication(const HifiSockAddr& nodeAddre SharedNodePointer NodeList::soloNodeOfType(char nodeType) { if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES)) != NULL) { - foreach (const SharedNodePointer& node, _nodeHash) { + foreach (const SharedNodePointer& node, getNodeHash()) { if (node->getType() == nodeType) { return node; } diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 9ac6c5970c..851110f0b4 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -87,7 +87,6 @@ public: int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; } - void clear(); void reset(); void setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest); @@ -163,6 +162,7 @@ private: void timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData); void resetDomainData(char domainField[], const char* domainData); void domainLookup(); + void clear(); }; #endif /* defined(__hifi__NodeList__) */