Refactor to fix issue with global var not checking for name conflicts on all sprites.

This commit is contained in:
Karishma Chadha 2018-07-03 23:20:49 -04:00
parent 92dfebdae6
commit ed608ffe6f
3 changed files with 35 additions and 16 deletions

View file

@ -330,19 +330,25 @@ class Blocks {
this.deleteBlock(e.blockId); this.deleteBlock(e.blockId);
break; break;
case 'var_create': case 'var_create':
// New variables being created by the user are all global. // Check if the variable being created is global or local
// Check if this variable exists on the current target or stage. // If local, create a local var on the current editing target, as long
// If not, create it on the appropriate target based on the event's // as there are no conflicts, and the current target is actually a sprite
// 'isLocal' flag. // If global or if the editing target is not present or we somehow got
if (editingTarget) { // into a state where a local var was requested for the stage,
// create a stage (global) var after checking for name conflicts
// on all the sprites.
if (e.isLocal && editingTarget && !editingTarget.isStage) {
if (!editingTarget.lookupVariableById(e.varId)) { if (!editingTarget.lookupVariableById(e.varId)) {
const varTarget = e.isLocal ? editingTarget : stage; editingTarget.createVariable(e.varId, e.varName, e.varType);
varTarget.createVariable(e.varId, e.varName, e.varType); }
} else {
// Check for name conflicts in all of the targets
const allTargets = optRuntime.targets.filter(t => t.isOriginal);
for (const target of allTargets) {
if (target.lookupVariableByNameAndType(e.varName, e.varType, true)) {
return;
}
} }
} else if (!stage.lookupVariableById(e.varId)) {
// Since getEditingTarget returned null, we now need to
// explicitly check if the stage has the variable, and
// create one if not.
stage.createVariable(e.varId, e.varName, e.varType); stage.createVariable(e.varId, e.varName, e.varType);
} }
break; break;

View file

@ -1715,6 +1715,15 @@ class Runtime extends EventEmitter {
return this._editingTarget; return this._editingTarget;
} }
getAllVarNamesOfType (varType) {
let varNames = [];
for (const target of this.targets) {
const targetVarNames = target.getAllVariableNamesInScopeByType(varType, true);
varNames = varNames.concat(targetVarNames);
}
return varNames;
}
/** /**
* Tell the runtime to request a redraw. * Tell the runtime to request a redraw.
* Use after a clone/sprite has completed some visible operation on the stage. * Use after a clone/sprite has completed some visible operation on the stage.

View file

@ -83,17 +83,19 @@ class Target extends EventEmitter {
/** /**
* Get the names of all the variables of the given type that are in scope for this target. * Get the names of all the variables of the given type that are in scope for this target.
* For targets that are not the stage, this includes any target-specific * For targets that are not the stage, this includes any target-specific
* variables as well as any stage variables. * variables as well as any stage variables unless the skipStage flag is true.
* For the stage, this is all stage variables. * For the stage, this is all stage variables.
* @param {string} type The variable type to search for; defaults to Variable.SCALAR_TYPE * @param {string} type The variable type to search for; defaults to Variable.SCALAR_TYPE
* @param {?bool} skipStage Optional flag to skip the stage.
* @return {Array<string>} A list of variable names * @return {Array<string>} A list of variable names
*/ */
getAllVariableNamesInScopeByType (type) { getAllVariableNamesInScopeByType (type, skipStage) {
if (typeof type !== 'string') type = Variable.SCALAR_TYPE; if (typeof type !== 'string') type = Variable.SCALAR_TYPE;
skipStage = skipStage || false;
const targetVariables = Object.values(this.variables) const targetVariables = Object.values(this.variables)
.filter(v => v.type === type) .filter(v => v.type === type)
.map(variable => variable.name); .map(variable => variable.name);
if (this.isStage || !this.runtime) { if (skipStage || this.isStage || !this.runtime) {
return targetVariables; return targetVariables;
} }
const stage = this.runtime.getTargetForStage(); const stage = this.runtime.getTargetForStage();
@ -194,11 +196,13 @@ class Target extends EventEmitter {
* was not found. * was not found.
* @param {string} name Name of the variable. * @param {string} name Name of the variable.
* @param {string} type Type of the variable. Defaults to Variable.SCALAR_TYPE. * @param {string} type Type of the variable. Defaults to Variable.SCALAR_TYPE.
* @param {?bool} skipStage Optional flag to skip checking the stage
* @return {?Variable} Variable object if found, or null if not. * @return {?Variable} Variable object if found, or null if not.
*/ */
lookupVariableByNameAndType (name, type) { lookupVariableByNameAndType (name, type, skipStage) {
if (typeof name !== 'string') return; if (typeof name !== 'string') return;
if (typeof type !== 'string') type = Variable.SCALAR_TYPE; if (typeof type !== 'string') type = Variable.SCALAR_TYPE;
skipStage = skipStage || false;
for (const varId in this.variables) { for (const varId in this.variables) {
const currVar = this.variables[varId]; const currVar = this.variables[varId];
@ -207,7 +211,7 @@ class Target extends EventEmitter {
} }
} }
if (this.runtime && !this.isStage) { if (!skipStage && this.runtime && !this.isStage) {
const stage = this.runtime.getTargetForStage(); const stage = this.runtime.getTargetForStage();
if (stage) { if (stage) {
for (const varId in stage.variables) { for (const varId in stage.variables) {