Showing the changes to interface/src/Application.cpp (1 of 107 files). Show all
Unified · Split
| @@ -308,7 +308,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 307 unmodified lines | ||
| 308 | 308 | _window(new MainWindow(desktop())), |
| 309 | 309 | _toolWindow(NULL), |
| 310 | 310 | _friendsWindow(NULL), |
| 311 | − _datagramProcessor(), | |
| 312 | 311 | _undoStack(), |
| 313 | 312 | _undoStackScriptingInterface(&_undoStack), |
| 314 | 313 | _frameCount(0), |
| @@ -381,19 +380,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 66 unmodified lines | ||
| 381 | 380 | |
| 382 | 381 | // start the nodeThread so its event loop is running |
| 383 | 382 | QThread* nodeThread = new QThread(this); |
| 384 | − nodeThread->setObjectName("Datagram Processor Thread"); | |
| 383 | + nodeThread->setObjectName("NodeList Thread"); | |
| 385 | 384 | nodeThread->start(); |
| 386 | 385 | |
| 387 | 386 | // make sure the node thread is given highest priority |
| 388 | 387 | nodeThread->setPriority(QThread::TimeCriticalPriority); |
| 389 | 388 | |
| 390 | − _datagramProcessor = new DatagramProcessor(nodeList.data()); | |
| 391 | − | |
| 392 | − // have the NodeList use deleteLater from DM customDeleter | |
| 393 | − nodeList->setCustomDeleter([](Dependency* dependency) { | |
| 394 | − static_cast<NodeList*>(dependency)->deleteLater(); | |
| 395 | − }); | |
| 396 | − | |
| 397 | 389 | // setup a timer for domain-server check ins |
| 398 | 390 | QTimer* domainCheckInTimer = new QTimer(nodeList.data()); |
| 399 | 391 | connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn); |
| @@ -409,9 +401,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 9 unmodified lines | ||
| 409 | 401 | ResourceCache* geometryCache = geometryCacheP.data(); |
| 410 | 402 | connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets); |
| 411 | 403 | |
| 412 | − // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal | |
| 413 | − connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _datagramProcessor, &DatagramProcessor::processDatagrams); | |
| 414 | − | |
| 415 | 404 | // put the audio processing on a separate thread |
| 416 | 405 | QThread* audioThread = new QThread(); |
| 417 | 406 | audioThread->setObjectName("Audio Thread"); |
| @@ -422,14 +411,27 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 4 unmodified lines | ||
| 422 | 411 | audioIO->setOrientationGetter(getOrientationForAudio); |
| 423 | 412 | |
| 424 | 413 | audioIO->moveToThread(audioThread); |
| 414 | + | |
| 415 | + auto& audioScriptingInterface = AudioScriptingInterface::getInstance(); | |
| 416 | + | |
| 425 | 417 | connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start); |
| 426 | 418 | connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit); |
| 427 | 419 | connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); |
| 428 | 420 | connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled); |
| 429 | − connect(audioIO.data(), &AudioClient::receivedFirstPacket, | |
| 430 | − &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::receivedFirstPacket); | |
| 431 | − connect(audioIO.data(), &AudioClient::disconnected, | |
| 432 | − &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::disconnected); | |
| 421 | + connect(audioIO.data(), &AudioClient::mutedByMixer, &audioScriptingInterface, &AudioScriptingInterface::mutedByMixer); | |
| 422 | + connect(audioIO.data(), &AudioClient::receivedFirstPacket, &audioScriptingInterface, &AudioScriptingInterface::receivedFirstPacket); | |
| 423 | + connect(audioIO.data(), &AudioClient::disconnected, &audioScriptingInterface, &AudioScriptingInterface::disconnected); | |
| 424 | + connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) { | |
| 425 | + auto audioClient = DependencyManager::get<AudioClient>(); | |
| 426 | + float distance = glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), | |
| 427 | + position); | |
| 428 | + bool shouldMute = !audioClient->isMuted() && (distance < radius); | |
| 429 | + | |
| 430 | + if (shouldMute) { | |
| 431 | + audioClient->toggleMute(); | |
| 432 | + AudioScriptingInterface::getInstance().environmentMuted(); | |
| 433 | + } | |
| 434 | + }); | |
| 433 | 435 | |
| 434 | 436 | audioThread->start(); |
| 435 | 437 | |
| @@ -462,7 +464,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 26 unmodified lines | ||
| 462 | 464 | connect(nodeList.data(), &NodeList::uuidChanged, _myAvatar, &MyAvatar::setSessionUUID); |
| 463 | 465 | connect(nodeList.data(), &NodeList::uuidChanged, this, &Application::setSessionUUID); |
| 464 | 466 | connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset); |
| 465 | − connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch); | |
| 467 | + connect(&nodeList->getPacketReceiver(), &PacketReceiver::packetVersionMismatch, | |
| 468 | + this, &Application::notifyPacketVersionMismatch); | |
| 466 | 469 | |
| 467 | 470 | // connect to appropriate slots on AccountManager |
| 468 | 471 | AccountManager& accountManager = AccountManager::getInstance(); |
| @@ -646,6 +649,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 177 unmodified lines | ||
| 646 | 649 | auto applicationUpdater = DependencyManager::get<AutoUpdater>(); |
| 647 | 650 | connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog); |
| 648 | 651 | applicationUpdater->checkForUpdate(); |
| 652 | + | |
| 653 | + auto& packetReceiver = nodeList->getPacketReceiver(); | |
| 654 | + packetReceiver.registerListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket"); | |
| 649 | 655 | } |
| 650 | 656 | |
| 651 | 657 | void Application::aboutToQuit() { |
| @@ -658,8 +664,10 @@ void Application::aboutToQuit() { · 6 unmodified lines | ||
| 658 | 664 | void Application::cleanupBeforeQuit() { |
| 659 | 665 | |
| 660 | 666 | _entities.clear(); // this will allow entity scripts to properly shutdown |
| 661 | − | |
| 662 | − _datagramProcessor->shutdown(); // tell the datagram processor we're shutting down, so it can short circuit | |
| 667 | + | |
| 668 | + // tell the packet receiver we're shutting down, so it can drop packets | |
| 669 | + DependencyManager::get<NodeList>()->getPacketReceiver().setShouldDropPackets(true); | |
| 670 | + | |
| 663 | 671 | _entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts |
| 664 | 672 | ScriptEngine::stopAllScripts(this); // stop all currently running global scripts |
| 665 | 673 | |
| @@ -734,6 +742,8 @@ Application::~Application() { · 68 unmodified lines | ||
| 734 | 742 | DependencyManager::destroy<SoundCache>(); |
| 735 | 743 | |
| 736 | 744 | QThread* nodeThread = DependencyManager::get<NodeList>()->thread(); |
| 745 | + | |
| 746 | + // remove the NodeList from the DependencyManager | |
| 737 | 747 | DependencyManager::destroy<NodeList>(); |
| 738 | 748 | |
| 739 | 749 | // ask the node thread to quit and wait until it is done |
| @@ -1787,7 +1797,6 @@ void Application::checkFPS() { · 1047 unmodified lines | ||
| 1787 | 1797 | |
| 1788 | 1798 | _fps = (float)_frameCount / diffTime; |
| 1789 | 1799 | _frameCount = 0; |
| 1790 | − _datagramProcessor->resetCounters(); | |
| 1791 | 1800 | _timerStart.start(); |
| 1792 | 1801 | } |
| 1793 | 1802 | |
| @@ -3809,11 +3818,23 @@ void Application::domainChanged(const QString& domainHostname) { · 2015 unmodified lines | ||
| 3809 | 3818 | _domainConnectionRefusals.clear(); |
| 3810 | 3819 | } |
| 3811 | 3820 | |
| 3812 | −void Application::domainConnectionDenied(const QString& reason) { | |
| 3821 | +void Application::handleDomainConnectionDeniedPacket(QSharedPointer<NLPacket> packet) { | |
| 3822 | + QDataStream packetStream(packet.data()); | |
| 3823 | + | |
| 3824 | + QString reason; | |
| 3825 | + packetStream >> reason; | |
| 3826 | + | |
| 3827 | + // output to the log so the user knows they got a denied connection request | |
| 3828 | + // and check and signal for an access token so that we can make sure they are logged in | |
| 3829 | + qCDebug(interfaceapp) << "The domain-server denied a connection request: " << reason; | |
| 3830 | + qCDebug(interfaceapp) << "You may need to re-log to generate a keypair so you can provide a username signature."; | |
| 3831 | + | |
| 3813 | 3832 | if (!_domainConnectionRefusals.contains(reason)) { |
| 3814 | 3833 | _domainConnectionRefusals.append(reason); |
| 3815 | 3834 | emit domainConnectionRefused(reason); |
| 3816 | 3835 | } |
| 3836 | + | |
| 3837 | + AccountManager::getInstance().checkAndSignalForAccessToken(); | |
| 3817 | 3838 | } |
| 3818 | 3839 | |
| 3819 | 3840 | void Application::connectedToDomain(const QString& hostname) { |
| @@ -3889,12 +3910,12 @@ void Application::nodeKilled(SharedNodePointer node) { · 69 unmodified lines | ||
| 3889 | 3910 | DependencyManager::get<AvatarManager>()->clearOtherAvatars(); |
| 3890 | 3911 | } |
| 3891 | 3912 | } |
| 3892 | − | |
| 3893 | −void Application::trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket) { | |
| 3913 | + | |
| 3914 | +void Application::trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket) { | |
| 3894 | 3915 | |
| 3895 | 3916 | // Attempt to identify the sender from its address. |
| 3896 | 3917 | if (sendingNode) { |
| 3897 | − QUuid nodeUUID = sendingNode->getUUID(); | |
| 3918 | + const QUuid& nodeUUID = sendingNode->getUUID(); | |
| 3898 | 3919 | |
| 3899 | 3920 | // now that we know the node ID, let's add these stats to the stats for that node... |
| 3900 | 3921 | _octreeSceneStatsLock.lockForWrite(); |
| @@ -3906,70 +3927,71 @@ void Application::trackIncomingOctreePacket(const QByteArray& packet, const Shar · 5 unmodified lines | ||
| 3906 | 3927 | } |
| 3907 | 3928 | } |
| 3908 | 3929 | |
| 3909 | −int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sendingNode) { | |
| 3930 | +int Application::processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode) { | |
| 3910 | 3931 | // But, also identify the sender, and keep track of the contained jurisdiction root for this server |
| 3911 | 3932 | |
| 3912 | 3933 | // parse the incoming stats datas stick it in a temporary object for now, while we |
| 3913 | 3934 | // determine which server it belongs to |
| 3914 | − OctreeSceneStats temp; | |
| 3915 | − int statsMessageLength = temp.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size()); | |
| 3935 | + int statsMessageLength = 0; | |
| 3916 | 3936 | |
| 3917 | − // quick fix for crash... why would voxelServer be NULL? | |
| 3918 | − if (sendingNode) { | |
| 3919 | − QUuid nodeUUID = sendingNode->getUUID(); | |
| 3937 | + const QUuid& nodeUUID = sendingNode->getUUID(); | |
| 3938 | + OctreeSceneStats* octreeStats; | |
| 3920 | 3939 | |
| 3921 | − // now that we know the node ID, let's add these stats to the stats for that node... | |
| 3922 | − _octreeSceneStatsLock.lockForWrite(); | |
| 3923 | − if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { | |
| 3924 | − _octreeServerSceneStats[nodeUUID].unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), | |
| 3925 | − packet.size()); | |
| 3926 | − } else { | |
| 3927 | − _octreeServerSceneStats[nodeUUID] = temp; | |
| 3928 | − } | |
| 3929 | − _octreeSceneStatsLock.unlock(); | |
| 3940 | + // now that we know the node ID, let's add these stats to the stats for that node... | |
| 3941 | + _octreeSceneStatsLock.lockForWrite(); | |
| 3942 | + auto it = _octreeServerSceneStats.find(nodeUUID); | |
| 3943 | + if (it != _octreeServerSceneStats.end()) { | |
| 3944 | + octreeStats = &it->second; | |
| 3945 | + statsMessageLength = octreeStats->unpackFromPacket(packet); | |
| 3946 | + } else { | |
| 3947 | + OctreeSceneStats temp; | |
| 3948 | + statsMessageLength = temp.unpackFromPacket(packet); | |
| 3949 | + octreeStats = &temp; | |
| 3950 | + } | |
| 3951 | + _octreeSceneStatsLock.unlock(); | |
| 3930 | 3952 | |
| 3931 | − VoxelPositionSize rootDetails; | |
| 3932 | − voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails); | |
| 3953 | + VoxelPositionSize rootDetails; | |
| 3954 | + voxelDetailsForCode(octreeStats->getJurisdictionRoot(), rootDetails); | |
| 3933 | 3955 | |
| 3934 | − // see if this is the first we've heard of this node... | |
| 3935 | − NodeToJurisdictionMap* jurisdiction = NULL; | |
| 3936 | − QString serverType; | |
| 3937 | − if (sendingNode->getType() == NodeType::EntityServer) { | |
| 3938 | − jurisdiction = &_entityServerJurisdictions; | |
| 3939 | − serverType = "Entity"; | |
| 3940 | − } | |
| 3956 | + // see if this is the first we've heard of this node... | |
| 3957 | + NodeToJurisdictionMap* jurisdiction = NULL; | |
| 3958 | + QString serverType; | |
| 3959 | + if (sendingNode->getType() == NodeType::EntityServer) { | |
| 3960 | + jurisdiction = &_entityServerJurisdictions; | |
| 3961 | + serverType = "Entity"; | |
| 3962 | + } | |
| 3941 | 3963 | |
| 3942 | − jurisdiction->lockForRead(); | |
| 3943 | − if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { | |
| 3944 | − jurisdiction->unlock(); | |
| 3964 | + jurisdiction->lockForRead(); | |
| 3965 | + if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { | |
| 3966 | + jurisdiction->unlock(); | |
| 3945 | 3967 | |
| 3946 | − qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]", | |
| 3947 | − qPrintable(serverType), | |
| 3948 | − (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s); | |
| 3968 | + qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]", | |
| 3969 | + qPrintable(serverType), | |
| 3970 | + (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s); | |
| 3949 | 3971 | |
| 3950 | − // Add the jurisditionDetails object to the list of "fade outs" | |
| 3951 | − if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnOctreeServerChanges)) { | |
| 3952 | − OctreeFade fade(OctreeFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE); | |
| 3953 | − fade.voxelDetails = rootDetails; | |
| 3954 | − const float slightly_smaller = 0.99f; | |
| 3955 | − fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; | |
| 3956 | − _octreeFadesLock.lockForWrite(); | |
| 3957 | − _octreeFades.push_back(fade); | |
| 3958 | − _octreeFadesLock.unlock(); | |
| 3959 | − } | |
| 3960 | − } else { | |
| 3961 | − jurisdiction->unlock(); | |
| 3972 | + // Add the jurisditionDetails object to the list of "fade outs" | |
| 3973 | + if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnOctreeServerChanges)) { | |
| 3974 | + OctreeFade fade(OctreeFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE); | |
| 3975 | + fade.voxelDetails = rootDetails; | |
| 3976 | + const float slightly_smaller = 0.99f; | |
| 3977 | + fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller; | |
| 3978 | + _octreeFadesLock.lockForWrite(); | |
| 3979 | + _octreeFades.push_back(fade); | |
| 3980 | + _octreeFadesLock.unlock(); | |
| 3962 | 3981 | } |
| 3963 | − // store jurisdiction details for later use | |
| 3964 | − // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it | |
| 3965 | − // but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the | |
| 3966 | − // details from the OctreeSceneStats to construct the JurisdictionMap | |
| 3967 | − JurisdictionMap jurisdictionMap; | |
| 3968 | − jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes()); | |
| 3969 | − jurisdiction->lockForWrite(); | |
| 3970 | − (*jurisdiction)[nodeUUID] = jurisdictionMap; | |
| 3982 | + } else { | |
| 3971 | 3983 | jurisdiction->unlock(); |
| 3972 | 3984 | } |
| 3985 | + // store jurisdiction details for later use | |
| 3986 | + // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it | |
| 3987 | + // but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the | |
| 3988 | + // details from the OctreeSceneStats to construct the JurisdictionMap | |
| 3989 | + JurisdictionMap jurisdictionMap; | |
| 3990 | + jurisdictionMap.copyContents(octreeStats->getJurisdictionRoot(), octreeStats->getJurisdictionEndNodes()); | |
| 3991 | + jurisdiction->lockForWrite(); | |
| 3992 | + (*jurisdiction)[nodeUUID] = jurisdictionMap; | |
| 3993 | + jurisdiction->unlock(); | |
| 3994 | + | |
| 3973 | 3995 | return statsMessageLength; |
| 3974 | 3996 | } |
| 3975 | 3997 | |
| @@ -4809,6 +4831,7 @@ mat4 Application::getEyeProjection(int eye) const { · 833 unmodified lines | ||
| 4809 | 4831 | if (isHMDMode()) { |
| 4810 | 4832 | return OculusManager::getEyeProjection(eye); |
| 4811 | 4833 | } |
| 4834 | + | |
| 4812 | 4835 | return _viewFrustum.getProjection(); |
| 4813 | 4836 | } |
| 4814 | 4837 | |