clear simulation ownership when owners vanish

This commit is contained in:
Andrew Meadows 2016-02-02 14:28:59 -08:00
parent 05fb866bb5
commit 381049acb3
2 changed files with 29 additions and 16 deletions

View file

@ -15,34 +15,46 @@
#include "SimpleEntitySimulation.h" #include "SimpleEntitySimulation.h"
#include "EntitiesLogging.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) { 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, if (_entitiesWithSimulator.size() == 0) {
// clear the owner. This guards against an interface failing to release the Entity when it return;
// has finished simulating it. }
auto nodeList = DependencyManager::get<LimitedNodeList>();
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); QMutexLocker lock(&_mutex);
SetOfEntities::iterator itemItr = _entitiesWithSimulator.begin(); SetOfEntities::iterator itemItr = _entitiesWithSimulator.begin();
while (itemItr != _entitiesWithSimulator.end()) { while (itemItr != _entitiesWithSimulator.end()) {
EntityItemPointer entity = *itemItr; EntityItemPointer entity = *itemItr;
if (entity->getSimulatorID().isNull()) { quint64 expiry = entity->getLastChangedOnServer() + MIN_SIMULATION_OWNERSHIP_UPDATE_PERIOD;
itemItr = _entitiesWithSimulator.erase(itemItr); if (expiry < now) {
} else if (now - entity->getLastChangedOnServer() >= AUTO_REMOVE_SIMULATION_OWNER_USEC) { if (entity->getSimulatorID().isNull()) {
SharedNodePointer ownerNode = nodeList->nodeWithUUID(entity->getSimulatorID()); // no simulators are volunteering
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 // zero the velocity on this entity so that it doesn't drift far away
entity->setVelocity(glm::vec3(0.0f)); entity->setVelocity(glm::vec3(0.0f));
// remove from list
itemItr = _entitiesWithSimulator.erase(itemItr);
continue;
} else { } 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 { } else if (expiry < _nextSimulationExpiry) {
++itemItr; _nextSimulationExpiry = expiry;
} }
++itemItr;
} }
} }

View file

@ -29,6 +29,7 @@ protected:
virtual void clearEntitiesInternal() override; virtual void clearEntitiesInternal() override;
SetOfEntities _entitiesWithSimulator; SetOfEntities _entitiesWithSimulator;
quint64 _nextSimulationExpiry { 0 };
}; };
#endif // hifi_SimpleEntitySimulation_h #endif // hifi_SimpleEntitySimulation_h