call leaveEntity when script stops

This commit is contained in:
SamGondelman 2019-04-19 14:53:23 -07:00
parent c09e0eca1d
commit 703a4a5700
2 changed files with 35 additions and 29 deletions

View file

@ -205,8 +205,11 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() {
foreach (const EntityItemID& entityID, entitiesWithEntityScripts) { foreach (const EntityItemID& entityID, entitiesWithEntityScripts) {
EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID);
if (entityItem) { if (entityItem && !entityItem->getScript().isEmpty()) {
if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) { if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) {
if (entityItem->contains(_avatarPosition)) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
}
_entitiesScriptEngine->unloadEntityScript(entityID, true); _entitiesScriptEngine->unloadEntityScript(entityID, true);
} }
} }
@ -534,7 +537,7 @@ void EntityTreeRenderer::handleSpaceUpdate(std::pair<int32_t, glm::vec4> proxyUp
_spaceUpdates.emplace_back(proxyUpdate.first, proxyUpdate.second); _spaceUpdates.emplace_back(proxyUpdate.first, proxyUpdate.second);
} }
bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityItemID>* entitiesContainingAvatar) { bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar) {
bool didUpdate = false; bool didUpdate = false;
float radius = 0.01f; // for now, assume 0.01 meter radius, because we actually check the point inside later float radius = 0.01f; // for now, assume 0.01 meter radius, because we actually check the point inside later
QVector<QUuid> entityIDs; QVector<QUuid> entityIDs;
@ -580,9 +583,7 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityIt
} }
if ((!hasScript && isZone) || scriptHasLoaded) { if ((!hasScript && isZone) || scriptHasLoaded) {
if (entitiesContainingAvatar) { entitiesContainingAvatar << entity->getEntityItemID();
*entitiesContainingAvatar << entity->getEntityItemID();
}
} }
} }
} }
@ -616,36 +617,36 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
auto movedEnough = glm::distance(avatarPosition, _avatarPosition) > ZONE_CHECK_DISTANCE; auto movedEnough = glm::distance(avatarPosition, _avatarPosition) > ZONE_CHECK_DISTANCE;
auto enoughTimeElapsed = (now - _lastZoneCheck) > ZONE_CHECK_INTERVAL; auto enoughTimeElapsed = (now - _lastZoneCheck) > ZONE_CHECK_INTERVAL;
if (movedEnough || enoughTimeElapsed) { if (_forceRecheckEntities || movedEnough || enoughTimeElapsed) {
_avatarPosition = avatarPosition; _avatarPosition = avatarPosition;
_lastZoneCheck = now; _lastZoneCheck = now;
QVector<EntityItemID> entitiesContainingAvatar; _forceRecheckEntities = false;
didUpdate = findBestZoneAndMaybeContainingEntities(&entitiesContainingAvatar);
QSet<EntityItemID> entitiesContainingAvatar;
didUpdate = findBestZoneAndMaybeContainingEntities(entitiesContainingAvatar);
// Note: at this point we don't need to worry about the tree being locked, because we only deal with // Note: at this point we don't need to worry about the tree being locked, because we only deal with
// EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts // EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts
// for entity IDs that no longer exist. // for entity IDs that no longer exist.
// for all of our previous containing entities, if they are no longer containing then send them a leave event if (_entitiesScriptEngine) {
foreach(const EntityItemID& entityID, _currentEntitiesInside) { // for all of our previous containing entities, if they are no longer containing then send them a leave event
if (!entitiesContainingAvatar.contains(entityID)) { foreach(const EntityItemID& entityID, _currentEntitiesInside) {
emit leaveEntity(entityID); if (!entitiesContainingAvatar.contains(entityID)) {
if (_entitiesScriptEngine) { emit leaveEntity(entityID);
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
} }
} }
}
// for all of our new containing entities, if they weren't previously containing then send them an enter event // for all of our new containing entities, if they weren't previously containing then send them an enter event
foreach(const EntityItemID& entityID, entitiesContainingAvatar) { foreach(const EntityItemID& entityID, entitiesContainingAvatar) {
if (!_currentEntitiesInside.contains(entityID)) { if (!_currentEntitiesInside.contains(entityID)) {
emit enterEntity(entityID); emit enterEntity(entityID);
if (_entitiesScriptEngine) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "enterEntity"); _entitiesScriptEngine->callEntityScriptMethod(entityID, "enterEntity");
} }
} }
_currentEntitiesInside = entitiesContainingAvatar;
} }
_currentEntitiesInside = entitiesContainingAvatar;
} }
} }
return didUpdate; return didUpdate;
@ -653,7 +654,7 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() { void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() {
if (_tree && !_shuttingDown) { if (_tree && !_shuttingDown) {
QVector<EntityItemID> currentEntitiesInsideToSave; QSet<EntityItemID> currentEntitiesInsideToSave;
foreach (const EntityItemID& entityID, _currentEntitiesInside) { foreach (const EntityItemID& entityID, _currentEntitiesInside) {
EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID);
if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) { if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) {
@ -662,7 +663,7 @@ void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
} }
} else { } else {
currentEntitiesInsideToSave.push_back(entityID); currentEntitiesInsideToSave.insert(entityID);
} }
} }
@ -687,9 +688,7 @@ void EntityTreeRenderer::leaveAllEntities() {
} }
void EntityTreeRenderer::forceRecheckEntities() { void EntityTreeRenderer::forceRecheckEntities() {
// make sure our "last avatar position" is something other than our current position, _forceRecheckEntities = true;
// so that on our next chance, we'll check for enter/leave entity events.
_avatarPosition = _viewState->getAvatarPosition() + glm::vec3((float)TREE_SCALE);
} }
bool EntityTreeRenderer::applyLayeredZones() { bool EntityTreeRenderer::applyLayeredZones() {
@ -992,7 +991,10 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
return; return;
} }
if (_tree && !_shuttingDown && _entitiesScriptEngine) { if (_tree && !_shuttingDown && _entitiesScriptEngine && !itr->second->getEntity()->getScript().isEmpty()) {
if (itr->second->getEntity()->contains(_avatarPosition)) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
}
_entitiesScriptEngine->unloadEntityScript(entityID, true); _entitiesScriptEngine->unloadEntityScript(entityID, true);
} }
@ -1038,6 +1040,9 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool
QString scriptUrl = entity->getScript(); QString scriptUrl = entity->getScript();
if ((shouldLoad && unloadFirst) || scriptUrl.isEmpty()) { if ((shouldLoad && unloadFirst) || scriptUrl.isEmpty()) {
if (_entitiesScriptEngine) { if (_entitiesScriptEngine) {
if (entity->contains(_avatarPosition)) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
}
_entitiesScriptEngine->unloadEntityScript(entityID); _entitiesScriptEngine->unloadEntityScript(entityID);
} }
entity->scriptHasUnloaded(); entity->scriptHasUnloaded();

View file

@ -169,7 +169,7 @@ private:
void resetEntitiesScriptEngine(); void resetEntitiesScriptEngine();
bool findBestZoneAndMaybeContainingEntities(QVector<EntityItemID>* entitiesContainingAvatar = nullptr); bool findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar);
bool applyLayeredZones(); bool applyLayeredZones();
void stopDomainAndNonOwnedEntities(); void stopDomainAndNonOwnedEntities();
@ -186,7 +186,8 @@ private:
void forceRecheckEntities(); void forceRecheckEntities();
glm::vec3 _avatarPosition { 0.0f }; glm::vec3 _avatarPosition { 0.0f };
QVector<EntityItemID> _currentEntitiesInside; bool _forceRecheckEntities { true };
QSet<EntityItemID> _currentEntitiesInside;
bool _wantScripts; bool _wantScripts;
ScriptEnginePointer _entitiesScriptEngine; ScriptEnginePointer _entitiesScriptEngine;