Showing the changes to libraries/entities/src/EntityScriptingInterface.cpp (1 of 25 files). Show all
Unified · Split
| @@ -966,42 +966,52 @@ void EntityScriptingInterface::deleteEntity(const QUuid& id) { · 965 unmodified lines | ||
| 966 | 966 | |
| 967 | 967 | _activityTracking.deletedEntityCount++; |
| 968 | 968 | |
| 969 | + if (!_entityTree) { | |
| 970 | + return; | |
| 971 | + } | |
| 972 | + | |
| 969 | 973 | EntityItemID entityID(id); |
| 970 | − bool shouldSendDeleteToServer = true; | |
| 971 | 974 | |
| 972 | 975 | // If we have a local entity tree set, then also update it. |
| 973 | − if (_entityTree) { | |
| 974 | − _entityTree->withWriteLock([&] { | |
| 975 | − EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID); | |
| 976 | − if (entity) { | |
| 977 | − auto nodeList = DependencyManager::get<NodeList>(); | |
| 978 | − const QUuid myNodeID = nodeList->getSessionUUID(); | |
| 979 | − if (entity->isAvatarEntity() && !entity->isMyAvatarEntity()) { | |
| 980 | − // don't delete other avatar's avatarEntities | |
| 981 | − shouldSendDeleteToServer = false; | |
| 982 | − return; | |
| 983 | − } | |
| 984 | − | |
| 985 | − if (entity->getLocked()) { | |
| 986 | − shouldSendDeleteToServer = false; | |
| 987 | − } else { | |
| 988 | − // only delete non-domain entities, domain entities will round trip through the server filters | |
| 989 | − if (!entity->isDomainEntity() || _entityTree->isServerlessMode()) { | |
| 990 | − shouldSendDeleteToServer = false; | |
| 991 | − _entityTree->deleteEntity(entityID); | |
| 976 | + SetOfEntities entitiesToDeleteImmediately; | |
| 977 | + SetOfEntities domainEntities; | |
| 978 | + _entityTree->withWriteLock([&] { | |
| 979 | + EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID); | |
| 980 | + if (entity) { | |
| 981 | + if (entity->isAvatarEntity() && !entity->isMyAvatarEntity()) { | |
| 982 | + // don't delete other avatar's avatarEntities | |
| 983 | + return; | |
| 984 | + } | |
| 985 | + if (entity->getLocked()) { | |
| 986 | + return; | |
| 987 | + } | |
| 992 | 988 | |
| 993 | − if (entity->isAvatarEntity() && getEntityPacketSender()->getMyAvatar()) { | |
| 994 | − getEntityPacketSender()->getMyAvatar()->clearAvatarEntity(entityID, false); | |
| 995 | − } | |
| 996 | − } | |
| 997 | − } | |
| 989 | + // Deleting an entity has consequences for linked children: some can be deleted but others can't. | |
| 990 | + // Local- and my-avatar-entities can be deleted immediately, but other-avatar-entities can't be deleted | |
| 991 | + // by this context, and domain-entity deletes must rountrip through the entity-server for authorization. | |
| 992 | + // So we recurse down the linked hierarchy and snarf children into two categories: | |
| 993 | + // (a) entitiesToDeleteImmediately and (b) domainEntntities. | |
| 994 | + if (entity->isDomainEntity()) { | |
| 995 | + domainEntities.insert(entity); | |
| 996 | + } else { | |
| 997 | + entitiesToDeleteImmediately.insert(entity); | |
| 998 | + const auto sessionID = DependencyManager::get<NodeList>()->getSessionUUID(); | |
| 999 | + entity->collectChildrenForDelete(entitiesToDeleteImmediately, domainEntities, sessionID); | |
| 998 | 1000 | } |
| 999 | − }); | |
| 1000 | − } | |
| 1001 | + if (!entitiesToDeleteImmediately.empty()) { | |
| 1002 | + _entityTree->deleteEntitiesByPointer(entitiesToDeleteImmediately); | |
| 1003 | + } | |
| 1004 | + } | |
| 1005 | + }); | |
| 1001 | 1006 | |
| 1002 | − // if at this point, we know the id, and we should still delete the entity, send the update to the entity server | |
| 1003 | − if (shouldSendDeleteToServer) { | |
| 1004 | − getEntityPacketSender()->queueEraseEntityMessage(entityID); | |
| 1007 | + foreach (auto entity, entitiesToDeleteImmediately) { | |
| 1008 | + if (entity->isMyAvatarEntity()) { | |
| 1009 | + getEntityPacketSender()->getMyAvatar()->clearAvatarEntity(entityID, false); | |
| 1010 | + } | |
| 1011 | + } | |
| 1012 | + // finally ask entity-server to delete domainEntities | |
| 1013 | + foreach (auto entity, domainEntities) { | |
| 1014 | + getEntityPacketSender()->queueEraseEntityMessage(entity->getID()); | |
| 1005 | 1015 | } |
| 1006 | 1016 | } |
| 1007 | 1017 | |