diff --git a/src/engine/blocks.js b/src/engine/blocks.js index b89a41b5d..f2d792d6b 100644 --- a/src/engine/blocks.js +++ b/src/engine/blocks.js @@ -487,6 +487,10 @@ class Blocks { } break; } + + // forceNoGlow is set to true on containers that don't affect the project serialization, + // e.g., the toolbox or monitor containers. + if (optRuntime && !this.forceNoGlow) optRuntime.emitProjectChanged(); } // --------------------------------------------------------------------- diff --git a/src/engine/runtime.js b/src/engine/runtime.js index e16ac5411..fa9c366bd 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -501,6 +501,14 @@ class Runtime extends EventEmitter { return 'PROJECT_LOADED'; } + /** + * Event name for report that a change was made that can be saved + * @const {string} + */ + static get PROJECT_CHANGED () { + return 'PROJECT_CHANGED'; + } + /** * Event name for targets update report. * @const {string} @@ -1737,7 +1745,6 @@ class Runtime extends EventEmitter { // Script glows must be cleared. this._scriptGlowsPreviousFrame = []; this._updateGlows(); - this.requestTargetsUpdate(editingTarget); } /** @@ -2035,6 +2042,13 @@ class Runtime extends EventEmitter { this.emit(Runtime.PROJECT_LOADED); } + /** + * Report that the project has changed in a way that would affect serialization + */ + emitProjectChanged () { + this.emit(Runtime.PROJECT_CHANGED); + } + /** * Report that a new target has been created, possibly by cloning an existing target. * @param {Target} newTarget - the newly created target. diff --git a/src/virtual-machine.js b/src/virtual-machine.js index 6f15c43d1..b829664a2 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -84,6 +84,9 @@ class VirtualMachine extends EventEmitter { this.runtime.on(Runtime.PROJECT_RUN_STOP, () => { this.emit(Runtime.PROJECT_RUN_STOP); }); + this.runtime.on(Runtime.PROJECT_CHANGED, () => { + this.emit(Runtime.PROJECT_CHANGED); + }); this.runtime.on(Runtime.VISUAL_REPORT, visualReport => { this.emit(Runtime.VISUAL_REPORT, visualReport); }); @@ -476,7 +479,7 @@ class VirtualMachine extends EventEmitter { } // Update the VM user's knowledge of targets and blocks on the workspace. - this.emitTargetsUpdate(); + this.emitTargetsUpdate(false /* Don't emit project change */); this.emitWorkspaceUpdate(); this.runtime.setEditingTarget(this.editingTarget); this.runtime.ioDevices.cloud.setStage(this.runtime.getTargetForStage()); @@ -1105,7 +1108,7 @@ class VirtualMachine extends EventEmitter { if (target) { this.editingTarget = target; // Emit appropriate UI updates. - this.emitTargetsUpdate(); + this.emitTargetsUpdate(false /* Don't emit project change */); this.emitWorkspaceUpdate(); this.runtime.setEditingTarget(target); } @@ -1199,6 +1202,7 @@ class VirtualMachine extends EventEmitter { if (this.editingTarget) { this.emitWorkspaceUpdate(); this.runtime.setEditingTarget(this.editingTarget); + this.emitTargetsUpdate(false /* Don't emit project change */); } } @@ -1206,8 +1210,12 @@ class VirtualMachine extends EventEmitter { * Emit metadata about available targets. * An editor UI could use this to display a list of targets and show * the currently editing one. + * @param {bool} triggerProjectChange If true, also emit a project changed event. + * Disabled selectively by updates that don't affect project serialization. + * Defaults to true. */ - emitTargetsUpdate () { + emitTargetsUpdate (triggerProjectChange) { + if (typeof triggerProjectChange === 'undefined') triggerProjectChange = true; this.emit('targetsUpdate', { // [[target id, human readable target name], ...]. targetList: this.runtime.targets @@ -1220,6 +1228,7 @@ class VirtualMachine extends EventEmitter { // Currently editing target id. editingTarget: this.editingTarget ? this.editingTarget.id : null }); + if (triggerProjectChange) this.runtime.emitProjectChanged(); } /**