Merge pull request #7547 from howard-stearns/lock-trees-on-import-export

Lock trees on import export
This commit is contained in:
Brad Hefta-Gaub 2016-04-03 14:23:54 -07:00
commit ecaaa34576
2 changed files with 61 additions and 48 deletions

View file

@ -2816,60 +2816,68 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt
auto entityTree = getEntities()->getTree();
auto exportTree = std::make_shared<EntityTree>();
exportTree->createRootElement();
glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE);
for (auto entityID : entityIDs) { // Gather entities and properties.
auto entityItem = entityTree->findEntityByEntityItemID(entityID);
if (!entityItem) {
qCWarning(interfaceapp) << "Skipping export of" << entityID << "that is not in scene.";
continue;
}
if (!givenOffset) {
EntityItemID parentID = entityItem->getParentID();
if (parentID.isInvalidID() || !entityIDs.contains(parentID) || !entityTree->findEntityByEntityItemID(parentID)) {
auto position = entityItem->getPosition(); // If parent wasn't selected, we want absolute position, which isn't in properties.
root.x = glm::min(root.x, position.x);
root.y = glm::min(root.y, position.y);
root.z = glm::min(root.z, position.z);
bool success = true;
entityTree->withReadLock([&] {
for (auto entityID : entityIDs) { // Gather entities and properties.
auto entityItem = entityTree->findEntityByEntityItemID(entityID);
if (!entityItem) {
qCWarning(interfaceapp) << "Skipping export of" << entityID << "that is not in scene.";
continue;
}
if (!givenOffset) {
EntityItemID parentID = entityItem->getParentID();
if (parentID.isInvalidID() || !entityIDs.contains(parentID) || !entityTree->findEntityByEntityItemID(parentID)) {
auto position = entityItem->getPosition(); // If parent wasn't selected, we want absolute position, which isn't in properties.
root.x = glm::min(root.x, position.x);
root.y = glm::min(root.y, position.y);
root.z = glm::min(root.z, position.z);
}
}
entities[entityID] = entityItem;
}
entities[entityID] = entityItem;
}
if (entities.size() == 0) {
return false;
}
if (entities.size() == 0) {
success = false;
return;
}
if (givenOffset) {
root = *givenOffset;
}
for (EntityItemPointer& entityDatum : entities) {
auto properties = entityDatum->getProperties();
EntityItemID parentID = properties.getParentID();
if (parentID.isInvalidID()) {
properties.setPosition(properties.getPosition() - root);
} else if (!entities.contains(parentID)) {
entityDatum->globalizeProperties(properties, "Parent %3 of %2 %1 is not selected for export.", -root);
} // else valid parent -- don't offset
exportTree->addEntity(entityDatum->getEntityItemID(), properties);
}
if (givenOffset) {
root = *givenOffset;
}
for (EntityItemPointer& entityDatum : entities) {
auto properties = entityDatum->getProperties();
EntityItemID parentID = properties.getParentID();
if (parentID.isInvalidID()) {
properties.setPosition(properties.getPosition() - root);
}
else if (!entities.contains(parentID)) {
entityDatum->globalizeProperties(properties, "Parent %3 of %2 %1 is not selected for export.", -root);
} // else valid parent -- don't offset
exportTree->addEntity(entityDatum->getEntityItemID(), properties);
}
});
if (success) {
exportTree->writeToJSONFile(filename.toLocal8Bit().constData());
exportTree->writeToJSONFile(filename.toLocal8Bit().constData());
// restore the main window's active state
_window->activateWindow();
return true;
// restore the main window's active state
_window->activateWindow();
}
return success;
}
bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) {
glm::vec3 offset(x, y, z);
QVector<EntityItemPointer> entities;
QVector<EntityItemID> ids;
getEntities()->getTree()->findEntities(AACube(offset, scale), entities);
foreach(EntityItemPointer entity, entities) {
ids << entity->getEntityItemID();
}
auto entityTree = getEntities()->getTree();
entityTree->withReadLock([&] {
entityTree->findEntities(AACube(offset, scale), entities);
foreach(EntityItemPointer entity, entities) {
ids << entity->getEntityItemID();
}
});
return exportEntities(filename, ids, &offset);
}
@ -2899,12 +2907,15 @@ void Application::saveSettings() {
}
bool Application::importEntities(const QString& urlOrFilename) {
_entityClipboard->eraseAllOctreeElements();
bool success = false;
_entityClipboard->withWriteLock([&] {
_entityClipboard->eraseAllOctreeElements();
bool success = _entityClipboard->readFromURL(urlOrFilename);
if (success) {
_entityClipboard->reaverageOctreeElements();
}
success = _entityClipboard->readFromURL(urlOrFilename);
if (success) {
_entityClipboard->reaverageOctreeElements();
}
});
return success;
}

View file

@ -1323,7 +1323,9 @@ QVector<EntityItemID> EntityTree::sendEntities(EntityEditPacketSender* packetSen
// We need to keep a map so that we can map parent identifiers correctly.
QHash<EntityItemID, EntityItemID> map;
args.map = &map;
recurseTreeWithOperation(sendEntitiesOperation, &args);
withReadLock([&] {
recurseTreeWithOperation(sendEntitiesOperation, &args);
});
packetSender->releaseQueuedMessages();
return map.values().toVector();