From dfb7ac7044e3e9ad1d3d02e49d8dec4f55e29d1b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Jun 2019 08:14:34 -0700 Subject: [PATCH] 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;