Lock trees on import export
Showing the changes to interface/src/Application.cpp (1 of 2 files). Show all
Unified · Split
| @@ -2816,60 +2816,68 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt · 2815 unmodified lines | |||
| 2816 | auto entityTree = getEntities()->getTree(); | 2816 | auto entityTree = getEntities()->getTree(); |
| 2817 | auto exportTree = std::make_shared<EntityTree>(); | 2817 | auto exportTree = std::make_shared<EntityTree>(); |
| 2818 | exportTree->createRootElement(); | 2818 | exportTree->createRootElement(); |
| 2819 | |||
| 2820 | glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE); | 2819 | glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE); |
| 2821 | for (auto entityID : entityIDs) { // Gather entities and properties. | 2820 | bool success = true; |
| 2822 | auto entityItem = entityTree->findEntityByEntityItemID(entityID); | 2821 | entityTree->withReadLock([&] { |
| 2823 | if (!entityItem) { | 2822 | for (auto entityID : entityIDs) { // Gather entities and properties. |
| 2824 | qCWarning(interfaceapp) << "Skipping export of" << entityID << "that is not in scene."; | 2823 | auto entityItem = entityTree->findEntityByEntityItemID(entityID); |
| 2825 | continue; | 2824 | if (!entityItem) { |
| 2826 | } | 2825 | qCWarning(interfaceapp) << "Skipping export of" << entityID << "that is not in scene."; |
| 2826 | continue; | ||
| 2827 | } | ||
| 2827 | 2828 | ||
| 2828 | if (!givenOffset) { | 2829 | if (!givenOffset) { |
| 2829 | EntityItemID parentID = entityItem->getParentID(); | 2830 | EntityItemID parentID = entityItem->getParentID(); |
| 2830 | if (parentID.isInvalidID() || !entityIDs.contains(parentID) || !entityTree->findEntityByEntityItemID(parentID)) { | 2831 | if (parentID.isInvalidID() || !entityIDs.contains(parentID) || !entityTree->findEntityByEntityItemID(parentID)) { |
| 2831 | auto position = entityItem->getPosition(); // If parent wasn't selected, we want absolute position, which isn't in properties. | 2832 | auto position = entityItem->getPosition(); // If parent wasn't selected, we want absolute position, which isn't in properties. |
| 2832 | root.x = glm::min(root.x, position.x); | 2833 | root.x = glm::min(root.x, position.x); |
| 2833 | root.y = glm::min(root.y, position.y); | 2834 | root.y = glm::min(root.y, position.y); |
| 2834 | root.z = glm::min(root.z, position.z); | 2835 | root.z = glm::min(root.z, position.z); |
| 2836 | } | ||
| 2835 | } | 2837 | } |
| 2838 | entities[entityID] = entityItem; | ||
| 2836 | } | 2839 | } |
| 2837 | entities[entityID] = entityItem; | ||
| 2838 | } | ||
| 2839 | 2840 | ||
| 2840 | if (entities.size() == 0) { | 2841 | if (entities.size() == 0) { |
| 2841 | return false; | 2842 | success = false; |
| 2842 | } | 2843 | return; |
| 2843 | 2844 | } | |
| 2844 | if (givenOffset) { | ||
| 2845 | root = *givenOffset; | ||
| 2846 | } | ||
| 2847 | for (EntityItemPointer& entityDatum : entities) { | ||
| 2848 | auto properties = entityDatum->getProperties(); | ||
| 2849 | EntityItemID parentID = properties.getParentID(); | ||
| 2850 | if (parentID.isInvalidID()) { | ||
| 2851 | properties.setPosition(properties.getPosition() - root); | ||
| 2852 | } else if (!entities.contains(parentID)) { | ||
| 2853 | entityDatum->globalizeProperties(properties, "Parent %3 of %2 %1 is not selected for export.", -root); | ||
| 2854 | } // else valid parent -- don't offset | ||
| 2855 | exportTree->addEntity(entityDatum->getEntityItemID(), properties); | ||
| 2856 | } | ||
| 2857 | 2845 | ||
| 2858 | exportTree->writeToJSONFile(filename.toLocal8Bit().constData()); | 2846 | if (givenOffset) { |
| 2847 | root = *givenOffset; | ||
| 2848 | } | ||
| 2849 | for (EntityItemPointer& entityDatum : entities) { | ||
| 2850 | auto properties = entityDatum->getProperties(); | ||
| 2851 | EntityItemID parentID = properties.getParentID(); | ||
| 2852 | if (parentID.isInvalidID()) { | ||
| 2853 | properties.setPosition(properties.getPosition() - root); | ||
| 2854 | } | ||
| 2855 | else if (!entities.contains(parentID)) { | ||
| 2856 | entityDatum->globalizeProperties(properties, "Parent %3 of %2 %1 is not selected for export.", -root); | ||
| 2857 | } // else valid parent -- don't offset | ||
| 2858 | exportTree->addEntity(entityDatum->getEntityItemID(), properties); | ||
| 2859 | } | ||
| 2860 | }); | ||
| 2861 | if (success) { | ||
| 2862 | exportTree->writeToJSONFile(filename.toLocal8Bit().constData()); | ||
| 2859 | 2863 | ||
| 2860 | // restore the main window's active state | 2864 | // restore the main window's active state |
| 2861 | _window->activateWindow(); | 2865 | _window->activateWindow(); |
| 2862 | return true; | 2866 | } |
| 2867 | return success; | ||
| 2863 | } | 2868 | } |
| 2864 | 2869 | ||
| 2865 | bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) { | 2870 | bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) { |
| 2866 | glm::vec3 offset(x, y, z); | 2871 | glm::vec3 offset(x, y, z); |
| 2867 | QVector<EntityItemPointer> entities; | 2872 | QVector<EntityItemPointer> entities; |
| 2868 | QVector<EntityItemID> ids; | 2873 | QVector<EntityItemID> ids; |
| 2869 | getEntities()->getTree()->findEntities(AACube(offset, scale), entities); | 2874 | auto entityTree = getEntities()->getTree(); |
| 2870 | foreach(EntityItemPointer entity, entities) { | 2875 | entityTree->withReadLock([&] { |
| 2871 | ids << entity->getEntityItemID(); | 2876 | entityTree->findEntities(AACube(offset, scale), entities); |
| 2872 | } | 2877 | foreach(EntityItemPointer entity, entities) { |
| 2878 | ids << entity->getEntityItemID(); | ||
| 2879 | } | ||
| 2880 | }); | ||
| 2873 | return exportEntities(filename, ids, &offset); | 2881 | return exportEntities(filename, ids, &offset); |
| 2874 | } | 2882 | } |
| 2875 | 2883 | ||
| @@ -2899,12 +2907,15 @@ void Application::saveSettings() { · 23 unmodified lines | |||
| 2899 | } | 2907 | } |
| 2900 | 2908 | ||
| 2901 | bool Application::importEntities(const QString& urlOrFilename) { | 2909 | bool Application::importEntities(const QString& urlOrFilename) { |
| 2902 | _entityClipboard->eraseAllOctreeElements(); | 2910 | bool success = false; |
| 2911 | _entityClipboard->withWriteLock([&] { | ||
| 2912 | _entityClipboard->eraseAllOctreeElements(); | ||
| 2903 | 2913 | ||
| 2904 | bool success = _entityClipboard->readFromURL(urlOrFilename); | 2914 | success = _entityClipboard->readFromURL(urlOrFilename); |
| 2905 | if (success) { | 2915 | if (success) { |
| 2906 | _entityClipboard->reaverageOctreeElements(); | 2916 | _entityClipboard->reaverageOctreeElements(); |
| 2907 | } | 2917 | } |
| 2918 | }); | ||
| 2908 | return success; | 2919 | return success; |
| 2909 | } | 2920 | } |
| 2910 | 2921 | ||