void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) { // If an Entity has a simulation owner and we don't get an update for some amount of time, // clear the owner. This guards against an interface failing to release the Entity when it // has finished simulating it. auto nodeList = DependencyManager::get<LimitedNodeList>(); SetOfEntities::iterator itemItr = _entitiesWithSimulator.begin(); while (itemItr != _entitiesWithSimulator.end()) { EntityItemPointer entity = *itemItr; if (entity->getSimulatorID().isNull()) { itemItr = _entitiesWithSimulator.erase(itemItr); } else if (now - entity->getLastChangedOnServer() >= AUTO_REMOVE_SIMULATION_OWNER_USEC) { SharedNodePointer ownerNode = nodeList->nodeWithUUID(entity->getSimulatorID()); if (ownerNode.isNull() || !ownerNode->isAlive()) { qCDebug(entities) << "auto-removing simulation owner" << entity->getSimulatorID(); entity->clearSimulationOwnership(); itemItr = _entitiesWithSimulator.erase(itemItr); // zero the velocity on this entity so that it doesn't drift far away entity->setVelocity(glm::vec3(0.0f)); } else { ++itemItr; } } else { ++itemItr; } } }
void SimpleEntitySimulation::clearOwnership(const QUuid& ownerID) { QMutexLocker lock(&_mutex); SetOfEntities::iterator itemItr = _entitiesWithSimulationOwner.begin(); while (itemItr != _entitiesWithSimulationOwner.end()) { EntityItemPointer entity = *itemItr; if (entity->getSimulatorID() == ownerID) { // the simulator has abandonded this object --> remove from owned list qCDebug(entities) << "auto-removing simulation owner " << entity->getSimulatorID(); itemItr = _entitiesWithSimulationOwner.erase(itemItr); if (entity->getDynamic() && entity->hasLocalVelocity()) { // it is still moving dynamically --> add to orphaned list _entitiesThatNeedSimulationOwner.insert(entity); quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD; if (expiry < _nextOwnerlessExpiry) { _nextOwnerlessExpiry = expiry; } } // remove ownership and dirty all the tree elements that contain the it entity->clearSimulationOwnership(); entity->markAsChangedOnServer(); DirtyOctreeElementOperator op(entity->getElement()); getEntityTree()->recurseTreeWithOperator(&op); } else { ++itemItr; } } }