Skip to content

Commit ed608ff

Browse files
committed
Refactor to fix issue with global var not checking for name conflicts on all sprites.
1 parent 92dfebd commit ed608ff

File tree

3 files changed

+35
-16
lines changed

3 files changed

+35
-16
lines changed

src/engine/blocks.js

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -330,19 +330,25 @@ class Blocks {
330330
this.deleteBlock(e.blockId);
331331
break;
332332
case 'var_create':
333-
// New variables being created by the user are all global.
334-
// Check if this variable exists on the current target or stage.
335-
// If not, create it on the appropriate target based on the event's
336-
// 'isLocal' flag.
337-
if (editingTarget) {
333+
// Check if the variable being created is global or local
334+
// If local, create a local var on the current editing target, as long
335+
// as there are no conflicts, and the current target is actually a sprite
336+
// If global or if the editing target is not present or we somehow got
337+
// into a state where a local var was requested for the stage,
338+
// create a stage (global) var after checking for name conflicts
339+
// on all the sprites.
340+
if (e.isLocal && editingTarget && !editingTarget.isStage) {
338341
if (!editingTarget.lookupVariableById(e.varId)) {
339-
const varTarget = e.isLocal ? editingTarget : stage;
340-
varTarget.createVariable(e.varId, e.varName, e.varType);
342+
editingTarget.createVariable(e.varId, e.varName, e.varType);
343+
}
344+
} else {
345+
// Check for name conflicts in all of the targets
346+
const allTargets = optRuntime.targets.filter(t => t.isOriginal);
347+
for (const target of allTargets) {
348+
if (target.lookupVariableByNameAndType(e.varName, e.varType, true)) {
349+
return;
350+
}
341351
}
342-
} else if (!stage.lookupVariableById(e.varId)) {
343-
// Since getEditingTarget returned null, we now need to
344-
// explicitly check if the stage has the variable, and
345-
// create one if not.
346352
stage.createVariable(e.varId, e.varName, e.varType);
347353
}
348354
break;

src/engine/runtime.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,15 @@ class Runtime extends EventEmitter {
17151715
return this._editingTarget;
17161716
}
17171717

1718+
getAllVarNamesOfType (varType) {
1719+
let varNames = [];
1720+
for (const target of this.targets) {
1721+
const targetVarNames = target.getAllVariableNamesInScopeByType(varType, true);
1722+
varNames = varNames.concat(targetVarNames);
1723+
}
1724+
return varNames;
1725+
}
1726+
17181727
/**
17191728
* Tell the runtime to request a redraw.
17201729
* Use after a clone/sprite has completed some visible operation on the stage.

src/engine/target.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,19 @@ class Target extends EventEmitter {
8383
/**
8484
* Get the names of all the variables of the given type that are in scope for this target.
8585
* For targets that are not the stage, this includes any target-specific
86-
* variables as well as any stage variables.
86+
* variables as well as any stage variables unless the skipStage flag is true.
8787
* For the stage, this is all stage variables.
8888
* @param {string} type The variable type to search for; defaults to Variable.SCALAR_TYPE
89+
* @param {?bool} skipStage Optional flag to skip the stage.
8990
* @return {Array<string>} A list of variable names
9091
*/
91-
getAllVariableNamesInScopeByType (type) {
92+
getAllVariableNamesInScopeByType (type, skipStage) {
9293
if (typeof type !== 'string') type = Variable.SCALAR_TYPE;
94+
skipStage = skipStage || false;
9395
const targetVariables = Object.values(this.variables)
9496
.filter(v => v.type === type)
9597
.map(variable => variable.name);
96-
if (this.isStage || !this.runtime) {
98+
if (skipStage || this.isStage || !this.runtime) {
9799
return targetVariables;
98100
}
99101
const stage = this.runtime.getTargetForStage();
@@ -194,11 +196,13 @@ class Target extends EventEmitter {
194196
* was not found.
195197
* @param {string} name Name of the variable.
196198
* @param {string} type Type of the variable. Defaults to Variable.SCALAR_TYPE.
199+
* @param {?bool} skipStage Optional flag to skip checking the stage
197200
* @return {?Variable} Variable object if found, or null if not.
198201
*/
199-
lookupVariableByNameAndType (name, type) {
202+
lookupVariableByNameAndType (name, type, skipStage) {
200203
if (typeof name !== 'string') return;
201204
if (typeof type !== 'string') type = Variable.SCALAR_TYPE;
205+
skipStage = skipStage || false;
202206

203207
for (const varId in this.variables) {
204208
const currVar = this.variables[varId];
@@ -207,7 +211,7 @@ class Target extends EventEmitter {
207211
}
208212
}
209213

210-
if (this.runtime && !this.isStage) {
214+
if (!skipStage && this.runtime && !this.isStage) {
211215
const stage = this.runtime.getTargetForStage();
212216
if (stage) {
213217
for (const varId in stage.variables) {

0 commit comments

Comments
 (0)