diff --git a/.gitignore b/.gitignore index 753e3f651..aad54ff5e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ npm-* /dist.js /vm.js /vm.min.js +/playground/assets /playground/media /playground/vendor.js /playground/vm.js diff --git a/src/blocks/scratch3_control.js b/src/blocks/scratch3_control.js index efa0c2fb6..a2bab50e1 100644 --- a/src/blocks/scratch3_control.js +++ b/src/blocks/scratch3_control.js @@ -167,6 +167,7 @@ Scratch3ControlBlocks.prototype.createClone = function (args, util) { }; Scratch3ControlBlocks.prototype.deleteClone = function (args, util) { + if (util.target.isOriginal) return; this.runtime.disposeTarget(util.target); this.runtime.stopForTarget(util.target); }; diff --git a/src/engine/runtime.js b/src/engine/runtime.js index 4a101147d..ea47a3ba9 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -369,17 +369,25 @@ Runtime.prototype.startHats = function (requestedHatOpcode, }; /** - * Dispose of a target. - * @param {!Target} target Target to dispose of. + * Dispose all targets. Return to clean state. */ -Runtime.prototype.disposeTarget = function (target) { - // Allow target to do dispose actions. - target.dispose(); - // Remove from list of targets. - var index = this.targets.indexOf(target); - if (index > -1) { - this.targets.splice(index, 1); - } +Runtime.prototype.dispose = function () { + this.stopAll(); + this.targets.map(this.disposeTarget, this); +}; + +/** + * Dispose of a target. + * @param {!Target} disposingTarget Target to dispose of. + */ +Runtime.prototype.disposeTarget = function (disposingTarget) { + this.targets = this.targets.filter(function (target) { + if (disposingTarget !== target) return true; + // Allow target to do dispose actions. + target.dispose(); + // Remove from list of targets. + return false; + }); }; /** diff --git a/src/index.js b/src/index.js index 469e3fec0..818ea4f1a 100644 --- a/src/index.js +++ b/src/index.js @@ -73,6 +73,15 @@ VirtualMachine.prototype.stopAll = function () { this.runtime.stopAll(); }; +/** + * Clear out current running project data. + */ +VirtualMachine.prototype.clear = function () { + this.runtime.dispose(); + this.editingTarget = null; + this.emitTargetsUpdate(); +}; + /** * Get data for playground. Data comes back in an emitted event. */ @@ -116,6 +125,7 @@ VirtualMachine.prototype.postIOData = function (device, data) { * @param {?string} json JSON string representing the project. */ VirtualMachine.prototype.loadProject = function (json) { + this.clear(); // @todo: Handle other formats, e.g., Scratch 1.4, Scratch 3.0. sb2import(json, this.runtime); // Select the first target for editing, e.g., the stage. @@ -237,7 +247,7 @@ VirtualMachine.prototype.emitTargetsUpdate = function () { return [target.id, target.getName()]; }), // Currently editing target id. - editingTarget: this.editingTarget.id + editingTarget: this.editingTarget ? this.editingTarget.id : null }); }; diff --git a/src/sprites/clone.js b/src/sprites/clone.js index 4d7c3672c..f63bbfe09 100644 --- a/src/sprites/clone.js +++ b/src/sprites/clone.js @@ -418,9 +418,6 @@ Clone.prototype.onGreenFlag = function () { * Dispose of this clone, destroying any run-time properties. */ Clone.prototype.dispose = function () { - if (this.isOriginal) { // Don't allow a non-clone to delete itself. - return; - } this.runtime.changeCloneCounter(-1); if (this.renderer && this.drawableID !== null) { this.renderer.destroyDrawable(this.drawableID);