Add "project changed" event

And emit it whenever we think the project has changed. Try to not emit it when a change has happened internally that shouldn't affect the serialized project.

This iteration fires the event too frequently, e.g., when switching sprites. This is meant as a simple initial implementation that can be improved.
This commit is contained in:
Ray Schamp 2018-11-26 17:03:41 -05:00
parent e071cf3c0c
commit 5022227c15
3 changed files with 31 additions and 4 deletions

View file

@ -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();
}
// ---------------------------------------------------------------------

View file

@ -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.

View file

@ -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();
}
/**