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 | 2816 | auto entityTree = getEntities()->getTree(); |
| 2817 | 2817 | auto exportTree = std::make_shared<EntityTree>(); |
| 2818 | 2818 | exportTree->createRootElement(); |
| 2819 | − | |
| 2820 | 2819 | glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE); |
| 2821 | − for (auto entityID : entityIDs) { // Gather entities and properties. | |
| 2822 | − auto entityItem = entityTree->findEntityByEntityItemID(entityID); | |
| 2823 | − if (!entityItem) { | |
| 2824 | − qCWarning(interfaceapp) << "Skipping export of" << entityID << "that is not in scene."; | |
| 2825 | − continue; | |
| 2826 | − } | |
| 2820 | + bool success = true; | |
| 2821 | + entityTree->withReadLock([&] { | |
| 2822 | + for (auto entityID : entityIDs) { // Gather entities and properties. | |
| 2823 | + auto entityItem = entityTree->findEntityByEntityItemID(entityID); | |
| 2824 | + if (!entityItem) { | |
| 2825 | + qCWarning(interfaceapp) << "Skipping export of" << entityID << "that is not in scene."; | |
| 2826 | + continue; | |
| 2827 | + } | |
| 2827 | 2828 | |
| 2828 | − if (!givenOffset) { | |
| 2829 | − EntityItemID parentID = entityItem->getParentID(); | |
| 2830 | − 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 | − root.x = glm::min(root.x, position.x); | |
| 2833 | − root.y = glm::min(root.y, position.y); | |
| 2834 | − root.z = glm::min(root.z, position.z); | |
| 2829 | + if (!givenOffset) { | |
| 2830 | + EntityItemID parentID = entityItem->getParentID(); | |
| 2831 | + if (parentID.isInvalidID() || !entityIDs.contains(parentID) || !entityTree->findEntityByEntityItemID(parentID)) { | |
| 2832 | + auto position = entityItem->getPosition(); // If parent wasn't selected, we want absolute position, which isn't in properties. | |
| 2833 | + root.x = glm::min(root.x, position.x); | |
| 2834 | + root.y = glm::min(root.y, position.y); | |
| 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 | − return false; | |
| 2842 | − } | |
| 2843 | − | |
| 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 | − } | |
| 2841 | + if (entities.size() == 0) { | |
| 2842 | + success = false; | |
| 2843 | + return; | |
| 2844 | + } | |
| 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 | |
| 2861 | − _window->activateWindow(); | |
| 2862 | − return true; | |
| 2864 | + // restore the main window's active state | |
| 2865 | + _window->activateWindow(); | |
| 2866 | + } | |
| 2867 | + return success; | |
| 2863 | 2868 | } |
| 2864 | 2869 | |
| 2865 | 2870 | bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) { |
| 2866 | 2871 | glm::vec3 offset(x, y, z); |
| 2867 | 2872 | QVector<EntityItemPointer> entities; |
| 2868 | 2873 | QVector<EntityItemID> ids; |
| 2869 | − getEntities()->getTree()->findEntities(AACube(offset, scale), entities); | |
| 2870 | − foreach(EntityItemPointer entity, entities) { | |
| 2871 | − ids << entity->getEntityItemID(); | |
| 2872 | − } | |
| 2874 | + auto entityTree = getEntities()->getTree(); | |
| 2875 | + entityTree->withReadLock([&] { | |
| 2876 | + entityTree->findEntities(AACube(offset, scale), entities); | |
| 2877 | + foreach(EntityItemPointer entity, entities) { | |
| 2878 | + ids << entity->getEntityItemID(); | |
| 2879 | + } | |
| 2880 | + }); | |
| 2873 | 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 | 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); | |
| 2905 | − if (success) { | |
| 2906 | − _entityClipboard->reaverageOctreeElements(); | |
| 2907 | − } | |
| 2914 | + success = _entityClipboard->readFromURL(urlOrFilename); | |
| 2915 | + if (success) { | |
| 2916 | + _entityClipboard->reaverageOctreeElements(); | |
| 2917 | + } | |
| 2918 | + }); | |
| 2908 | 2919 | return success; |
| 2909 | 2920 | } |
| 2910 | 2921 | |