From 092424569d04c72f0092b8398e67ac1801934cf3 Mon Sep 17 00:00:00 2001
From: RebeccaStankus <Rebecca@highfidelity.io>
Date: Tue, 8 Oct 2019 11:55:14 -0700
Subject: [PATCH 1/2] Added flag to ensure mouse event signals are not
 connected twice

---
 .../src/EntityTreeRenderer.cpp                | 82 ++++++++++---------
 .../controllers/controllerDispatcher.js       |  4 +
 2 files changed, 48 insertions(+), 38 deletions(-)

diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
index 52738bb6cd..94a5ca76f7 100644
--- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp
+++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
@@ -157,6 +157,7 @@ render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& i
 }
 
 int EntityTreeRenderer::_entitiesScriptEngineCount = 0;
+bool _signalsConnected = false;
 
 void EntityTreeRenderer::resetEntitiesScriptEngine() {
     _entitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT,
@@ -168,47 +169,52 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() {
     entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider);
 
     // Connect mouse events to entity script callbacks
-    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);
-    });
+    if (!_signalsConnected) {
+    
+        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::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);
-    });
+        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);
+        });
 
-    connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) {
-        EntityItemPointer entity = getTree()->findEntityByID(entityID);
-        if (entity) {
-            entity->setScriptHasFinishedPreload(true);
-        }
-    });
+        connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptPreloadFinished, [&](const EntityItemID& entityID) {
+            EntityItemPointer entity = getTree()->findEntityByID(entityID);
+            if (entity) {
+                entity->setScriptHasFinishedPreload(true);
+            }
+        });
+
+        _signalsConnected = true;
+    }
 }
 
 void EntityTreeRenderer::stopDomainAndNonOwnedEntities() {
diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js
index cf365a4119..f0d3ec0c03 100644
--- a/scripts/system/controllers/controllerDispatcher.js
+++ b/scripts/system/controllers/controllerDispatcher.js
@@ -595,6 +595,10 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
             Controller.disableMapping(MAPPING_NAME);
             _this.pointerManager.removePointers();
             Pointers.removePointer(this.mouseRayPointer);
+            Overlays.mouseReleaseOnOverlay.disconnect(mouseReleaseOnOverlay);
+            Overlays.mousePressOnOverlay.disconnect(mousePress);
+            Entities.mousePressOnEntity.disconnect(mousePress);
+            Messages.messageReceived.disconnect(controllerDispatcher.handleMessage);
         };
     }
 

From 458d3bfb4864f8c7657173f51b78e8288fb02237 Mon Sep 17 00:00:00 2001
From: RebeccaStankus <Rebecca@highfidelity.io>
Date: Tue, 8 Oct 2019 13:15:27 -0700
Subject: [PATCH 2/2] Renamed variable and made it private

---
 libraries/entities-renderer/src/EntityTreeRenderer.cpp | 5 ++---
 libraries/entities-renderer/src/EntityTreeRenderer.h   | 2 ++
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
index 94a5ca76f7..ab3f4c5243 100644
--- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp
+++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
@@ -157,7 +157,6 @@ render::ItemID EntityTreeRenderer::renderableIdForEntityId(const EntityItemID& i
 }
 
 int EntityTreeRenderer::_entitiesScriptEngineCount = 0;
-bool _signalsConnected = false;
 
 void EntityTreeRenderer::resetEntitiesScriptEngine() {
     _entitiesScriptEngine = scriptEngineFactory(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT,
@@ -169,7 +168,7 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() {
     entityScriptingInterface->setEntitiesScriptEngine(entitiesScriptEngineProvider);
 
     // Connect mouse events to entity script callbacks
-    if (!_signalsConnected) {
+    if (!_mouseAndPreloadSignalHandlersConnected) {
     
         connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, _entitiesScriptEngine.data(), [&](const EntityItemID& entityID, const PointerEvent& event) {
             _entitiesScriptEngine->callEntityScriptMethod(entityID, "mousePressOnEntity", event);
@@ -213,7 +212,7 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() {
             }
         });
 
-        _signalsConnected = true;
+        _mouseAndPreloadSignalHandlersConnected = true;
     }
 }
 
diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h
index b9fda690dd..6dbaedc123 100644
--- a/libraries/entities-renderer/src/EntityTreeRenderer.h
+++ b/libraries/entities-renderer/src/EntityTreeRenderer.h
@@ -210,6 +210,8 @@ private:
     std::function<RayToEntityIntersectionResult(unsigned int)> _getPrevRayPickResultOperator;
     std::function<void(unsigned int, bool)> _setPrecisionPickingOperator;
 
+    bool _mouseAndPreloadSignalHandlersConnected { false };
+
     class LayeredZone {
     public:
         LayeredZone(std::shared_ptr<ZoneEntityItem> zone) : zone(zone), id(zone->getID()), volume(zone->getVolumeEstimate()) {}