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 "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<LimitedNodeList>();
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;
}
}

View file

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