From c96b704a28e64ea92e6e1b12d04fcbf256289a66 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Jun 2019 15:38:59 -0700 Subject: [PATCH 1/8] avoid dupe connections and teardown old connections --- interface/src/octree/SafeLanding.cpp | 55 +++++++++++++++------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 2e11de508b..573933a408 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -34,15 +34,15 @@ bool SafeLanding::SequenceLessThan::operator()(const int& a, const int& b) const } void SafeLanding::startEntitySequence(QSharedPointer entityTreeRenderer) { - if (!entityTreeRenderer.isNull()) { auto entityTree = entityTreeRenderer->getTree(); - if (entityTree) { + if (entityTree && !_trackingEntities) { Locker lock(_lock); _entityTreeRenderer = entityTreeRenderer; _trackedEntities.clear(); _trackingEntities = true; _maxTrackedEntityCount = 0; + connect(std::const_pointer_cast(entityTree).get(), &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity, Qt::DirectConnection); connect(std::const_pointer_cast(entityTree).get(), @@ -69,25 +69,20 @@ void SafeLanding::stopEntitySequence() { } void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { - if (_trackingEntities) { + if (_trackingEntities && _entityTreeRenderer) { Locker lock(_lock); + auto entityTree = _entityTreeRenderer->getTree(); + if (entityTree) { + EntityItemPointer entity = entityTree->findEntityByID(entityID); + if (entity && !entity->isLocalEntity() && entity->getCreated() < _startTime) { + _trackedEntities.emplace(entityID, entity); - if (_entityTreeRenderer.isNull() || _entityTreeRenderer->getTree() == nullptr) { - return; - } - - EntityItemPointer entity = _entityTreeRenderer->getTree()->findEntityByID(entityID); - - if (entity && !entity->isLocalEntity() && entity->getCreated() < _startTime) { - - _trackedEntities.emplace(entityID, entity); - int trackedEntityCount = (int)_trackedEntities.size(); - - if (trackedEntityCount > _maxTrackedEntityCount) { - _maxTrackedEntityCount = trackedEntityCount; - _trackedEntityStabilityCount = 0; + int trackedEntityCount = (int)_trackedEntities.size(); + if (trackedEntityCount > _maxTrackedEntityCount) { + _maxTrackedEntityCount = trackedEntityCount; + _trackedEntityStabilityCount = 0; + } } - //qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } } @@ -114,11 +109,20 @@ void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) { bool SafeLanding::isLoadSequenceComplete() { if ((isEntityLoadingComplete() && isSequenceNumbersComplete()) || qApp->failedToConnectToEntityServer()) { + _trackingEntities = false; + Locker lock(_lock); + if (_entityTreeRenderer) { + auto entityTree = _entityTreeRenderer->getTree(); + disconnect(std::const_pointer_cast(entityTree).get(), + &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity); + disconnect(std::const_pointer_cast(entityTree).get(), + &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); + _entityTreeRenderer.reset(); + } + _initialStart = INVALID_SEQUENCE; _initialEnd = INVALID_SEQUENCE; - _entityTreeRenderer.clear(); - _trackingEntities = false; // Don't track anything else that comes in. EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority); } @@ -187,9 +191,9 @@ bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) { bool SafeLanding::isEntityLoadingComplete() { Locker lock(_lock); - - - auto entityTree = qApp->getEntities(); + if (!_entityTreeRenderer) { + return true; + } auto entityMapIter = _trackedEntities.begin(); bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); @@ -200,9 +204,9 @@ bool SafeLanding::isEntityLoadingComplete() { bool isVisuallyReady = true; if (enableInterstitial) { - auto entityRenderable = entityTree->renderableForEntityId(entityMapIter->first); + auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first); if (!entityRenderable) { - entityTree->addingEntity(entityMapIter->first); + _entityTreeRenderer->addingEntity(entityMapIter->first); } isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete()); @@ -223,7 +227,6 @@ bool SafeLanding::isEntityLoadingComplete() { _trackedEntityStabilityCount++; } - return _trackedEntities.empty(); } From 355de0e6d5712c8caa54da4a1311219ef129c2e2 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Jun 2019 15:41:01 -0700 Subject: [PATCH 2/8] move Application::setFailedToConnect() to cpp for easier debugging --- interface/src/Application.cpp | 4 ++++ interface/src/Application.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index eba8664f72..f2ffbcc3ac 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2498,6 +2498,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo pauseUntilLoginDetermined(); } +void Application::setFailedToConnectToEntityServer() { + _failedToConnectToEntityServer = true; +} + void Application::updateVerboseLogging() { auto menu = Menu::getInstance(); if (!menu) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 2cea492d56..641f62461f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -512,7 +512,7 @@ private slots: void loadSettings(); void saveSettings() const; - void setFailedToConnectToEntityServer() { _failedToConnectToEntityServer = true; } + void setFailedToConnectToEntityServer(); bool acceptSnapshot(const QString& urlString); bool askToSetAvatarUrl(const QString& url); From 46b3d84be583946babe9b0185c285d9e1131aa7f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Jun 2019 15:41:50 -0700 Subject: [PATCH 3/8] remove unused cruft --- interface/src/Application.cpp | 2 -- interface/src/Application.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f2ffbcc3ac..234e3d597a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6186,8 +6186,6 @@ void Application::update(float deltaTime) { bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); if (gpuTextureMemSizeStable() || !enableInterstitial) { - // we've received a new full-scene octree stats packet, or it's been long enough to try again anyway - _lastPhysicsCheckTime = now; _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; _lastQueriedViews.clear(); // Force new view. diff --git a/interface/src/Application.h b/interface/src/Application.h index 641f62461f..bd7c9d758e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -786,8 +786,6 @@ private: qint64 _gpuTextureMemSizeStabilityCount { 0 }; qint64 _gpuTextureMemSizeAtLastCheck { 0 }; - quint64 _lastPhysicsCheckTime { usecTimestampNow() }; // when did we last check to see if physics was ready - bool _keyboardDeviceHasFocus { true }; ConnectionMonitor _connectionMonitor; From 496a7f36087c48a5198b11bc4589eacf44f4ccc7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Jun 2019 16:02:00 -0700 Subject: [PATCH 4/8] less cruft, more readable --- interface/src/Application.cpp | 2 +- .../src/octree/OctreePacketProcessor.cpp | 2 +- interface/src/octree/OctreePacketProcessor.h | 2 +- interface/src/octree/SafeLanding.cpp | 43 ++++++++----------- interface/src/octree/SafeLanding.h | 2 +- 5 files changed, 21 insertions(+), 30 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 234e3d597a..e23e3172ac 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5915,7 +5915,7 @@ void Application::resetPhysicsReadyInformation() { _gpuTextureMemSizeStabilityCount = 0; _gpuTextureMemSizeAtLastCheck = 0; _physicsEnabled = false; - _octreeProcessor.startEntitySequence(); + _octreeProcessor.startSafeLanding(); } diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 6b07e6717c..544c56c802 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -133,6 +133,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag } } -void OctreePacketProcessor::startEntitySequence() { +void OctreePacketProcessor::startSafeLanding() { _safeLanding->startEntitySequence(qApp->getEntities()); } diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index d6ffb942e6..7f906eab99 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -25,7 +25,7 @@ public: OctreePacketProcessor(); ~OctreePacketProcessor(); - void startEntitySequence(); + void startSafeLanding(); bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); } float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); } diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 573933a408..e4a2156aff 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -57,17 +57,6 @@ void SafeLanding::startEntitySequence(QSharedPointer entityT } } -void SafeLanding::stopEntitySequence() { - Locker lock(_lock); - _trackingEntities = false; - _maxTrackedEntityCount = 0; - _trackedEntityStabilityCount = 0; - _initialStart = INVALID_SEQUENCE; - _initialEnd = INVALID_SEQUENCE; - _trackedEntities.clear(); - _sequenceNumbers.clear(); -} - void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { if (_trackingEntities && _entityTreeRenderer) { Locker lock(_lock); @@ -109,24 +98,26 @@ void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) { bool SafeLanding::isLoadSequenceComplete() { if ((isEntityLoadingComplete() && isSequenceNumbersComplete()) || qApp->failedToConnectToEntityServer()) { - _trackingEntities = false; + stopTracking(); + } + return !_trackingEntities; +} - Locker lock(_lock); - if (_entityTreeRenderer) { - auto entityTree = _entityTreeRenderer->getTree(); - disconnect(std::const_pointer_cast(entityTree).get(), - &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity); - disconnect(std::const_pointer_cast(entityTree).get(), - &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); - _entityTreeRenderer.reset(); - } - - _initialStart = INVALID_SEQUENCE; - _initialEnd = INVALID_SEQUENCE; - EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority); +void SafeLanding::stopTracking() { + Locker lock(_lock); + _trackingEntities = false; + if (_entityTreeRenderer) { + auto entityTree = _entityTreeRenderer->getTree(); + disconnect(std::const_pointer_cast(entityTree).get(), + &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity); + disconnect(std::const_pointer_cast(entityTree).get(), + &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); + _entityTreeRenderer.reset(); } - return !_trackingEntities; + _initialStart = INVALID_SEQUENCE; + _initialEnd = INVALID_SEQUENCE; + EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority); } float SafeLanding::loadingProgressPercentage() { diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index 428ca15bdc..f88282ba5e 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -26,7 +26,6 @@ class EntityItemID; class SafeLanding : public QObject { public: void startEntitySequence(QSharedPointer entityTreeRenderer); - void stopEntitySequence(); void setCompletionSequenceNumbers(int first, int last); // 'last' exclusive. void noteReceivedsequenceNumber(int sequenceNumber); bool isLoadSequenceComplete(); @@ -41,6 +40,7 @@ private: bool isEntityPhysicsReady(const EntityItemPointer& entity); void debugDumpSequenceIDs() const; bool isEntityLoadingComplete(); + void stopTracking(); std::mutex _lock; using Locker = std::lock_guard; From 00185ee82e0afcf953b4713cad0dd17e4b6b0d77 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Jun 2019 17:05:44 -0700 Subject: [PATCH 5/8] cleaup to help unravel one spaghetti strand --- interface/src/Application.cpp | 41 +++++++++++-------- interface/src/Application.h | 1 + .../src/octree/OctreePacketProcessor.cpp | 10 +++-- interface/src/octree/OctreePacketProcessor.h | 1 + interface/src/octree/SafeLanding.cpp | 8 ++-- interface/src/octree/SafeLanding.h | 8 ++-- 6 files changed, 42 insertions(+), 27 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e23e3172ac..58b042e084 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6165,6 +6165,24 @@ void Application::updateSecondaryCameraViewFrustum() { static bool domainLoadingInProgress = false; +void Application::tryToEnablePhysics() { + bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); + + if (gpuTextureMemSizeStable() || !enableInterstitial) { + _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; + _lastQueriedViews.clear(); // Force new view. + + // process octree stats packets are sent in between full sends of a scene (this isn't currently true). + // We keep physics disabled until we've received a full scene and everything near the avatar in that + // scene is ready to compute its collision shape. + if (getMyAvatar()->isReadyForPhysics()) { + _physicsEnabled = true; + setIsInterstitialMode(false); + getMyAvatar()->updateMotionBehaviorFromMenu(); + } + } +} + void Application::update(float deltaTime) { PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_graphicsEngine._renderFrameCount + 1); @@ -6172,7 +6190,6 @@ void Application::update(float deltaTime) { return; } - if (!_physicsEnabled) { if (!domainLoadingInProgress) { PROFILE_ASYNC_BEGIN(app, "Scene Loading", ""); @@ -6182,21 +6199,13 @@ void Application::update(float deltaTime) { // we haven't yet enabled physics. we wait until we think we have all the collision information // for nearby entities before starting bullet up. quint64 now = usecTimestampNow(); - if (isServerlessMode() || _octreeProcessor.isLoadSequenceComplete()) { - bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); - - if (gpuTextureMemSizeStable() || !enableInterstitial) { - _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; - _lastQueriedViews.clear(); // Force new view. - - // process octree stats packets are sent in between full sends of a scene (this isn't currently true). - // We keep physics disabled until we've received a full scene and everything near the avatar in that - // scene is ready to compute its collision shape. - if (getMyAvatar()->isReadyForPhysics()) { - _physicsEnabled = true; - setIsInterstitialMode(false); - getMyAvatar()->updateMotionBehaviorFromMenu(); - } + if (isServerlessMode()) { + tryToEnablePhysics(); + } else if (_failedToConnectToEntityServer) { + _octreeProcessor.stopSafeLanding(); + } else { + if (_octreeProcessor.isLoadSequenceComplete()) { + tryToEnablePhysics(); } } } else if (domainLoadingInProgress) { diff --git a/interface/src/Application.h b/interface/src/Application.h index bd7c9d758e..8b25417abe 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -564,6 +564,7 @@ private: void cleanupBeforeQuit(); void idle(); + void tryToEnablePhysics(); void update(float deltaTime); // Various helper functions called during update() diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 544c56c802..68e68ee0af 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -115,7 +115,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag auto renderer = qApp->getEntities(); if (renderer) { renderer->processDatagram(*message, sendingNode); - _safeLanding->noteReceivedsequenceNumber(renderer->getLastOctreeMessageSequence()); + _safeLanding->updateSequence(renderer->getLastOctreeMessageSequence()); } } } break; @@ -124,7 +124,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag // Read sequence # OCTREE_PACKET_SEQUENCE completionNumber; message->readPrimitive(&completionNumber); - _safeLanding->setCompletionSequenceNumbers(0, completionNumber); + _safeLanding->finishSequence(0, completionNumber); } break; default: { @@ -134,5 +134,9 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag } void OctreePacketProcessor::startSafeLanding() { - _safeLanding->startEntitySequence(qApp->getEntities()); + _safeLanding->startTracking(qApp->getEntities()); +} + +void OctreePacketProcessor::stopSafeLanding() { + _safeLanding->stopTracking(); } diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 7f906eab99..5c5bc7ed9a 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -26,6 +26,7 @@ public: ~OctreePacketProcessor(); void startSafeLanding(); + void stopSafeLanding(); bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); } float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); } diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index e4a2156aff..3ae31a4b1a 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -33,7 +33,7 @@ bool SafeLanding::SequenceLessThan::operator()(const int& a, const int& b) const return lessThanWraparound(a, b); } -void SafeLanding::startEntitySequence(QSharedPointer entityTreeRenderer) { +void SafeLanding::startTracking(QSharedPointer entityTreeRenderer) { if (!entityTreeRenderer.isNull()) { auto entityTree = entityTreeRenderer->getTree(); if (entityTree && !_trackingEntities) { @@ -81,7 +81,7 @@ void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) { _trackedEntities.erase(entityID); } -void SafeLanding::setCompletionSequenceNumbers(int first, int last) { +void SafeLanding::finishSequence(int first, int last) { Locker lock(_lock); if (_initialStart == INVALID_SEQUENCE) { _initialStart = first; @@ -89,7 +89,7 @@ void SafeLanding::setCompletionSequenceNumbers(int first, int last) { } } -void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) { +void SafeLanding::updateSequence(int sequenceNumber) { if (_trackingEntities) { Locker lock(_lock); _sequenceNumbers.insert(sequenceNumber); @@ -97,7 +97,7 @@ void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) { } bool SafeLanding::isLoadSequenceComplete() { - if ((isEntityLoadingComplete() && isSequenceNumbersComplete()) || qApp->failedToConnectToEntityServer()) { + if (isEntityLoadingComplete() && isSequenceNumbersComplete()) { stopTracking(); } return !_trackingEntities; diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index f88282ba5e..ec9fb98989 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -25,9 +25,10 @@ class EntityItemID; class SafeLanding : public QObject { public: - void startEntitySequence(QSharedPointer entityTreeRenderer); - void setCompletionSequenceNumbers(int first, int last); // 'last' exclusive. - void noteReceivedsequenceNumber(int sequenceNumber); + void startTracking(QSharedPointer entityTreeRenderer); + void stopTracking(); + void finishSequence(int first, int last); // 'last' exclusive. + void updateSequence(int sequenceNumber); bool isLoadSequenceComplete(); float loadingProgressPercentage(); @@ -40,7 +41,6 @@ private: bool isEntityPhysicsReady(const EntityItemPointer& entity); void debugDumpSequenceIDs() const; bool isEntityLoadingComplete(); - void stopTracking(); std::mutex _lock; using Locker = std::lock_guard; From dfb7ac7044e3e9ad1d3d02e49d8dec4f55e29d1b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Jun 2019 08:14:34 -0700 Subject: [PATCH 6/8] name changes and improved flow for SafeLanding logic --- interface/src/Application.cpp | 4 +- .../src/octree/OctreePacketProcessor.cpp | 10 +- interface/src/octree/OctreePacketProcessor.h | 4 +- interface/src/octree/SafeLanding.cpp | 143 ++++++++---------- interface/src/octree/SafeLanding.h | 8 +- 5 files changed, 81 insertions(+), 88 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 58b042e084..7ffa32c40c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6198,13 +6198,13 @@ void Application::update(float deltaTime) { // we haven't yet enabled physics. we wait until we think we have all the collision information // for nearby entities before starting bullet up. - quint64 now = usecTimestampNow(); if (isServerlessMode()) { tryToEnablePhysics(); } else if (_failedToConnectToEntityServer) { _octreeProcessor.stopSafeLanding(); } else { - if (_octreeProcessor.isLoadSequenceComplete()) { + _octreeProcessor.updateSafeLanding(); + if (_octreeProcessor.safeLandingIsComplete()) { tryToEnablePhysics(); } } diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 68e68ee0af..1cfbcd0890 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -115,7 +115,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag auto renderer = qApp->getEntities(); if (renderer) { renderer->processDatagram(*message, sendingNode); - _safeLanding->updateSequence(renderer->getLastOctreeMessageSequence()); + _safeLanding->addToSequence(renderer->getLastOctreeMessageSequence()); } } } break; @@ -137,6 +137,14 @@ void OctreePacketProcessor::startSafeLanding() { _safeLanding->startTracking(qApp->getEntities()); } +void OctreePacketProcessor::updateSafeLanding() { + _safeLanding->updateTracking(); +} + void OctreePacketProcessor::stopSafeLanding() { _safeLanding->stopTracking(); } + +bool OctreePacketProcessor::safeLandingIsComplete() const { + return _safeLanding->trackingIsComplete(); +} diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 5c5bc7ed9a..e59ae7cb5e 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -26,8 +26,10 @@ public: ~OctreePacketProcessor(); void startSafeLanding(); + void updateSafeLanding(); void stopSafeLanding(); - bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); } + bool safeLandingIsComplete() const; + float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); } signals: diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 3ae31a4b1a..c9fd8c01ee 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -40,18 +40,18 @@ void SafeLanding::startTracking(QSharedPointer entityTreeRen Locker lock(_lock); _entityTreeRenderer = entityTreeRenderer; _trackedEntities.clear(); - _trackingEntities = true; _maxTrackedEntityCount = 0; + _initialStart = INVALID_SEQUENCE; + _initialEnd = INVALID_SEQUENCE; + _sequenceNumbers.clear(); + _trackingEntities = true; + _startTime = usecTimestampNow(); connect(std::const_pointer_cast(entityTree).get(), &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity, Qt::DirectConnection); connect(std::const_pointer_cast(entityTree).get(), &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); - _sequenceNumbers.clear(); - _initialStart = INVALID_SEQUENCE; - _initialEnd = INVALID_SEQUENCE; - _startTime = usecTimestampNow(); EntityTreeRenderer::setEntityLoadingPriorityFunction(&ElevatedPriority); } } @@ -83,24 +83,71 @@ void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) { void SafeLanding::finishSequence(int first, int last) { Locker lock(_lock); - if (_initialStart == INVALID_SEQUENCE) { + if (_trackingEntities) { _initialStart = first; _initialEnd = last; } } -void SafeLanding::updateSequence(int sequenceNumber) { +void SafeLanding::addToSequence(int sequenceNumber) { + Locker lock(_lock); if (_trackingEntities) { - Locker lock(_lock); _sequenceNumbers.insert(sequenceNumber); } } -bool SafeLanding::isLoadSequenceComplete() { - if (isEntityLoadingComplete() && isSequenceNumbersComplete()) { - stopTracking(); +void SafeLanding::updateTracking() { + if (!_trackingEntities || !_entityTreeRenderer) { + return; + } + Locker lock(_lock); + + bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); + + auto entityMapIter = _trackedEntities.begin(); + while (entityMapIter != _trackedEntities.end()) { + auto entity = entityMapIter->second; + bool isVisuallyReady = true; + if (enableInterstitial) { + auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first); + if (!entityRenderable) { + _entityTreeRenderer->addingEntity(entityMapIter->first); + } + + isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete()); + } + if (isEntityPhysicsReady(entity) && isVisuallyReady) { + entityMapIter = _trackedEntities.erase(entityMapIter); + } else { + if (!isVisuallyReady) { + entity->requestRenderUpdate(); + } + entityMapIter++; + } + } + + if (enableInterstitial) { + _trackedEntityStabilityCount++; + } + + if (_trackedEntities.empty()) { + // no more tracked entities --> check sequenceNumbers + if (_initialStart != INVALID_SEQUENCE) { + Locker lock(_lock); + int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart: + _initialEnd + SEQUENCE_MODULO - _initialStart; + auto startIter = _sequenceNumbers.find(_initialStart); + auto endIter = _sequenceNumbers.find(_initialEnd - 1); + + bool missingSequenceNumbers = qApp->isMissingSequenceNumbers(); + if (sequenceSize == 0 || + (startIter != _sequenceNumbers.end() && + endIter != _sequenceNumbers.end() && + ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))) { + stopTracking(); + } + } } - return !_trackingEntities; } void SafeLanding::stopTracking() { @@ -114,12 +161,13 @@ void SafeLanding::stopTracking() { &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); _entityTreeRenderer.reset(); } - - _initialStart = INVALID_SEQUENCE; - _initialEnd = INVALID_SEQUENCE; EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority); } +bool SafeLanding::trackingIsComplete() const { + return !_trackingEntities && (_initialStart != INVALID_SEQUENCE); +} + float SafeLanding::loadingProgressPercentage() { Locker lock(_lock); static const int MINIMUM_TRACKED_ENTITY_STABILITY_COUNT = 15; @@ -136,29 +184,6 @@ float SafeLanding::loadingProgressPercentage() { return entityReadyPercentage; } -bool SafeLanding::isSequenceNumbersComplete() { - if (_initialStart != INVALID_SEQUENCE) { - Locker lock(_lock); - int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart: - _initialEnd + SEQUENCE_MODULO - _initialStart; - auto startIter = _sequenceNumbers.find(_initialStart); - auto endIter = _sequenceNumbers.find(_initialEnd - 1); - - bool missingSequenceNumbers = qApp->isMissingSequenceNumbers(); - if (sequenceSize == 0 || - (startIter != _sequenceNumbers.end() - && endIter != _sequenceNumbers.end() - && ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))) { - bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); - if (!enableInterstitial) { - _trackingEntities = false; // Don't track anything else that comes in. - } - return true; - } - } - return false; -} - bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) { if (entity && !entity->getCollisionless()) { const auto& entityType = entity->getType(); @@ -176,51 +201,9 @@ bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) { } } } - return true; } -bool SafeLanding::isEntityLoadingComplete() { - Locker lock(_lock); - if (!_entityTreeRenderer) { - return true; - } - auto entityMapIter = _trackedEntities.begin(); - - bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); - - while (entityMapIter != _trackedEntities.end()) { - auto entity = entityMapIter->second; - - bool isVisuallyReady = true; - - if (enableInterstitial) { - auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first); - if (!entityRenderable) { - _entityTreeRenderer->addingEntity(entityMapIter->first); - } - - isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete()); - } - - if (isEntityPhysicsReady(entity) && isVisuallyReady) { - entityMapIter = _trackedEntities.erase(entityMapIter); - } else { - if (!isVisuallyReady) { - entity->requestRenderUpdate(); - } - - entityMapIter++; - } - } - - if (enableInterstitial) { - _trackedEntityStabilityCount++; - } - - return _trackedEntities.empty(); -} - float SafeLanding::ElevatedPriority(const EntityItem& entityItem) { return entityItem.getCollisionless() ? 0.0f : 10.0f; } diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index ec9fb98989..32fba282fe 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -26,10 +26,12 @@ class EntityItemID; class SafeLanding : public QObject { public: void startTracking(QSharedPointer entityTreeRenderer); + void updateTracking(); void stopTracking(); + bool trackingIsComplete() const; + void finishSequence(int first, int last); // 'last' exclusive. - void updateSequence(int sequenceNumber); - bool isLoadSequenceComplete(); + void addToSequence(int sequenceNumber); float loadingProgressPercentage(); private slots: @@ -37,10 +39,8 @@ private slots: void deleteTrackedEntity(const EntityItemID& entityID); private: - bool isSequenceNumbersComplete(); bool isEntityPhysicsReady(const EntityItemPointer& entity); void debugDumpSequenceIDs() const; - bool isEntityLoadingComplete(); std::mutex _lock; using Locker = std::lock_guard; From bf068a32114036130a4901e2475999d5486f59d1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Jun 2019 11:33:51 -0700 Subject: [PATCH 7/8] fix SafeLanding start/stop on entity-server connection flow --- interface/src/Application.cpp | 17 +++-- interface/src/Application.h | 2 +- .../src/octree/OctreePacketProcessor.cpp | 29 +++++--- interface/src/octree/OctreePacketProcessor.h | 1 + interface/src/octree/SafeLanding.cpp | 69 ++++++++++--------- interface/src/octree/SafeLanding.h | 1 + 6 files changed, 71 insertions(+), 48 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7ffa32c40c..676577932a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6201,7 +6201,9 @@ void Application::update(float deltaTime) { if (isServerlessMode()) { tryToEnablePhysics(); } else if (_failedToConnectToEntityServer) { - _octreeProcessor.stopSafeLanding(); + if (_octreeProcessor.safeLandingIsActive()) { + _octreeProcessor.stopSafeLanding(); + } } else { _octreeProcessor.updateSafeLanding(); if (_octreeProcessor.safeLandingIsComplete()) { @@ -7154,13 +7156,17 @@ void Application::resettingDomain() { clearDomainOctreeDetails(false); } -void Application::nodeAdded(SharedNodePointer node) const { +void Application::nodeAdded(SharedNodePointer node) { if (node->getType() == NodeType::EntityServer) { - if (!_failedToConnectToEntityServer) { + if (_failedToConnectToEntityServer && !_entityServerConnectionTimer.isActive()) { + _failedToConnectToEntityServer = false; + _octreeProcessor.stopSafeLanding(); + _octreeProcessor.startSafeLanding(); + } else if (_entityServerConnectionTimer.isActive()) { _entityServerConnectionTimer.stop(); - _entityServerConnectionTimer.setInterval(ENTITY_SERVER_CONNECTION_TIMEOUT); - _entityServerConnectionTimer.start(); } + _entityServerConnectionTimer.setInterval(ENTITY_SERVER_CONNECTION_TIMEOUT); + _entityServerConnectionTimer.start(); } } @@ -7170,7 +7176,6 @@ void Application::nodeActivated(SharedNodePointer node) { #if !defined(DISABLE_QML) auto offscreenUi = getOffscreenUI(); - if (offscreenUi) { auto nodeList = DependencyManager::get(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 8b25417abe..2d6821bbd9 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -527,7 +527,7 @@ private slots: void domainURLChanged(QUrl domainURL); void updateWindowTitle() const; - void nodeAdded(SharedNodePointer node) const; + void nodeAdded(SharedNodePointer node); void nodeActivated(SharedNodePointer node); void nodeKilled(SharedNodePointer node); static void packetSent(quint64 length); diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 1cfbcd0890..7533ddbac5 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -63,7 +63,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag // construct a new packet from the piggybacked one auto buffer = std::unique_ptr(new char[piggybackBytes]); memcpy(buffer.get(), message->getRawMessage() + statsMessageLength, piggybackBytes); - auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggybackBytes, message->getSenderSockAddr()); message = QSharedPointer::create(*newPacket); } else { @@ -80,7 +79,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag const QUuid& senderUUID = sendingNode->getUUID(); if (!versionDebugSuppressMap.contains(senderUUID, packetType)) { - qDebug() << "Was stats packet? " << wasStatsPacket; qDebug() << "OctreePacketProcessor - piggyback packet version mismatch on" << packetType << "- Sender" << senderUUID << "sent" << (int) message->getVersion() << "but" @@ -113,7 +111,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag case PacketType::EntityData: { if (DependencyManager::get()->shouldRenderEntities()) { auto renderer = qApp->getEntities(); - if (renderer) { + if (renderer && _safeLanding) { renderer->processDatagram(*message, sendingNode); _safeLanding->addToSequence(renderer->getLastOctreeMessageSequence()); } @@ -124,7 +122,9 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag // Read sequence # OCTREE_PACKET_SEQUENCE completionNumber; message->readPrimitive(&completionNumber); - _safeLanding->finishSequence(0, completionNumber); + if (_safeLanding) { + _safeLanding->finishSequence(0, completionNumber); + } } break; default: { @@ -134,17 +134,30 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag } void OctreePacketProcessor::startSafeLanding() { - _safeLanding->startTracking(qApp->getEntities()); + if (_safeLanding) { + _safeLanding->startTracking(qApp->getEntities()); + } } void OctreePacketProcessor::updateSafeLanding() { - _safeLanding->updateTracking(); + if (_safeLanding) { + _safeLanding->updateTracking(); + } } void OctreePacketProcessor::stopSafeLanding() { - _safeLanding->stopTracking(); + if (_safeLanding) { + _safeLanding->stopTracking(); + } +} + +bool OctreePacketProcessor::safeLandingIsActive() const { + return _safeLanding && _safeLanding->isTracking(); } bool OctreePacketProcessor::safeLandingIsComplete() const { - return _safeLanding->trackingIsComplete(); + if (_safeLanding) { + return _safeLanding->trackingIsComplete(); + } + return false; } diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index e59ae7cb5e..eacc15f62d 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -28,6 +28,7 @@ public: void startSafeLanding(); void updateSafeLanding(); void stopSafeLanding(); + bool safeLandingIsActive() const; bool safeLandingIsComplete() const; float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); } diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index c9fd8c01ee..bcce86f9f9 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -100,50 +100,53 @@ void SafeLanding::updateTracking() { if (!_trackingEntities || !_entityTreeRenderer) { return; } - Locker lock(_lock); - bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); - - auto entityMapIter = _trackedEntities.begin(); - while (entityMapIter != _trackedEntities.end()) { - auto entity = entityMapIter->second; - bool isVisuallyReady = true; + { + Locker lock(_lock); + bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); + auto entityMapIter = _trackedEntities.begin(); + while (entityMapIter != _trackedEntities.end()) { + auto entity = entityMapIter->second; + bool isVisuallyReady = true; + if (enableInterstitial) { + auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first); + if (!entityRenderable) { + _entityTreeRenderer->addingEntity(entityMapIter->first); + } + isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete()); + } + if (isEntityPhysicsReady(entity) && isVisuallyReady) { + entityMapIter = _trackedEntities.erase(entityMapIter); + } else { + if (!isVisuallyReady) { + entity->requestRenderUpdate(); + } + entityMapIter++; + } + } if (enableInterstitial) { - auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first); - if (!entityRenderable) { - _entityTreeRenderer->addingEntity(entityMapIter->first); - } - - isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete()); + _trackedEntityStabilityCount++; } - if (isEntityPhysicsReady(entity) && isVisuallyReady) { - entityMapIter = _trackedEntities.erase(entityMapIter); - } else { - if (!isVisuallyReady) { - entity->requestRenderUpdate(); - } - entityMapIter++; - } - } - - if (enableInterstitial) { - _trackedEntityStabilityCount++; } if (_trackedEntities.empty()) { // no more tracked entities --> check sequenceNumbers if (_initialStart != INVALID_SEQUENCE) { - Locker lock(_lock); - int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart: - _initialEnd + SEQUENCE_MODULO - _initialStart; - auto startIter = _sequenceNumbers.find(_initialStart); - auto endIter = _sequenceNumbers.find(_initialEnd - 1); + bool shouldStop = false; + { + Locker lock(_lock); + int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart: + _initialEnd + SEQUENCE_MODULO - _initialStart; + auto startIter = _sequenceNumbers.find(_initialStart); + auto endIter = _sequenceNumbers.find(_initialEnd - 1); - bool missingSequenceNumbers = qApp->isMissingSequenceNumbers(); - if (sequenceSize == 0 || + bool missingSequenceNumbers = qApp->isMissingSequenceNumbers(); + shouldStop = (sequenceSize == 0 || (startIter != _sequenceNumbers.end() && endIter != _sequenceNumbers.end() && - ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))) { + ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))); + } + if (shouldStop) { stopTracking(); } } diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index 32fba282fe..2f1db2366f 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -28,6 +28,7 @@ public: void startTracking(QSharedPointer entityTreeRenderer); void updateTracking(); void stopTracking(); + bool isTracking() const { return _trackingEntities; } bool trackingIsComplete() const; void finishSequence(int first, int last); // 'last' exclusive. From 0bec2bca838f69a2f040b3dca31bdbd1a22f93ab Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Jun 2019 14:44:23 -0700 Subject: [PATCH 8/8] OctreePacketProcessor should process packet even when no SafeLanding --- interface/src/octree/OctreePacketProcessor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 7533ddbac5..c6f908e039 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -111,9 +111,11 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag case PacketType::EntityData: { if (DependencyManager::get()->shouldRenderEntities()) { auto renderer = qApp->getEntities(); - if (renderer && _safeLanding) { + if (renderer) { renderer->processDatagram(*message, sendingNode); - _safeLanding->addToSequence(renderer->getLastOctreeMessageSequence()); + if (_safeLanding && _safeLanding->isTracking()) { + _safeLanding->addToSequence(renderer->getLastOctreeMessageSequence()); + } } } } break;