From 86f7c28ee93151d4f713a3540a913c040d00e3b9 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 27 Jan 2015 10:24:28 -0800 Subject: [PATCH 1/2] Update EntityScriptingInterface::deleteEntity to not delete when known entity is locked --- .../entities/src/EntityScriptingInterface.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 6226012052..166e6d2819 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -144,15 +144,26 @@ void EntityScriptingInterface::deleteEntity(EntityItemID entityID) { } } + bool shouldDelete = true; + // If we have a local entity tree set, then also update it. if (_entityTree) { _entityTree->lockForWrite(); - _entityTree->deleteEntity(entityID); + + EntityItem* entity = const_cast(_entityTree->findEntityByEntityItemID(actualID)); + if (entity) { + if (entity->getLocked()) { + shouldDelete = false; + } else { + _entityTree->deleteEntity(entityID); + } + } + _entityTree->unlock(); } - // if at this point, we know the id, send the update to the entity server - if (entityID.isKnownID) { + // if at this point, we know the id, and we should still delete the entity, send the update to the entity server + if (shouldDelete && entityID.isKnownID) { getEntityPacketSender()->queueEraseEntityMessage(entityID); } } From f65640a5934401551b9ebc629a5e1348b3ee0c50 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 27 Jan 2015 10:24:54 -0800 Subject: [PATCH 2/2] Update EntityTree.cpp to not delete entity when locked --- libraries/entities/src/EntityTree.cpp | 42 +++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 580fed8790..a0a8a33ca8 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -229,6 +229,23 @@ void EntityTree::setSimulation(EntitySimulation* simulation) { } void EntityTree::deleteEntity(const EntityItemID& entityID) { + EntityTreeElement* containingElement = getContainingElement(entityID); + if (!containingElement) { + qDebug() << "UNEXPECTED!!!! EntityTree::deleteEntity() entityID doesn't exist!!! entityID=" << entityID; + return; + } + + EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID); + if (!existingEntity) { + qDebug() << "UNEXPECTED!!!! don't call EntityTree::deleteEntity() on entity items that don't exist. entityID=" << entityID; + return; + } + + if (existingEntity->getLocked()) { + qDebug() << "ERROR! EntityTree::deleteEntity() trying to delete locked entity. entityID=" << entityID; + return; + } + emit deletingEntity(entityID); // NOTE: callers must lock the tree before using this method @@ -242,14 +259,33 @@ void EntityTree::deleteEntities(QSet entityIDs) { // NOTE: callers must lock the tree before using this method DeleteEntityOperator theOperator(this); foreach(const EntityItemID& entityID, entityIDs) { + EntityTreeElement* containingElement = getContainingElement(entityID); + if (!containingElement) { + qDebug() << "UNEXPECTED!!!! EntityTree::deleteEntities() entityID doesn't exist!!! entityID=" << entityID; + continue; + } + + EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID); + if (!existingEntity) { + qDebug() << "UNEXPECTED!!!! don't call EntityTree::deleteEntities() on entity items that don't exist. entityID=" << entityID; + continue; + } + + if (existingEntity->getLocked()) { + qDebug() << "ERROR! EntityTree::deleteEntities() trying to delete locked entity. entityID=" << entityID; + continue; + } + // tell our delete operator about this entityID theOperator.addEntityIDToDeleteList(entityID); emit deletingEntity(entityID); } - recurseTreeWithOperator(&theOperator); - processRemovedEntities(theOperator); - _isDirty = true; + if (theOperator.getEntities().size() > 0) { + recurseTreeWithOperator(&theOperator); + processRemovedEntities(theOperator); + _isDirty = true; + } } void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) {