History

apply delete rules down linked hierarchy

Andrew Meadows committed 7 years ago

Commit 8ab70221 parent 470a45c25 files · +401 −279Browse files

Showing the changes to libraries/entities/src/EntityScriptingInterface.cpp (1 of 25 files). Show all

Unified · Split

libraries/entities/src/EntityScriptingInterface.cpp+40−30
@@ -966,42 +966,52 @@ void EntityScriptingInterface::deleteEntity(const QUuid& id) { · 965 unmodified lines
966 966
967 _activityTracking.deletedEntityCount++;967 _activityTracking.deletedEntityCount++;
968 968
969 if (!_entityTree) {
970 return;
971 }
972
969 EntityItemID entityID(id);973 EntityItemID entityID(id);
970 bool shouldSendDeleteToServer = true;
971 974
972 // If we have a local entity tree set, then also update it.975 // If we have a local entity tree set, then also update it.
973 if (_entityTree) {976 SetOfEntities entitiesToDeleteImmediately;
974 _entityTree->withWriteLock([&] {977 SetOfEntities domainEntities;
975 EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);978 _entityTree->withWriteLock([&] {
976 if (entity) {979 EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
977 auto nodeList = DependencyManager::get<NodeList>();980 if (entity) {
978 const QUuid myNodeID = nodeList->getSessionUUID();981 if (entity->isAvatarEntity() && !entity->isMyAvatarEntity()) {
979 if (entity->isAvatarEntity() && !entity->isMyAvatarEntity()) {982 // don't delete other avatar's avatarEntities
980 // don't delete other avatar's avatarEntities983 return;
981 shouldSendDeleteToServer = false;984 }
982 return;985 if (entity->getLocked()) {
983 }986 return;
984 987 }
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);
992 988
993 if (entity->isAvatarEntity() && getEntityPacketSender()->getMyAvatar()) {989 // Deleting an entity has consequences for linked children: some can be deleted but others can't.
994 getEntityPacketSender()->getMyAvatar()->clearAvatarEntity(entityID, false);990 // Local- and my-avatar-entities can be deleted immediately, but other-avatar-entities can't be deleted
995 }991 // by this context, and domain-entity deletes must rountrip through the entity-server for authorization.
996 }992 // So we recurse down the linked hierarchy and snarf children into two categories:
997 }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 });1001 if (!entitiesToDeleteImmediately.empty()) {
1000 }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 server1007 foreach (auto entity, entitiesToDeleteImmediately) {
1003 if (shouldSendDeleteToServer) {1008 if (entity->isMyAvatarEntity()) {
1004 getEntityPacketSender()->queueEraseEntityMessage(entityID);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