From 81940214bb943958611d1789d6cd6fb52dfb523b Mon Sep 17 00:00:00 2001 From: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com> Date: Mon, 16 Nov 2020 21:20:25 -0800 Subject: [PATCH] Revert "Revert "Split Local and owned Avatar Entity scripts into their own ScriptEngine"" --- .../src/scripts/EntityScriptServer.cpp | 4 +- .../src/EntityTreeRenderer.cpp | 230 +++++++++++------- .../src/EntityTreeRenderer.h | 9 +- .../entities/src/EntityScriptingInterface.cpp | 34 ++- .../entities/src/EntityScriptingInterface.h | 15 +- 5 files changed, 183 insertions(+), 109 deletions(-) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 065ab12abc..16931e8c26 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -470,7 +470,9 @@ void EntityScriptServer::resetEntitiesScriptEngine() { scriptEngines->runScriptInitializers(newEngine); newEngine->runInThread(); auto newEngineSP = qSharedPointerCast(newEngine); - DependencyManager::get()->setEntitiesScriptEngine(newEngineSP); + // On the entity script server, these are the same + DependencyManager::get()->setPersistentEntitiesScriptEngine(newEngineSP); + DependencyManager::get()->setNonPersistentEntitiesScriptEngine(newEngineSP); if (_entitiesScriptEngine) { disconnect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated, diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 3538f07d32..2f9c8c4b3a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -158,79 +158,98 @@ render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& i int EntityTreeRenderer::_entitiesScriptEngineCount = 0; -void EntityTreeRenderer::resetEntitiesScriptEngine() { - _entitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, - QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); - DependencyManager::get()->runScriptInitializers(_entitiesScriptEngine); - _entitiesScriptEngine->runInThread(); - auto entitiesScriptEngineProvider = qSharedPointerCast(_entitiesScriptEngine); +void EntityTreeRenderer::setupEntityScriptEngineSignals(const ScriptEnginePointer& scriptEngine) { auto entityScriptingInterface = DependencyManager::get(); - entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider); - connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) { + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); + // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming + scriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); + }); + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event); + }); + + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event); + }); + connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, scriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { + scriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); + }); + + connect(scriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) { EntityItemPointer entity = getTree()->findEntityByID(entityID); if (entity) { entity->setScriptHasFinishedPreload(true); } }); +} - // Connect mouse events to entity script callbacks - if (!_mouseAndPreloadSignalHandlersConnected) { - - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseDoublePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseDoublePressOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveOnEntity", event); - // FIXME: this is a duplicate of mouseMoveOnEntity, but it seems like some scripts might use this naming - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseMoveEvent", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "mouseReleaseOnEntity", event); - }); - - connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickDownOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::holdingClickOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "holdingClickOnEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickReleaseOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "clickReleaseOnEntity", event); - }); - - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverEnterEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverOverEntity", event); - }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "hoverLeaveEntity", event); - }); - - _mouseAndPreloadSignalHandlersConnected = true; +void EntityTreeRenderer::resetPersistentEntitiesScriptEngine() { + if (_persistentEntitiesScriptEngine) { + _persistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _persistentEntitiesScriptEngine->stop(); + _persistentEntitiesScriptEngine->waitTillDoneRunning(); + _persistentEntitiesScriptEngine->disconnectNonEssentialSignals(); } + _persistentEntitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, + QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); + DependencyManager::get()->runScriptInitializers(_persistentEntitiesScriptEngine); + _persistentEntitiesScriptEngine->runInThread(); + auto entitiesScriptEngineProvider = qSharedPointerCast(_persistentEntitiesScriptEngine); + auto entityScriptingInterface = DependencyManager::get(); + entityScriptingInterface->setPersistentEntitiesScriptEngine(entitiesScriptEngineProvider); + + setupEntityScriptEngineSignals(_persistentEntitiesScriptEngine); +} + +void EntityTreeRenderer::resetNonPersistentEntitiesScriptEngine() { + if (_nonPersistentEntitiesScriptEngine) { + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(false); + _nonPersistentEntitiesScriptEngine->stop(); + _nonPersistentEntitiesScriptEngine->waitTillDoneRunning(); + _nonPersistentEntitiesScriptEngine->disconnectNonEssentialSignals(); + } + _nonPersistentEntitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, + QString("about:Entities %1").arg(++_entitiesScriptEngineCount)); + DependencyManager::get()->runScriptInitializers(_nonPersistentEntitiesScriptEngine); + _nonPersistentEntitiesScriptEngine->runInThread(); + auto entitiesScriptEngineProvider = qSharedPointerCast(_nonPersistentEntitiesScriptEngine); + DependencyManager::get()->setNonPersistentEntitiesScriptEngine(entitiesScriptEngineProvider); + + setupEntityScriptEngineSignals(_nonPersistentEntitiesScriptEngine); } void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { leaveDomainAndNonOwnedEntities(); // unload and stop the engine - if (_entitiesScriptEngine) { - QList entitiesWithEntityScripts = _entitiesScriptEngine->getListOfEntityScriptIDs(); + if (_nonPersistentEntitiesScriptEngine) { + QList entitiesWithEntityScripts = _nonPersistentEntitiesScriptEngine->getListOfEntityScriptIDs(); - foreach (const EntityItemID& entityID, entitiesWithEntityScripts) { + foreach (const EntityItemID& entityID, entitiesWithEntityScripts) { EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); - if (entityItem && !entityItem->getScript().isEmpty()) { if (!(entityItem->isLocalEntity() || entityItem->isMyAvatarEntity())) { - if (_currentEntitiesInside.contains(entityID)) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); - } - _entitiesScriptEngine->unloadEntityScript(entityID, true); + _nonPersistentEntitiesScriptEngine->unloadEntityScript(entityID, true); } } } @@ -240,6 +259,10 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { stopDomainAndNonOwnedEntities(); + if (!_shuttingDown && _wantScripts) { + resetNonPersistentEntitiesScriptEngine(); + } + std::unordered_map savedEntities; std::unordered_set savedRenderables; // remove all entities from the scene @@ -269,16 +292,22 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { void EntityTreeRenderer::clear() { leaveAllEntities(); - // unload and stop the engine - if (_entitiesScriptEngine) { - // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread - _entitiesScriptEngine->unloadAllEntityScripts(true); - _entitiesScriptEngine->stop(); - } // reset the engine auto scene = _viewState->getMain3DScene(); if (_shuttingDown) { + // unload and stop the engines + if (_nonPersistentEntitiesScriptEngine) { + // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _nonPersistentEntitiesScriptEngine->stop(); + } + if (_persistentEntitiesScriptEngine) { + // do this here (instead of in deleter) to avoid marshalling unload signals back to this thread + _persistentEntitiesScriptEngine->unloadAllEntityScripts(true); + _persistentEntitiesScriptEngine->stop(); + } + if (scene) { render::Transaction transaction; for (const auto& entry : _entitiesInScene) { @@ -289,7 +318,8 @@ void EntityTreeRenderer::clear() { } } else { if (_wantScripts) { - resetEntitiesScriptEngine(); + resetPersistentEntitiesScriptEngine(); + resetNonPersistentEntitiesScriptEngine(); } if (scene) { for (const auto& entry : _entitiesInScene) { @@ -313,13 +343,17 @@ void EntityTreeRenderer::clear() { } void EntityTreeRenderer::reloadEntityScripts() { - _entitiesScriptEngine->unloadAllEntityScripts(); - _entitiesScriptEngine->resetModuleCache(); + _persistentEntitiesScriptEngine->unloadAllEntityScripts(); + _persistentEntitiesScriptEngine->resetModuleCache(); + _nonPersistentEntitiesScriptEngine->unloadAllEntityScripts(); + _nonPersistentEntitiesScriptEngine->resetModuleCache(); + for (const auto& entry : _entitiesInScene) { const auto& renderer = entry.second; const auto& entity = renderer->getEntity(); - if (!entity->getScript().isEmpty()) { - _entitiesScriptEngine->loadEntityScript(entity->getEntityItemID(), resolveScriptURL(entity->getScript()), true); + if (entity && !entity->getScript().isEmpty()) { + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->loadEntityScript(entity->getEntityItemID(), resolveScriptURL(entity->getScript()), true); } } } @@ -329,7 +363,8 @@ void EntityTreeRenderer::init() { EntityTreePointer entityTree = std::static_pointer_cast(_tree); if (_wantScripts) { - resetEntitiesScriptEngine(); + resetPersistentEntitiesScriptEngine(); + resetNonPersistentEntitiesScriptEngine(); } forceRecheckEntities(); // setup our state to force checking our inside/outsideness of entities @@ -341,8 +376,11 @@ void EntityTreeRenderer::init() { } void EntityTreeRenderer::shutdown() { - if (_entitiesScriptEngine) { - _entitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential + if (_persistentEntitiesScriptEngine) { + _persistentEntitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential + } + if (_nonPersistentEntitiesScriptEngine) { + _nonPersistentEntitiesScriptEngine->disconnectNonEssentialSignals(); // disconnect all slots/signals from the script engine, except essential } _shuttingDown = true; @@ -658,12 +696,16 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { // EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts // for entity IDs that no longer exist. - if (_entitiesScriptEngine) { + if (_persistentEntitiesScriptEngine && _nonPersistentEntitiesScriptEngine) { // for all of our previous containing entities, if they are no longer containing then send them a leave event foreach(const EntityItemID& entityID, _currentEntitiesInside) { if (!entitiesContainingAvatar.contains(entityID)) { emit leaveEntity(entityID); - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + auto entity = getTree()->findEntityByEntityItemID(entityID); + if (entity) { + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + } } } @@ -671,7 +713,11 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { foreach(const EntityItemID& entityID, entitiesContainingAvatar) { if (!_currentEntitiesInside.contains(entityID)) { emit enterEntity(entityID); - _entitiesScriptEngine->callEntityScriptMethod(entityID, "enterEntity"); + auto entity = getTree()->findEntityByEntityItemID(entityID); + if (entity) { + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + scriptEngine->callEntityScriptMethod(entityID, "enterEntity"); + } } } _currentEntitiesInside = entitiesContainingAvatar; @@ -687,8 +733,8 @@ void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() { EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); if (entityItem && !(entityItem->isLocalEntity() || entityItem->isMyAvatarEntity())) { emit leaveEntity(entityID); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + if (_nonPersistentEntitiesScriptEngine) { + _nonPersistentEntitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } } else { currentEntitiesInsideToSave.insert(entityID); @@ -706,8 +752,12 @@ void EntityTreeRenderer::leaveAllEntities() { // for all of our previous containing entities, if they are no longer containing then send them a leave event foreach(const EntityItemID& entityID, _currentEntitiesInside) { emit leaveEntity(entityID); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); + if (entityItem) { + auto& scriptEngine = (entityItem->isLocalEntity() || entityItem->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + } } } _currentEntitiesInside.clear(); @@ -1003,11 +1053,12 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { return; } - if (_tree && !_shuttingDown && _entitiesScriptEngine && !itr->second->getEntity()->getScript().isEmpty()) { + auto& scriptEngine = (itr->second->getEntity()->isLocalEntity() || itr->second->getEntity()->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (_tree && !_shuttingDown && scriptEngine && !itr->second->getEntity()->getScript().isEmpty()) { if (_currentEntitiesInside.contains(entityID)) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } - _entitiesScriptEngine->unloadEntityScript(entityID, true); + scriptEngine->unloadEntityScript(entityID, true); } auto scene = _viewState->getMain3DScene(); @@ -1052,20 +1103,21 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool if (!entity) { return; } - bool shouldLoad = entity->shouldPreloadScript() && _entitiesScriptEngine; + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + bool shouldLoad = entity->shouldPreloadScript() && scriptEngine; QString scriptUrl = entity->getScript(); if ((shouldLoad && unloadFirst) || scriptUrl.isEmpty()) { - if (_entitiesScriptEngine) { + if (scriptEngine) { if (_currentEntitiesInside.contains(entityID)) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); + scriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } - _entitiesScriptEngine->unloadEntityScript(entityID); + scriptEngine->unloadEntityScript(entityID); } entity->scriptHasUnloaded(); } if (shouldLoad) { entity->setScriptHasFinishedPreload(false); - _entitiesScriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload); + scriptEngine->loadEntityScript(entityID, resolveScriptURL(scriptUrl), reload); entity->scriptHasPreloaded(); } } @@ -1172,8 +1224,9 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons if ((myNodeID == entityASimulatorID && entityAIsDynamic) || (myNodeID == entityBSimulatorID && (!entityAIsDynamic || entityASimulatorID.isNull()))) { playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); + auto& scriptEngine = (entityA->isLocalEntity() || entityA->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); } } @@ -1183,8 +1236,9 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons Collision invertedCollision(collision); invertedCollision.invert(); emit collisionWithEntity(idB, idA, invertedCollision); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); + auto& scriptEngine = (entityB->isLocalEntity() || entityB->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, invertedCollision); } } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 149b23702f..f7623aad10 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -173,7 +173,9 @@ private: EntityRendererPointer renderableForEntity(const EntityItemPointer& entity) const { return renderableForEntityId(entity->getID()); } render::ItemID renderableIdForEntity(const EntityItemPointer& entity) const { return renderableIdForEntityId(entity->getID()); } - void resetEntitiesScriptEngine(); + void resetPersistentEntitiesScriptEngine(); + void resetNonPersistentEntitiesScriptEngine(); + void setupEntityScriptEngineSignals(const ScriptEnginePointer& scriptEngine); void findBestZoneAndMaybeContainingEntities(QSet& entitiesContainingAvatar); @@ -196,7 +198,8 @@ private: QSet _currentEntitiesInside; bool _wantScripts; - ScriptEnginePointer _entitiesScriptEngine; + ScriptEnginePointer _nonPersistentEntitiesScriptEngine; // used for domain + non-owned avatar entities, cleared on domain switch + ScriptEnginePointer _persistentEntitiesScriptEngine; // used for local + owned avatar entities, persists on domain switch, cleared on reload content void playEntityCollisionSound(const EntityItemPointer& entity, const Collision& collision); @@ -214,8 +217,6 @@ private: std::function _getPrevRayPickResultOperator; std::function _setPrecisionPickingOperator; - bool _mouseAndPreloadSignalHandlersConnected { false }; - class LayeredZone { public: LayeredZone(std::shared_ptr zone) : zone(zone), id(zone->getID()), volume(zone->getVolumeEstimate()) {} diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 05947551ba..36beb9f0d3 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1046,18 +1046,26 @@ QSizeF EntityScriptingInterface::textSize(const QUuid& id, const QString& text) return EntityTree::textSize(id, text); } -void EntityScriptingInterface::setEntitiesScriptEngine(QSharedPointer engine) { +void EntityScriptingInterface::setPersistentEntitiesScriptEngine(QSharedPointer engine) { std::lock_guard lock(_entitiesScriptEngineLock); - _entitiesScriptEngine = engine; + _persistentEntitiesScriptEngine = engine; +} + +void EntityScriptingInterface::setNonPersistentEntitiesScriptEngine(QSharedPointer engine) { + std::lock_guard lock(_entitiesScriptEngineLock); + _nonPersistentEntitiesScriptEngine = engine; } void EntityScriptingInterface::callEntityMethod(const QUuid& id, const QString& method, const QStringList& params) { PROFILE_RANGE(script_entities, __FUNCTION__); - - std::lock_guard lock(_entitiesScriptEngineLock); - if (_entitiesScriptEngine) { - EntityItemID entityID{ id }; - _entitiesScriptEngine->callEntityScriptMethod(entityID, method, params); + + auto entity = getEntityTree()->findEntityByEntityItemID(id); + if (entity) { + std::lock_guard lock(_entitiesScriptEngineLock); + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(id, method, params); + } } } @@ -1099,9 +1107,13 @@ void EntityScriptingInterface::handleEntityScriptCallMethodPacket(QSharedPointer params << paramString; } - std::lock_guard lock(_entitiesScriptEngineLock); - if (_entitiesScriptEngine) { - _entitiesScriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID()); + auto entity = getEntityTree()->findEntityByEntityItemID(entityID); + if (entity) { + std::lock_guard lock(_entitiesScriptEngineLock); + auto& scriptEngine = (entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine; + if (scriptEngine) { + scriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID()); + } } } } @@ -1332,7 +1344,7 @@ bool EntityPropertyMetadataRequest::script(EntityItemID entityID, QScriptValue h if (entitiesScriptEngine) { request->setFuture(entitiesScriptEngine->getLocalEntityScriptDetails(entityID)); } - }); + }, entityID); if (!request->isStarted()) { request->deleteLater(); callScopedHandlerObject(handler, _engine->makeError("Entities Scripting Provider unavailable", "InternalError"), QScriptValue()); diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index fca0dad871..14d853fbaf 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -181,7 +181,8 @@ public: void setEntityTree(EntityTreePointer modelTree); EntityTreePointer getEntityTree() { return _entityTree; } - void setEntitiesScriptEngine(QSharedPointer engine); + void setPersistentEntitiesScriptEngine(QSharedPointer engine); + void setNonPersistentEntitiesScriptEngine(QSharedPointer engine); void resetActivityTracking(); ActivityTracking getActivityTracking() const { return _activityTracking; } @@ -2510,9 +2511,12 @@ signals: void webEventReceived(const EntityItemID& entityItemID, const QVariant& message); protected: - void withEntitiesScriptEngine(std::function)> function) { - std::lock_guard lock(_entitiesScriptEngineLock); - function(_entitiesScriptEngine); + void withEntitiesScriptEngine(std::function)> function, const EntityItemID& id) { + auto entity = getEntityTree()->findEntityByEntityItemID(id); + if (entity) { + std::lock_guard lock(_entitiesScriptEngineLock); + function((entity->isLocalEntity() || entity->isMyAvatarEntity()) ? _persistentEntitiesScriptEngine : _nonPersistentEntitiesScriptEngine); + } }; private slots: @@ -2542,7 +2546,8 @@ private: EntityTreePointer _entityTree; std::recursive_mutex _entitiesScriptEngineLock; - QSharedPointer _entitiesScriptEngine; + QSharedPointer _persistentEntitiesScriptEngine; + QSharedPointer _nonPersistentEntitiesScriptEngine; bool _bidOnSimulationOwnership { false };