From 3f3c34b43a9fcbc5b35166d35d39ce7294e3e2e6 Mon Sep 17 00:00:00 2001
From: picklesrus <picklesrus@users.noreply.github.com>
Date: Thu, 6 Dec 2018 18:59:58 -0500
Subject: [PATCH] Given the bug found with the old approach, fix this by going
 and deleting all of the monitor blocks for each sprite and the global
 variables.

---
 src/engine/runtime.js  |  7 ++++++-
 src/engine/target.js   | 20 ++++++++++++++++++++
 src/virtual-machine.js |  7 +------
 3 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/engine/runtime.js b/src/engine/runtime.js
index 945f5294d..3eb58f1e5 100644
--- a/src/engine/runtime.js
+++ b/src/engine/runtime.js
@@ -1541,13 +1541,18 @@ class Runtime extends EventEmitter {
         return newThreads;
     }
 
+
     /**
      * Dispose all targets. Return to clean state.
      */
     dispose () {
         this.stopAll();
+        // Deleting each target's variable's monitors.
+        this.targets.forEach(target => {
+            if (target.isOriginal) target.deleteMonitors();
+        });
+
         this.targets.map(this.disposeTarget, this);
-        this.monitorBlocks = new Blocks(true);
         this._monitorState = OrderedMap({});
         // @todo clear out extensions? turboMode? etc.
 
diff --git a/src/engine/target.js b/src/engine/target.js
index 312f1319e..251c381cb 100644
--- a/src/engine/target.js
+++ b/src/engine/target.js
@@ -336,6 +336,26 @@ class Target extends EventEmitter {
         }
     }
 
+    /**
+     * Remove this target's monitors from the runtime state and remove the
+     * target-specific monitored blocks (e.g. local variables, global variables for the stage, x-position).
+     * NOTE: This does not delete any of the stage monitors like backdrop name.
+     */
+    deleteMonitors () {
+        this.runtime.requestRemoveMonitorByTargetId(this.id);
+        let targetSpecificMonitorBlockIds;
+        if (this.isStage) {
+            // This only deletes global variables and not other stage monitors like backdrop number.
+            targetSpecificMonitorBlockIds = Object.keys(this.variables);
+        } else {
+            targetSpecificMonitorBlockIds = Object.keys(this.runtime.monitorBlocks._blocks)
+                .filter(key => this.runtime.monitorBlocks._blocks[key].targetId === this.id);
+        }
+        for (const blockId of targetSpecificMonitorBlockIds) {
+            this.runtime.monitorBlocks.deleteBlock(blockId);
+        }
+    }
+
     /**
      * Create a clone of the variable with the given id from the dictionary of
      * this target's variables.
diff --git a/src/virtual-machine.js b/src/virtual-machine.js
index e25f757a1..cae5219b1 100644
--- a/src/virtual-machine.js
+++ b/src/virtual-machine.js
@@ -936,12 +936,7 @@ class VirtualMachine extends EventEmitter {
             const restoreSprite = () => spritePromise.then(spriteBuffer => this.addSprite(spriteBuffer));
             // Remove monitors from the runtime state and remove the
             // target-specific monitored blocks (e.g. local variables)
-            this.runtime.requestRemoveMonitorByTargetId(targetId);
-            const targetSpecificMonitorBlockIds = Object.keys(this.runtime.monitorBlocks._blocks)
-                .filter(key => this.runtime.monitorBlocks._blocks[key].targetId === targetId);
-            for (const blockId of targetSpecificMonitorBlockIds) {
-                this.runtime.monitorBlocks.deleteBlock(blockId);
-            }
+            target.deleteMonitors();
             const currentEditingTarget = this.editingTarget;
             for (let i = 0; i < sprite.clones.length; i++) {
                 const clone = sprite.clones[i];