diff --git a/src/engine/target.js b/src/engine/target.js index 223254221..5e4d2e08a 100644 --- a/src/engine/target.js +++ b/src/engine/target.js @@ -154,7 +154,7 @@ class Target extends EventEmitter { // If the stage has a global copy, return it. if (this.runtime && !this.isStage) { const stage = this.runtime.getTargetForStage(); - if (stage.variables.hasOwnProperty(id)) { + if (stage && stage.variables.hasOwnProperty(id)) { return stage.variables[id]; } } diff --git a/src/virtual-machine.js b/src/virtual-machine.js index ca6d8d173..1c9c2883d 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -1071,6 +1071,42 @@ class VirtualMachine extends EventEmitter { this.editingTarget.postSpriteInfo(data); } } + + /** + * Set a target's variable's value. Return whether it succeeded. + * @param {!string} targetId ID of the target which owns the variable. + * @param {!string} variableId ID of the variable to set. + * @param {!*} value The new value of that variable. + * @returns {boolean} whether the target and variable were found and updated. + */ + setVariableValue (targetId, variableId, value) { + const target = this.runtime.getTargetById(targetId); + if (target) { + const variable = target.lookupVariableById(variableId); + if (variable) { + variable.value = value; + return true; + } + } + return false; + } + + /** + * Get a target's variable's value. Return null if the target or variable does not exist. + * @param {!string} targetId ID of the target which owns the variable. + * @param {!string} variableId ID of the variable to set. + * @returns {?*} The value of the variable, or null if it could not be looked up. + */ + getVariableValue (targetId, variableId) { + const target = this.runtime.getTargetById(targetId); + if (target) { + const variable = target.lookupVariableById(variableId); + if (variable) { + return variable.value; + } + } + return null; + } } module.exports = VirtualMachine; diff --git a/test/unit/virtual-machine.js b/test/unit/virtual-machine.js index 70d06fee3..f86267ae8 100644 --- a/test/unit/virtual-machine.js +++ b/test/unit/virtual-machine.js @@ -1,6 +1,7 @@ const test = require('tap').test; const VirtualMachine = require('../../src/virtual-machine.js'); const Sprite = require('../../src/sprites/sprite.js'); +const Variable = require('../../src/engine/variable.js'); test('addSprite throws on invalid string', t => { const vm = new VirtualMachine(); @@ -452,3 +453,46 @@ test('select original after dragging clone', t => { t.equal(newEditingTargetId, 'sprite1_original'); t.end(); }); + +test('setVariableValue', t => { + const vm = new VirtualMachine(); + const spr = new Sprite(null, vm.runtime); + const target = spr.createClone(); + target.createVariable('a-variable', 'a-name', Variable.SCALAR_TYPE); + + vm.runtime.targets = [target]; + + // Returns false if there is no variable to set + t.equal(vm.setVariableValue(target.id, 'not-a-variable', 100), false); + + // Returns false if there is no target with that id + t.equal(vm.setVariableValue('not-a-target', 'a-variable', 100), false); + + // Returns true and updates the value if variable is present + t.equal(vm.setVariableValue(target.id, 'a-variable', 100), true); + t.equal(target.lookupVariableById('a-variable').value, 100); + + t.end(); +}); + +test('getVariableValue', t => { + const vm = new VirtualMachine(); + const spr = new Sprite(null, vm.runtime); + const target = spr.createClone(); + target.createVariable('a-variable', 'a-name', Variable.SCALAR_TYPE); + + vm.runtime.targets = [target]; + + // Returns null if there is no variable with that id + t.equal(vm.getVariableValue(target.id, 'not-a-variable'), null); + + // Returns null if there is no variable with that id + t.equal(vm.getVariableValue('not-a-target', 'a-variable'), null); + + // Returns true and updates the value if variable is present + t.equal(vm.getVariableValue(target.id, 'a-variable'), 0); + vm.setVariableValue(target.id, 'a-variable', 'string'); + t.equal(vm.getVariableValue(target.id, 'a-variable'), 'string'); + + t.end(); +});