Handle collision events when we do other updates (and their entity scripts) rather than when we do the physic updates while the tree is locked.
Given that, remove the check that kept sound from playing (or scripts from running) when we would have deadlocked, because now we don't.
This commit is contained in:
Howard Stearns 2015-05-20 11:07:03 -07:00
parent f188078623
commit c5b8dd51d8
2 changed files with 5 additions and 12 deletions

View file

@ -2461,7 +2461,6 @@ void Application::update(float deltaTime) {
if (_physicsEngine.hasOutgoingChanges()) { if (_physicsEngine.hasOutgoingChanges()) {
_entitySimulation.lock(); _entitySimulation.lock();
_entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges(), _physicsEngine.getSessionID()); _entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges(), _physicsEngine.getSessionID());
_entitySimulation.handleCollisionEvents(_physicsEngine.getCollisionEvents());
_entitySimulation.unlock(); _entitySimulation.unlock();
_physicsEngine.dumpStatsIfNecessary(); _physicsEngine.dumpStatsIfNecessary();
} }
@ -2469,9 +2468,11 @@ void Application::update(float deltaTime) {
if (!_aboutToQuit) { if (!_aboutToQuit) {
PerformanceTimer perfTimer("entities"); PerformanceTimer perfTimer("entities");
// NOTE: the _entities.update() call below will wait for lock // Collision events (and their scripts) must not be handled when we're locked, above. (That would risk deadlock.)
_entitySimulation.handleCollisionEvents(_physicsEngine.getCollisionEvents());
// NOTE: the _entities.update() call below will wait for lock
// and will simulate entity motion (the EntityTree has been given an EntitySimulation). // and will simulate entity motion (the EntityTree has been given an EntitySimulation).
_entities.update(); // update the models... _entities.update(); // update the models...
} }
{ {

View file

@ -1174,8 +1174,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons
if (!_tree || _shuttingDown) { if (!_tree || _shuttingDown) {
return; return;
} }
// Don't respond to small continuous contacts. It causes deadlocks when locking the entityTree. // Don't respond to small continuous contacts.
// Note that any entity script is likely to Entities.getEntityProperties(), which locks the tree.
const float COLLISION_MINUMUM_PENETRATION = 0.005; const float COLLISION_MINUMUM_PENETRATION = 0.005;
if ((collision.type != CONTACT_EVENT_TYPE_START) && (glm::length(collision.penetration) < COLLISION_MINUMUM_PENETRATION)) { if ((collision.type != CONTACT_EVENT_TYPE_START) && (glm::length(collision.penetration) < COLLISION_MINUMUM_PENETRATION)) {
return; return;
@ -1183,16 +1182,9 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons
// See if we should play sounds // See if we should play sounds
EntityTree* entityTree = static_cast<EntityTree*>(_tree); EntityTree* entityTree = static_cast<EntityTree*>(_tree);
if (!entityTree->tryLockForRead()) {
// I don't know why this can happen, but if it does,
// the consequences are a deadlock, so bail.
qCDebug(entitiesrenderer) << "NOTICE: skipping collision type " << collision.type << " penetration " << glm::length(collision.penetration);
return;
}
const QUuid& myNodeID = DependencyManager::get<NodeList>()->getSessionUUID(); const QUuid& myNodeID = DependencyManager::get<NodeList>()->getSessionUUID();
playEntityCollisionSound(myNodeID, entityTree, idA, collision); playEntityCollisionSound(myNodeID, entityTree, idA, collision);
playEntityCollisionSound(myNodeID, entityTree, idB, collision); playEntityCollisionSound(myNodeID, entityTree, idB, collision);
entityTree->unlock();
// And now the entity scripts // And now the entity scripts
QScriptValue entityScriptA = loadEntityScript(idA); QScriptValue entityScriptA = loadEntityScript(idA);