From 381049acb3d0393c7b52f3e31ccbf7498927799f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 2 Feb 2016 14:28:59 -0800 Subject: [PATCH] clear simulation ownership when owners vanish --- .../entities/src/SimpleEntitySimulation.cpp | 44 ++++++++++++------- .../entities/src/SimpleEntitySimulation.h | 1 + 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index 120b536161..f0461abb97 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -15,34 +15,46 @@ #include "SimpleEntitySimulation.h" #include "EntitiesLogging.h" -const quint64 AUTO_REMOVE_SIMULATION_OWNER_USEC = 2 * USECS_PER_SECOND; +const quint64 MIN_SIMULATION_OWNERSHIP_UPDATE_PERIOD = 2 * USECS_PER_SECOND; 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(); + if (_entitiesWithSimulator.size() == 0) { + return; + } + + if (now < _nextSimulationExpiry) { + // nothing has expired yet + return; + } + + // If an Entity has a simulation owner but there has been no update for a while: clear the owner. + // If an Entity goes ownerless for too long: zero velocity and remove from _entitiesWithSimulator. + _nextSimulationExpiry = now + MIN_SIMULATION_OWNERSHIP_UPDATE_PERIOD; QMutexLocker lock(&_mutex); 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); + quint64 expiry = entity->getLastChangedOnServer() + MIN_SIMULATION_OWNERSHIP_UPDATE_PERIOD; + if (expiry < now) { + if (entity->getSimulatorID().isNull()) { + // no simulators are volunteering // zero the velocity on this entity so that it doesn't drift far away entity->setVelocity(glm::vec3(0.0f)); + // remove from list + itemItr = _entitiesWithSimulator.erase(itemItr); + continue; } else { - ++itemItr; + // the simulator has stopped updating this object + // clear ownership and restart timer, giving nearby simulators time to volunteer + qCDebug(entities) << "auto-removing simulation owner " << entity.getSimulatorID(); + entity->clearSimulationOwnership(); + entity->markAsChangedOnServer(); } - } else { - ++itemItr; + } else if (expiry < _nextSimulationExpiry) { + _nextSimulationExpiry = expiry; } + ++itemItr; } } diff --git a/libraries/entities/src/SimpleEntitySimulation.h b/libraries/entities/src/SimpleEntitySimulation.h index 83c51525a8..53a7574bf2 100644 --- a/libraries/entities/src/SimpleEntitySimulation.h +++ b/libraries/entities/src/SimpleEntitySimulation.h @@ -29,6 +29,7 @@ protected: virtual void clearEntitiesInternal() override; SetOfEntities _entitiesWithSimulator; + quint64 _nextSimulationExpiry { 0 }; }; #endif // hifi_SimpleEntitySimulation_h