var Cast = require('../util/cast'); var Scratch3DataBlocks = function (runtime) { /** * The runtime instantiating this block package. * @type {Runtime} */ this.runtime = runtime; }; /** * Retrieve the block primitives implemented by this package. * @return {Object.} Mapping of opcode to Function. */ Scratch3DataBlocks.prototype.getPrimitives = function () { return { 'data_variable': this.getVariable, 'data_setvariableto': this.setVariableTo, 'data_changevariableby': this.changeVariableBy, 'data_listcontents': this.getListContents, 'data_addtolist': this.addToList, 'data_deleteoflist': this.deleteOfList, 'data_insertatlist': this.insertAtList, 'data_replaceitemoflist': this.replaceItemOfList, 'data_itemoflist': this.getItemOfList, 'data_lengthoflist': this.lengthOfList, 'data_listcontainsitem': this.listContainsItem }; }; Scratch3DataBlocks.prototype.getVariable = function (args, util) { var variable = util.target.lookupOrCreateVariable(args.VARIABLE); return variable.value; }; Scratch3DataBlocks.prototype.setVariableTo = function (args, util) { var variable = util.target.lookupOrCreateVariable(args.VARIABLE); variable.value = args.VALUE; }; Scratch3DataBlocks.prototype.changeVariableBy = function (args, util) { var variable = util.target.lookupOrCreateVariable(args.VARIABLE); var castedValue = Cast.toNumber(variable.value); var dValue = Cast.toNumber(args.VALUE); variable.value = castedValue + dValue; }; Scratch3DataBlocks.prototype.getListContents = function (args, util) { var list = util.target.lookupOrCreateList(args.LIST); // Determine if the list is all single letters. // If it is, report contents joined together with no separator. // If it's not, report contents joined together with a space. var allSingleLetters = true; for (var i = 0; i < list.contents.length; i++) { var listItem = list.contents[i]; if (!((typeof listItem === 'string') && (listItem.length === 1))) { allSingleLetters = false; break; } } if (allSingleLetters) { return list.contents.join(''); } else { return list.contents.join(' '); } }; Scratch3DataBlocks.prototype.addToList = function (args, util) { var list = util.target.lookupOrCreateList(args.LIST); list.contents.push(args.ITEM); }; Scratch3DataBlocks.prototype.deleteOfList = function (args, util) { var list = util.target.lookupOrCreateList(args.LIST); var index = Cast.toListIndex(args.INDEX, list.contents.length); if (index === Cast.LIST_INVALID) { return; } else if (index === Cast.LIST_ALL) { list.contents = []; return; } list.contents.splice(index - 1, 1); }; Scratch3DataBlocks.prototype.insertAtList = function (args, util) { var item = args.ITEM; var list = util.target.lookupOrCreateList(args.LIST); var index = Cast.toListIndex(args.INDEX, list.contents.length + 1); if (index === Cast.LIST_INVALID) { return; } list.contents.splice(index - 1, 0, item); }; Scratch3DataBlocks.prototype.replaceItemOfList = function (args, util) { var item = args.ITEM; var list = util.target.lookupOrCreateList(args.LIST); var index = Cast.toListIndex(args.INDEX, list.contents.length); if (index === Cast.LIST_INVALID) { return; } list.contents.splice(index - 1, 1, item); }; Scratch3DataBlocks.prototype.getItemOfList = function (args, util) { var list = util.target.lookupOrCreateList(args.LIST); var index = Cast.toListIndex(args.INDEX, list.contents.length); if (index === Cast.LIST_INVALID) { return ''; } return list.contents[index - 1]; }; Scratch3DataBlocks.prototype.lengthOfList = function (args, util) { var list = util.target.lookupOrCreateList(args.LIST); return list.contents.length; }; Scratch3DataBlocks.prototype.listContainsItem = function (args, util) { var item = args.ITEM; var list = util.target.lookupOrCreateList(args.LIST); if (list.contents.indexOf(item) >= 0) { return true; } // Try using Scratch comparison operator on each item. // (Scratch considers the string '123' equal to the number 123). for (var i = 0; i < list.contents.length; i++) { if (Cast.compare(list.contents[i], item) === 0) { return true; } } return false; }; module.exports = Scratch3DataBlocks;