diff --git a/interface/resources/qml/dialogs/RunningScripts.qml b/interface/resources/qml/dialogs/RunningScripts.qml index 4c347aef3d..0d771b79cd 100644 --- a/interface/resources/qml/dialogs/RunningScripts.qml +++ b/interface/resources/qml/dialogs/RunningScripts.qml @@ -111,8 +111,7 @@ Window { Button { text: "Stop all"; onClicked: stopAll() } } - ListView { - clip: true + ScrollView { anchors { top: allButtons.bottom; left: parent.left; @@ -122,45 +121,49 @@ Window { bottomMargin: 8 } - model: runningScriptsModel + ListView { + clip: true + anchors { fill: parent; margins: 0 } - delegate: Rectangle { - radius: 3 - anchors { left: parent.left; right: parent.right } + model: runningScriptsModel - height: scriptName.height + 12 - color: index % 2 ? "#ddd" : "#eee" + delegate: Rectangle { + radius: 3 + anchors { left: parent.left; right: parent.right } - Text { - anchors { left: parent.left; leftMargin: 4; verticalCenter: parent.verticalCenter } - id: scriptName - text: name - } + height: scriptName.height + 12 + color: index % 2 ? "#ddd" : "#eee" - Row { - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 4 - spacing: 4 - HifiControls.FontAwesome { - text: "\uf021"; size: scriptName.height; - MouseArea { - anchors { fill: parent; margins: -2; } - onClicked: reloadScript(model.url) - } + Text { + anchors { left: parent.left; leftMargin: 4; verticalCenter: parent.verticalCenter } + id: scriptName + text: name } - HifiControls.FontAwesome { - size: scriptName.height; text: "\uf00d" - MouseArea { - anchors { fill: parent; margins: -2; } - onClicked: stopScript(model.url) + + Row { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 4 + spacing: 4 + HifiControls.FontAwesome { + text: "\uf021"; size: scriptName.height; + MouseArea { + anchors { fill: parent; margins: -2; } + onClicked: reloadScript(model.url) + } + } + HifiControls.FontAwesome { + size: scriptName.height; text: "\uf00d" + MouseArea { + anchors { fill: parent; margins: -2; } + onClicked: stopScript(model.url) + } } } } } } - Text { id: loadLabel text: "Load Scripts" diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7dcb863049..fa730c5d40 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2653,6 +2653,8 @@ void Application::loadSettings() { Menu::getInstance()->loadSettings(); getMyAvatar()->loadData(); + + _settingsLoaded = true; } void Application::saveSettings() { @@ -3276,6 +3278,10 @@ int Application::sendNackPackets() { void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) { + if (!_settingsLoaded) { + return; // bail early if settings are not loaded + } + //qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView(); bool wantExtraDebugging = getLogger()->extraDebugging(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 3840e10c93..30cda33051 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -510,6 +510,8 @@ private: bool _reticleClickPressed { false }; int _avatarAttachmentRequest = 0; + + bool _settingsLoaded { false }; }; #endif // hifi_Application_h diff --git a/interface/src/ui/UpdateDialog.cpp b/interface/src/ui/UpdateDialog.cpp index 6fa2d858fb..4001e615a1 100644 --- a/interface/src/ui/UpdateDialog.cpp +++ b/interface/src/ui/UpdateDialog.cpp @@ -51,10 +51,10 @@ void UpdateDialog::closeDialog() { } void UpdateDialog::hide() { - ((QQuickItem*)parent())->setEnabled(false); + ((QQuickItem*)parent())->setVisible(false); } void UpdateDialog::triggerUpgrade() { auto applicationUpdater = DependencyManager::get(); applicationUpdater.data()->performAutoUpdate(applicationUpdater.data()->getBuildData().lastKey()); -} \ No newline at end of file +} diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 57a29de596..72dc79b882 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -772,8 +772,14 @@ int RenderableModelEntityItem::getJointIndex(const QString& name) const { return -1; } - -// TODO -- expose a way to list joint names -// RenderableModelEntityItem::QStringList getJointNames() const { -// rig->nameOfJoint(i); -// } +QStringList RenderableModelEntityItem::getJointNames() const { + QStringList result; + if (_model && _model->isActive()) { + RigPointer rig = _model->getRig(); + int jointCount = rig->getJointStateCount(); + for (int jointIndex = 0; jointIndex < jointCount; jointIndex++) { + result << rig->nameOfJoint(jointIndex); + } + } + return result; +} diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 834513ecf7..20afb3c157 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -80,6 +80,7 @@ public: virtual void resizeJointArrays(int newSize = -1) override; virtual int getJointIndex(const QString& name) const override; + virtual QStringList getJointNames() const override; private: QVariantMap parseTexturesToMap(QString textures); diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index f40ee88960..9be018183a 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -396,6 +396,7 @@ public: virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; } virtual int getJointIndex(const QString& name) const { return -1; } + virtual QStringList getJointNames() const { return QStringList(); } virtual void loader() {} // called indirectly when urls for geometry are updated diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index f78cd4fd8c..8fd7be912e 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -977,6 +977,18 @@ int EntityScriptingInterface::getJointIndex(const QUuid& entityID, const QString if (!_entityTree) { return -1; } - EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID); - return entity->getJointIndex(name); + int result; + QMetaObject::invokeMethod(_entityTree.get(), "getJointIndex", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(int, result), Q_ARG(QUuid, entityID), Q_ARG(QString, name)); + return result; +} + +QStringList EntityScriptingInterface::getJointNames(const QUuid& entityID) { + if (!_entityTree) { + return QStringList(); + } + QStringList result; + QMetaObject::invokeMethod(_entityTree.get(), "getJointNames", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(QStringList, result), Q_ARG(QUuid, entityID)); + return result; } diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index e7a4c0e071..641da7518e 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -162,6 +162,7 @@ public slots: const QVector& translations); Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name); + Q_INVOKABLE QStringList getJointNames(const QUuid& entityID); signals: void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index eb23034506..2a8d3352b0 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1291,12 +1291,13 @@ void EntityTree::remapIDs() { recurseTreeWithOperator(&theOperator); } -bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues) { +bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues, + bool skipThoseWithBadParents) { if (! entityDescription.contains("Entities")) { entityDescription["Entities"] = QVariantList(); } QScriptEngine scriptEngine; - RecurseOctreeToMapOperator theOperator(entityDescription, element, &scriptEngine, skipDefaultValues); + RecurseOctreeToMapOperator theOperator(entityDescription, element, &scriptEngine, skipDefaultValues, skipThoseWithBadParents); recurseTreeWithOperator(&theOperator); return true; } @@ -1358,7 +1359,6 @@ void EntityTree::trackIncomingEntityLastEdited(quint64 lastEditedTime, int bytes } } - void EntityTree::callLoader(EntityItemID entityID) { // this is used to bounce from the networking thread to the main thread EntityItemPointer entity = findEntityByEntityItemID(entityID); @@ -1366,3 +1366,21 @@ void EntityTree::callLoader(EntityItemID entityID) { entity->loader(); } } + +int EntityTree::getJointIndex(const QUuid& entityID, const QString& name) const { + EntityTree* nonConstThis = const_cast(this); + EntityItemPointer entity = nonConstThis->findEntityByEntityItemID(entityID); + if (!entity) { + return -1; + } + return entity->getJointIndex(name); +} + +QStringList EntityTree::getJointNames(const QUuid& entityID) const { + EntityTree* nonConstThis = const_cast(this); + EntityItemPointer entity = nonConstThis->findEntityByEntityItemID(entityID); + if (!entity) { + return QStringList(); + } + return entity->getJointNames(); +} diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 0f77c4af9a..b1d8a31254 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -199,7 +199,8 @@ public: void remapIDs(); - virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues) override; + virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues, + bool skipThoseWithBadParents) override; virtual bool readFromMap(QVariantMap& entityDescription) override; float getContentsLargestDimension(); @@ -236,6 +237,10 @@ public: return _deletedEntityItemIDs.contains(id); } + // these are used to call through to EntityItems + Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name) const; + Q_INVOKABLE QStringList getJointNames(const QUuid& entityID) const; + public slots: void callLoader(EntityItemID entityID); diff --git a/libraries/entities/src/RecurseOctreeToMapOperator.cpp b/libraries/entities/src/RecurseOctreeToMapOperator.cpp index 81465bfaf5..e930d5ef5f 100644 --- a/libraries/entities/src/RecurseOctreeToMapOperator.cpp +++ b/libraries/entities/src/RecurseOctreeToMapOperator.cpp @@ -16,12 +16,14 @@ RecurseOctreeToMapOperator::RecurseOctreeToMapOperator(QVariantMap& map, OctreeElementPointer top, QScriptEngine* engine, - bool skipDefaultValues) : + bool skipDefaultValues, + bool skipThoseWithBadParents) : RecurseOctreeOperator(), _map(map), _top(top), _engine(engine), - _skipDefaultValues(skipDefaultValues) + _skipDefaultValues(skipDefaultValues), + _skipThoseWithBadParents(skipThoseWithBadParents) { // if some element "top" was given, only save information for that element and its children. if (_top) { @@ -47,6 +49,10 @@ bool RecurseOctreeToMapOperator::postRecursion(OctreeElementPointer element) { QVariantList entitiesQList = qvariant_cast(_map["Entities"]); entityTreeElement->forEachEntity([&](EntityItemPointer entityItem) { + if (_skipThoseWithBadParents && !entityItem->isParentIDValid()) { + return; // we weren't able to resolve a parent from _parentID, so don't save this entity. + } + EntityItemProperties properties = entityItem->getProperties(); QScriptValue qScriptValues; if (_skipDefaultValues) { diff --git a/libraries/entities/src/RecurseOctreeToMapOperator.h b/libraries/entities/src/RecurseOctreeToMapOperator.h index 35c7f1b6a9..c64cf91b61 100644 --- a/libraries/entities/src/RecurseOctreeToMapOperator.h +++ b/libraries/entities/src/RecurseOctreeToMapOperator.h @@ -13,7 +13,8 @@ class RecurseOctreeToMapOperator : public RecurseOctreeOperator { public: - RecurseOctreeToMapOperator(QVariantMap& map, OctreeElementPointer top, QScriptEngine* engine, bool skipDefaultValues); + RecurseOctreeToMapOperator(QVariantMap& map, OctreeElementPointer top, QScriptEngine* engine, bool skipDefaultValues, + bool skipThoseWithBadParents); bool preRecursion(OctreeElementPointer element); bool postRecursion(OctreeElementPointer element); private: @@ -22,4 +23,5 @@ public: QScriptEngine* _engine; bool _withinTop; bool _skipDefaultValues; + bool _skipThoseWithBadParents; }; diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index bdad5682a9..a685c2580c 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -1919,7 +1919,7 @@ void Octree::writeToJSONFile(const char* fileName, OctreeElementPointer element, entityDescription["Version"] = (int) expectedVersion; // store the entity data - bool entityDescriptionSuccess = writeToMap(entityDescription, top, true); + bool entityDescriptionSuccess = writeToMap(entityDescription, top, true, true); if (!entityDescriptionSuccess) { qCritical("Failed to convert Entities to QVariantMap while saving to json."); return; diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index 789d0f5600..0939ae37f6 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -304,7 +304,8 @@ public: void writeToFile(const char* filename, OctreeElementPointer element = NULL, QString persistAsFileType = "svo"); void writeToJSONFile(const char* filename, OctreeElementPointer element = NULL, bool doGzip = false); void writeToSVOFile(const char* filename, OctreeElementPointer element = NULL); - virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues) = 0; + virtual bool writeToMap(QVariantMap& entityDescription, OctreeElementPointer element, bool skipDefaultValues, + bool skipThoseWithBadParents) = 0; // Octree importers bool readFromFile(const char* filename); diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index dc38671091..75783fa6d5 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -118,6 +118,8 @@ public: void die() { _isDead = true; } bool isDead() const { return _isDead; } + bool isParentIDValid() const { bool success = false; getParentPointer(success); return success; } + protected: const NestableType _nestableType; // EntityItem or an AvatarData QUuid _id;