name changes and improved flow for SafeLanding logic

This commit is contained in:
Andrew Meadows 2019-06-27 08:14:34 -07:00
parent 00185ee82e
commit dfb7ac7044
5 changed files with 81 additions and 88 deletions

View file

@ -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 // we haven't yet enabled physics. we wait until we think we have all the collision information
// for nearby entities before starting bullet up. // for nearby entities before starting bullet up.
quint64 now = usecTimestampNow();
if (isServerlessMode()) { if (isServerlessMode()) {
tryToEnablePhysics(); tryToEnablePhysics();
} else if (_failedToConnectToEntityServer) { } else if (_failedToConnectToEntityServer) {
_octreeProcessor.stopSafeLanding(); _octreeProcessor.stopSafeLanding();
} else { } else {
if (_octreeProcessor.isLoadSequenceComplete()) { _octreeProcessor.updateSafeLanding();
if (_octreeProcessor.safeLandingIsComplete()) {
tryToEnablePhysics(); tryToEnablePhysics();
} }
} }

View file

@ -115,7 +115,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
auto renderer = qApp->getEntities(); auto renderer = qApp->getEntities();
if (renderer) { if (renderer) {
renderer->processDatagram(*message, sendingNode); renderer->processDatagram(*message, sendingNode);
_safeLanding->updateSequence(renderer->getLastOctreeMessageSequence()); _safeLanding->addToSequence(renderer->getLastOctreeMessageSequence());
} }
} }
} break; } break;
@ -137,6 +137,14 @@ void OctreePacketProcessor::startSafeLanding() {
_safeLanding->startTracking(qApp->getEntities()); _safeLanding->startTracking(qApp->getEntities());
} }
void OctreePacketProcessor::updateSafeLanding() {
_safeLanding->updateTracking();
}
void OctreePacketProcessor::stopSafeLanding() { void OctreePacketProcessor::stopSafeLanding() {
_safeLanding->stopTracking(); _safeLanding->stopTracking();
} }
bool OctreePacketProcessor::safeLandingIsComplete() const {
return _safeLanding->trackingIsComplete();
}

View file

@ -26,8 +26,10 @@ public:
~OctreePacketProcessor(); ~OctreePacketProcessor();
void startSafeLanding(); void startSafeLanding();
void updateSafeLanding();
void stopSafeLanding(); void stopSafeLanding();
bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); } bool safeLandingIsComplete() const;
float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); } float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); }
signals: signals:

View file

@ -40,18 +40,18 @@ void SafeLanding::startTracking(QSharedPointer<EntityTreeRenderer> entityTreeRen
Locker lock(_lock); Locker lock(_lock);
_entityTreeRenderer = entityTreeRenderer; _entityTreeRenderer = entityTreeRenderer;
_trackedEntities.clear(); _trackedEntities.clear();
_trackingEntities = true;
_maxTrackedEntityCount = 0; _maxTrackedEntityCount = 0;
_initialStart = INVALID_SEQUENCE;
_initialEnd = INVALID_SEQUENCE;
_sequenceNumbers.clear();
_trackingEntities = true;
_startTime = usecTimestampNow();
connect(std::const_pointer_cast<EntityTree>(entityTree).get(), connect(std::const_pointer_cast<EntityTree>(entityTree).get(),
&EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity, Qt::DirectConnection); &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity, Qt::DirectConnection);
connect(std::const_pointer_cast<EntityTree>(entityTree).get(), connect(std::const_pointer_cast<EntityTree>(entityTree).get(),
&EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity);
_sequenceNumbers.clear();
_initialStart = INVALID_SEQUENCE;
_initialEnd = INVALID_SEQUENCE;
_startTime = usecTimestampNow();
EntityTreeRenderer::setEntityLoadingPriorityFunction(&ElevatedPriority); EntityTreeRenderer::setEntityLoadingPriorityFunction(&ElevatedPriority);
} }
} }
@ -83,24 +83,71 @@ void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) {
void SafeLanding::finishSequence(int first, int last) { void SafeLanding::finishSequence(int first, int last) {
Locker lock(_lock); Locker lock(_lock);
if (_initialStart == INVALID_SEQUENCE) { if (_trackingEntities) {
_initialStart = first; _initialStart = first;
_initialEnd = last; _initialEnd = last;
} }
} }
void SafeLanding::updateSequence(int sequenceNumber) { void SafeLanding::addToSequence(int sequenceNumber) {
Locker lock(_lock);
if (_trackingEntities) { if (_trackingEntities) {
Locker lock(_lock);
_sequenceNumbers.insert(sequenceNumber); _sequenceNumbers.insert(sequenceNumber);
} }
} }
bool SafeLanding::isLoadSequenceComplete() { void SafeLanding::updateTracking() {
if (isEntityLoadingComplete() && isSequenceNumbersComplete()) { if (!_trackingEntities || !_entityTreeRenderer) {
stopTracking(); return;
}
Locker lock(_lock);
bool enableInterstitial = DependencyManager::get<NodeList>()->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() { void SafeLanding::stopTracking() {
@ -114,12 +161,13 @@ void SafeLanding::stopTracking() {
&EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity);
_entityTreeRenderer.reset(); _entityTreeRenderer.reset();
} }
_initialStart = INVALID_SEQUENCE;
_initialEnd = INVALID_SEQUENCE;
EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority); EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority);
} }
bool SafeLanding::trackingIsComplete() const {
return !_trackingEntities && (_initialStart != INVALID_SEQUENCE);
}
float SafeLanding::loadingProgressPercentage() { float SafeLanding::loadingProgressPercentage() {
Locker lock(_lock); Locker lock(_lock);
static const int MINIMUM_TRACKED_ENTITY_STABILITY_COUNT = 15; static const int MINIMUM_TRACKED_ENTITY_STABILITY_COUNT = 15;
@ -136,29 +184,6 @@ float SafeLanding::loadingProgressPercentage() {
return entityReadyPercentage; 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<NodeList>()->getDomainHandler().getInterstitialModeEnabled();
if (!enableInterstitial) {
_trackingEntities = false; // Don't track anything else that comes in.
}
return true;
}
}
return false;
}
bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) { bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) {
if (entity && !entity->getCollisionless()) { if (entity && !entity->getCollisionless()) {
const auto& entityType = entity->getType(); const auto& entityType = entity->getType();
@ -176,51 +201,9 @@ bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) {
} }
} }
} }
return true; return true;
} }
bool SafeLanding::isEntityLoadingComplete() {
Locker lock(_lock);
if (!_entityTreeRenderer) {
return true;
}
auto entityMapIter = _trackedEntities.begin();
bool enableInterstitial = DependencyManager::get<NodeList>()->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) { float SafeLanding::ElevatedPriority(const EntityItem& entityItem) {
return entityItem.getCollisionless() ? 0.0f : 10.0f; return entityItem.getCollisionless() ? 0.0f : 10.0f;
} }

View file

@ -26,10 +26,12 @@ class EntityItemID;
class SafeLanding : public QObject { class SafeLanding : public QObject {
public: public:
void startTracking(QSharedPointer<EntityTreeRenderer> entityTreeRenderer); void startTracking(QSharedPointer<EntityTreeRenderer> entityTreeRenderer);
void updateTracking();
void stopTracking(); void stopTracking();
bool trackingIsComplete() const;
void finishSequence(int first, int last); // 'last' exclusive. void finishSequence(int first, int last); // 'last' exclusive.
void updateSequence(int sequenceNumber); void addToSequence(int sequenceNumber);
bool isLoadSequenceComplete();
float loadingProgressPercentage(); float loadingProgressPercentage();
private slots: private slots:
@ -37,10 +39,8 @@ private slots:
void deleteTrackedEntity(const EntityItemID& entityID); void deleteTrackedEntity(const EntityItemID& entityID);
private: private:
bool isSequenceNumbersComplete();
bool isEntityPhysicsReady(const EntityItemPointer& entity); bool isEntityPhysicsReady(const EntityItemPointer& entity);
void debugDumpSequenceIDs() const; void debugDumpSequenceIDs() const;
bool isEntityLoadingComplete();
std::mutex _lock; std::mutex _lock;
using Locker = std::lock_guard<std::mutex>; using Locker = std::lock_guard<std::mutex>;