mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-08-20 18:29:57 -04:00
Pass with --fix
This commit is contained in:
parent
f646a61c5b
commit
e01c4ae108
41 changed files with 803 additions and 824 deletions
src
blocks
scratch3_control.jsscratch3_data.jsscratch3_event.jsscratch3_looks.jsscratch3_motion.jsscratch3_operators.jsscratch3_pen.jsscratch3_procedures.jsscratch3_sensing.jsscratch3_sound.js
engine
adapter.jsblocks.jsexecute.jslist.jsmutation-adapter.jsruntime.jssequencer.jstarget.jsthread.jsvariable.js
import
index.jsio
playground
sprites
util
virtual-machine.js
|
@ -1,7 +1,7 @@
|
|||
var Cast = require('../util/cast');
|
||||
var Timer = require('../util/timer');
|
||||
const Cast = require('../util/cast');
|
||||
const Timer = require('../util/timer');
|
||||
|
||||
var Scratch3ControlBlocks = function (runtime) {
|
||||
const Scratch3ControlBlocks = function (runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
|
@ -37,7 +37,7 @@ Scratch3ControlBlocks.prototype.getHats = function () {
|
|||
};
|
||||
|
||||
Scratch3ControlBlocks.prototype.repeat = function (args, util) {
|
||||
var times = Math.floor(Cast.toNumber(args.TIMES));
|
||||
const times = Math.floor(Cast.toNumber(args.TIMES));
|
||||
// Initialize loop
|
||||
if (typeof util.stackFrame.loopCounter === 'undefined') {
|
||||
util.stackFrame.loopCounter = times;
|
||||
|
@ -54,7 +54,7 @@ Scratch3ControlBlocks.prototype.repeat = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3ControlBlocks.prototype.repeatUntil = function (args, util) {
|
||||
var condition = Cast.toBoolean(args.CONDITION);
|
||||
const condition = Cast.toBoolean(args.CONDITION);
|
||||
// If the condition is true, start the branch.
|
||||
if (!condition) {
|
||||
util.startBranch(1, true);
|
||||
|
@ -62,7 +62,7 @@ Scratch3ControlBlocks.prototype.repeatUntil = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3ControlBlocks.prototype.waitUntil = function (args, util) {
|
||||
var condition = Cast.toBoolean(args.CONDITION);
|
||||
const condition = Cast.toBoolean(args.CONDITION);
|
||||
if (!condition) {
|
||||
util.yield();
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ Scratch3ControlBlocks.prototype.wait = function (args, util) {
|
|||
util.yield();
|
||||
this.runtime.requestRedraw();
|
||||
} else {
|
||||
var duration = Math.max(0, 1000 * Cast.toNumber(args.DURATION));
|
||||
const duration = Math.max(0, 1000 * Cast.toNumber(args.DURATION));
|
||||
if (util.stackFrame.timer.timeElapsed() < duration) {
|
||||
util.yield();
|
||||
}
|
||||
|
@ -87,14 +87,14 @@ Scratch3ControlBlocks.prototype.wait = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3ControlBlocks.prototype.if = function (args, util) {
|
||||
var condition = Cast.toBoolean(args.CONDITION);
|
||||
const condition = Cast.toBoolean(args.CONDITION);
|
||||
if (condition) {
|
||||
util.startBranch(1, false);
|
||||
}
|
||||
};
|
||||
|
||||
Scratch3ControlBlocks.prototype.ifElse = function (args, util) {
|
||||
var condition = Cast.toBoolean(args.CONDITION);
|
||||
const condition = Cast.toBoolean(args.CONDITION);
|
||||
if (condition) {
|
||||
util.startBranch(1, false);
|
||||
} else {
|
||||
|
@ -103,7 +103,7 @@ Scratch3ControlBlocks.prototype.ifElse = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3ControlBlocks.prototype.stop = function (args, util) {
|
||||
var option = args.STOP_OPTION;
|
||||
const option = args.STOP_OPTION;
|
||||
if (option === 'all') {
|
||||
util.stopAll();
|
||||
} else if (option === 'other scripts in sprite' ||
|
||||
|
@ -115,7 +115,7 @@ Scratch3ControlBlocks.prototype.stop = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3ControlBlocks.prototype.createClone = function (args, util) {
|
||||
var cloneTarget;
|
||||
let cloneTarget;
|
||||
if (args.CLONE_OPTION === '_myself_') {
|
||||
cloneTarget = util.target;
|
||||
} else {
|
||||
|
@ -124,7 +124,7 @@ Scratch3ControlBlocks.prototype.createClone = function (args, util) {
|
|||
if (!cloneTarget) {
|
||||
return;
|
||||
}
|
||||
var newClone = cloneTarget.makeClone();
|
||||
const newClone = cloneTarget.makeClone();
|
||||
if (newClone) {
|
||||
this.runtime.targets.push(newClone);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var Cast = require('../util/cast');
|
||||
const Cast = require('../util/cast');
|
||||
|
||||
var Scratch3DataBlocks = function (runtime) {
|
||||
const Scratch3DataBlocks = function (runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
|
@ -29,30 +29,30 @@ Scratch3DataBlocks.prototype.getPrimitives = function () {
|
|||
};
|
||||
|
||||
Scratch3DataBlocks.prototype.getVariable = function (args, util) {
|
||||
var variable = util.target.lookupOrCreateVariable(args.VARIABLE);
|
||||
const variable = util.target.lookupOrCreateVariable(args.VARIABLE);
|
||||
return variable.value;
|
||||
};
|
||||
|
||||
Scratch3DataBlocks.prototype.setVariableTo = function (args, util) {
|
||||
var variable = util.target.lookupOrCreateVariable(args.VARIABLE);
|
||||
const 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);
|
||||
const variable = util.target.lookupOrCreateVariable(args.VARIABLE);
|
||||
const castedValue = Cast.toNumber(variable.value);
|
||||
const dValue = Cast.toNumber(args.VALUE);
|
||||
variable.value = castedValue + dValue;
|
||||
};
|
||||
|
||||
Scratch3DataBlocks.prototype.getListContents = function (args, util) {
|
||||
var list = util.target.lookupOrCreateList(args.LIST);
|
||||
const 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];
|
||||
let allSingleLetters = true;
|
||||
for (let i = 0; i < list.contents.length; i++) {
|
||||
const listItem = list.contents[i];
|
||||
if (!((typeof listItem === 'string') &&
|
||||
(listItem.length === 1))) {
|
||||
allSingleLetters = false;
|
||||
|
@ -61,19 +61,19 @@ Scratch3DataBlocks.prototype.getListContents = function (args, util) {
|
|||
}
|
||||
if (allSingleLetters) {
|
||||
return list.contents.join('');
|
||||
} else {
|
||||
return list.contents.join(' ');
|
||||
}
|
||||
return list.contents.join(' ');
|
||||
|
||||
};
|
||||
|
||||
Scratch3DataBlocks.prototype.addToList = function (args, util) {
|
||||
var list = util.target.lookupOrCreateList(args.LIST);
|
||||
const 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);
|
||||
const list = util.target.lookupOrCreateList(args.LIST);
|
||||
const index = Cast.toListIndex(args.INDEX, list.contents.length);
|
||||
if (index === Cast.LIST_INVALID) {
|
||||
return;
|
||||
} else if (index === Cast.LIST_ALL) {
|
||||
|
@ -84,9 +84,9 @@ Scratch3DataBlocks.prototype.deleteOfList = function (args, util) {
|
|||
};
|
||||
|
||||
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);
|
||||
const item = args.ITEM;
|
||||
const list = util.target.lookupOrCreateList(args.LIST);
|
||||
const index = Cast.toListIndex(args.INDEX, list.contents.length + 1);
|
||||
if (index === Cast.LIST_INVALID) {
|
||||
return;
|
||||
}
|
||||
|
@ -94,9 +94,9 @@ Scratch3DataBlocks.prototype.insertAtList = function (args, util) {
|
|||
};
|
||||
|
||||
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);
|
||||
const item = args.ITEM;
|
||||
const list = util.target.lookupOrCreateList(args.LIST);
|
||||
const index = Cast.toListIndex(args.INDEX, list.contents.length);
|
||||
if (index === Cast.LIST_INVALID) {
|
||||
return;
|
||||
}
|
||||
|
@ -104,8 +104,8 @@ Scratch3DataBlocks.prototype.replaceItemOfList = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3DataBlocks.prototype.getItemOfList = function (args, util) {
|
||||
var list = util.target.lookupOrCreateList(args.LIST);
|
||||
var index = Cast.toListIndex(args.INDEX, list.contents.length);
|
||||
const list = util.target.lookupOrCreateList(args.LIST);
|
||||
const index = Cast.toListIndex(args.INDEX, list.contents.length);
|
||||
if (index === Cast.LIST_INVALID) {
|
||||
return '';
|
||||
}
|
||||
|
@ -113,19 +113,19 @@ Scratch3DataBlocks.prototype.getItemOfList = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3DataBlocks.prototype.lengthOfList = function (args, util) {
|
||||
var list = util.target.lookupOrCreateList(args.LIST);
|
||||
const 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);
|
||||
const item = args.ITEM;
|
||||
const 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++) {
|
||||
for (let i = 0; i < list.contents.length; i++) {
|
||||
if (Cast.compare(list.contents[i], item) === 0) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var Cast = require('../util/cast');
|
||||
const Cast = require('../util/cast');
|
||||
|
||||
var Scratch3EventBlocks = function (runtime) {
|
||||
const Scratch3EventBlocks = function (runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
|
@ -45,8 +45,8 @@ Scratch3EventBlocks.prototype.getHats = function () {
|
|||
};
|
||||
|
||||
Scratch3EventBlocks.prototype.hatGreaterThanPredicate = function (args, util) {
|
||||
var option = Cast.toString(args.WHENGREATERTHANMENU).toLowerCase();
|
||||
var value = Cast.toNumber(args.VALUE);
|
||||
const option = Cast.toString(args.WHENGREATERTHANMENU).toLowerCase();
|
||||
const value = Cast.toNumber(args.VALUE);
|
||||
// @todo: Other cases :)
|
||||
if (option === 'timer') {
|
||||
return util.ioQuery('clock', 'projectTimer') > value;
|
||||
|
@ -55,14 +55,14 @@ Scratch3EventBlocks.prototype.hatGreaterThanPredicate = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3EventBlocks.prototype.broadcast = function (args, util) {
|
||||
var broadcastOption = Cast.toString(args.BROADCAST_OPTION);
|
||||
const broadcastOption = Cast.toString(args.BROADCAST_OPTION);
|
||||
util.startHats('event_whenbroadcastreceived', {
|
||||
BROADCAST_OPTION: broadcastOption
|
||||
});
|
||||
};
|
||||
|
||||
Scratch3EventBlocks.prototype.broadcastAndWait = function (args, util) {
|
||||
var broadcastOption = Cast.toString(args.BROADCAST_OPTION);
|
||||
const broadcastOption = Cast.toString(args.BROADCAST_OPTION);
|
||||
// Have we run before, starting threads?
|
||||
if (!util.stackFrame.startedThreads) {
|
||||
// No - start hats for this broadcast.
|
||||
|
@ -77,10 +77,8 @@ Scratch3EventBlocks.prototype.broadcastAndWait = function (args, util) {
|
|||
}
|
||||
}
|
||||
// We've run before; check if the wait is still going on.
|
||||
var instance = this;
|
||||
var waiting = util.stackFrame.startedThreads.some(function (thread) {
|
||||
return instance.runtime.isActiveThread(thread);
|
||||
});
|
||||
const instance = this;
|
||||
const waiting = util.stackFrame.startedThreads.some(thread => instance.runtime.isActiveThread(thread));
|
||||
if (waiting) {
|
||||
util.yield();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var Cast = require('../util/cast');
|
||||
const Cast = require('../util/cast');
|
||||
|
||||
var Scratch3LooksBlocks = function (runtime) {
|
||||
const Scratch3LooksBlocks = function (runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
|
@ -45,8 +45,8 @@ Scratch3LooksBlocks.prototype.say = function (args, util) {
|
|||
|
||||
Scratch3LooksBlocks.prototype.sayforsecs = function (args, util) {
|
||||
util.target.setSay('say', args.MESSAGE);
|
||||
return new Promise(function (resolve) {
|
||||
setTimeout(function () {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
// Clear say bubble and proceed.
|
||||
util.target.setSay();
|
||||
resolve();
|
||||
|
@ -60,8 +60,8 @@ Scratch3LooksBlocks.prototype.think = function (args, util) {
|
|||
|
||||
Scratch3LooksBlocks.prototype.thinkforsecs = function (args, util) {
|
||||
util.target.setSay('think', args.MESSAGE);
|
||||
return new Promise(function (resolve) {
|
||||
setTimeout(function () {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
// Clear say bubble and proceed.
|
||||
util.target.setSay();
|
||||
resolve();
|
||||
|
@ -91,7 +91,7 @@ Scratch3LooksBlocks.prototype._setCostumeOrBackdrop = function (target,
|
|||
target.setCostume(optZeroIndex ?
|
||||
requestedCostume : requestedCostume - 1);
|
||||
} else {
|
||||
var costumeIndex = target.getCostumeIndexByName(requestedCostume);
|
||||
const costumeIndex = target.getCostumeIndexByName(requestedCostume);
|
||||
if (costumeIndex > -1) {
|
||||
target.setCostume(costumeIndex);
|
||||
} else if (requestedCostume === 'previous costume' ||
|
||||
|
@ -101,7 +101,7 @@ Scratch3LooksBlocks.prototype._setCostumeOrBackdrop = function (target,
|
|||
requestedCostume === 'next backdrop') {
|
||||
target.setCostume(target.currentCostume + 1);
|
||||
} else {
|
||||
var forcedNumber = Number(requestedCostume);
|
||||
const forcedNumber = Number(requestedCostume);
|
||||
if (!isNaN(forcedNumber)) {
|
||||
target.setCostume(optZeroIndex ?
|
||||
forcedNumber : forcedNumber - 1);
|
||||
|
@ -110,7 +110,7 @@ Scratch3LooksBlocks.prototype._setCostumeOrBackdrop = function (target,
|
|||
}
|
||||
if (target === this.runtime.getTargetForStage()) {
|
||||
// Target is the stage - start hats.
|
||||
var newName = target.sprite.costumes[target.currentCostume].name;
|
||||
const newName = target.sprite.costumes[target.currentCostume].name;
|
||||
return this.runtime.startHats('event_whenbackdropswitchesto', {
|
||||
BACKDROP: newName
|
||||
});
|
||||
|
@ -148,33 +148,31 @@ Scratch3LooksBlocks.prototype.switchBackdropAndWait = function (args, util) {
|
|||
}
|
||||
}
|
||||
// We've run before; check if the wait is still going on.
|
||||
var instance = this;
|
||||
var waiting = util.stackFrame.startedThreads.some(function (thread) {
|
||||
return instance.runtime.isActiveThread(thread);
|
||||
});
|
||||
const instance = this;
|
||||
const waiting = util.stackFrame.startedThreads.some(thread => instance.runtime.isActiveThread(thread));
|
||||
if (waiting) {
|
||||
util.yield();
|
||||
}
|
||||
};
|
||||
|
||||
Scratch3LooksBlocks.prototype.nextBackdrop = function () {
|
||||
var stage = this.runtime.getTargetForStage();
|
||||
const stage = this.runtime.getTargetForStage();
|
||||
this._setCostumeOrBackdrop(
|
||||
stage, stage.currentCostume + 1, true
|
||||
);
|
||||
};
|
||||
|
||||
Scratch3LooksBlocks.prototype.changeEffect = function (args, util) {
|
||||
var effect = Cast.toString(args.EFFECT).toLowerCase();
|
||||
var change = Cast.toNumber(args.CHANGE);
|
||||
const effect = Cast.toString(args.EFFECT).toLowerCase();
|
||||
const change = Cast.toNumber(args.CHANGE);
|
||||
if (!util.target.effects.hasOwnProperty(effect)) return;
|
||||
var newValue = change + util.target.effects[effect];
|
||||
const newValue = change + util.target.effects[effect];
|
||||
util.target.setEffect(effect, newValue);
|
||||
};
|
||||
|
||||
Scratch3LooksBlocks.prototype.setEffect = function (args, util) {
|
||||
var effect = Cast.toString(args.EFFECT).toLowerCase();
|
||||
var value = Cast.toNumber(args.VALUE);
|
||||
const effect = Cast.toString(args.EFFECT).toLowerCase();
|
||||
const value = Cast.toNumber(args.VALUE);
|
||||
util.target.setEffect(effect, value);
|
||||
};
|
||||
|
||||
|
@ -183,12 +181,12 @@ Scratch3LooksBlocks.prototype.clearEffects = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3LooksBlocks.prototype.changeSize = function (args, util) {
|
||||
var change = Cast.toNumber(args.CHANGE);
|
||||
const change = Cast.toNumber(args.CHANGE);
|
||||
util.target.setSize(util.target.size + change);
|
||||
};
|
||||
|
||||
Scratch3LooksBlocks.prototype.setSize = function (args, util) {
|
||||
var size = Cast.toNumber(args.SIZE);
|
||||
const size = Cast.toNumber(args.SIZE);
|
||||
util.target.setSize(size);
|
||||
};
|
||||
|
||||
|
@ -205,12 +203,12 @@ Scratch3LooksBlocks.prototype.getSize = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3LooksBlocks.prototype.getBackdropIndex = function () {
|
||||
var stage = this.runtime.getTargetForStage();
|
||||
const stage = this.runtime.getTargetForStage();
|
||||
return stage.currentCostume + 1;
|
||||
};
|
||||
|
||||
Scratch3LooksBlocks.prototype.getBackdropName = function () {
|
||||
var stage = this.runtime.getTargetForStage();
|
||||
const stage = this.runtime.getTargetForStage();
|
||||
return stage.sprite.costumes[stage.currentCostume].name;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
var Cast = require('../util/cast');
|
||||
var MathUtil = require('../util/math-util');
|
||||
var Timer = require('../util/timer');
|
||||
const Cast = require('../util/cast');
|
||||
const MathUtil = require('../util/math-util');
|
||||
const Timer = require('../util/timer');
|
||||
|
||||
var Scratch3MotionBlocks = function (runtime) {
|
||||
const Scratch3MotionBlocks = function (runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
|
@ -37,32 +37,32 @@ Scratch3MotionBlocks.prototype.getPrimitives = function () {
|
|||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.moveSteps = function (args, util) {
|
||||
var steps = Cast.toNumber(args.STEPS);
|
||||
var radians = MathUtil.degToRad(90 - util.target.direction);
|
||||
var dx = steps * Math.cos(radians);
|
||||
var dy = steps * Math.sin(radians);
|
||||
const steps = Cast.toNumber(args.STEPS);
|
||||
const radians = MathUtil.degToRad(90 - util.target.direction);
|
||||
const dx = steps * Math.cos(radians);
|
||||
const dy = steps * Math.sin(radians);
|
||||
util.target.setXY(util.target.x + dx, util.target.y + dy);
|
||||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.goToXY = function (args, util) {
|
||||
var x = Cast.toNumber(args.X);
|
||||
var y = Cast.toNumber(args.Y);
|
||||
const x = Cast.toNumber(args.X);
|
||||
const y = Cast.toNumber(args.Y);
|
||||
util.target.setXY(x, y);
|
||||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.goTo = function (args, util) {
|
||||
var targetX = 0;
|
||||
var targetY = 0;
|
||||
let targetX = 0;
|
||||
let targetY = 0;
|
||||
if (args.TO === '_mouse_') {
|
||||
targetX = util.ioQuery('mouse', 'getX');
|
||||
targetY = util.ioQuery('mouse', 'getY');
|
||||
} else if (args.TO === '_random_') {
|
||||
var stageWidth = this.runtime.constructor.STAGE_WIDTH;
|
||||
var stageHeight = this.runtime.constructor.STAGE_HEIGHT;
|
||||
const stageWidth = this.runtime.constructor.STAGE_WIDTH;
|
||||
const stageHeight = this.runtime.constructor.STAGE_HEIGHT;
|
||||
targetX = Math.round(stageWidth * (Math.random() - 0.5));
|
||||
targetY = Math.round(stageHeight * (Math.random() - 0.5));
|
||||
} else {
|
||||
var goToTarget = this.runtime.getSpriteTargetByName(args.TO);
|
||||
const goToTarget = this.runtime.getSpriteTargetByName(args.TO);
|
||||
if (!goToTarget) return;
|
||||
targetX = goToTarget.x;
|
||||
targetY = goToTarget.y;
|
||||
|
@ -71,36 +71,36 @@ Scratch3MotionBlocks.prototype.goTo = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.turnRight = function (args, util) {
|
||||
var degrees = Cast.toNumber(args.DEGREES);
|
||||
const degrees = Cast.toNumber(args.DEGREES);
|
||||
util.target.setDirection(util.target.direction + degrees);
|
||||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.turnLeft = function (args, util) {
|
||||
var degrees = Cast.toNumber(args.DEGREES);
|
||||
const degrees = Cast.toNumber(args.DEGREES);
|
||||
util.target.setDirection(util.target.direction - degrees);
|
||||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.pointInDirection = function (args, util) {
|
||||
var direction = Cast.toNumber(args.DIRECTION);
|
||||
const direction = Cast.toNumber(args.DIRECTION);
|
||||
util.target.setDirection(direction);
|
||||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.pointTowards = function (args, util) {
|
||||
var targetX = 0;
|
||||
var targetY = 0;
|
||||
let targetX = 0;
|
||||
let targetY = 0;
|
||||
if (args.TOWARDS === '_mouse_') {
|
||||
targetX = util.ioQuery('mouse', 'getX');
|
||||
targetY = util.ioQuery('mouse', 'getY');
|
||||
} else {
|
||||
var pointTarget = this.runtime.getSpriteTargetByName(args.TOWARDS);
|
||||
const pointTarget = this.runtime.getSpriteTargetByName(args.TOWARDS);
|
||||
if (!pointTarget) return;
|
||||
targetX = pointTarget.x;
|
||||
targetY = pointTarget.y;
|
||||
}
|
||||
|
||||
var dx = targetX - util.target.x;
|
||||
var dy = targetY - util.target.y;
|
||||
var direction = 90 - MathUtil.radToDeg(Math.atan2(dy, dx));
|
||||
const dx = targetX - util.target.x;
|
||||
const dy = targetY - util.target.y;
|
||||
const direction = 90 - MathUtil.radToDeg(Math.atan2(dy, dx));
|
||||
util.target.setDirection(direction);
|
||||
};
|
||||
|
||||
|
@ -121,12 +121,12 @@ Scratch3MotionBlocks.prototype.glide = function (args, util) {
|
|||
}
|
||||
util.yield();
|
||||
} else {
|
||||
var timeElapsed = util.stackFrame.timer.timeElapsed();
|
||||
const timeElapsed = util.stackFrame.timer.timeElapsed();
|
||||
if (timeElapsed < util.stackFrame.duration * 1000) {
|
||||
// In progress: move to intermediate position.
|
||||
var frac = timeElapsed / (util.stackFrame.duration * 1000);
|
||||
var dx = frac * (util.stackFrame.endX - util.stackFrame.startX);
|
||||
var dy = frac * (util.stackFrame.endY - util.stackFrame.startY);
|
||||
const frac = timeElapsed / (util.stackFrame.duration * 1000);
|
||||
const dx = frac * (util.stackFrame.endX - util.stackFrame.startX);
|
||||
const dy = frac * (util.stackFrame.endY - util.stackFrame.startY);
|
||||
util.target.setXY(
|
||||
util.stackFrame.startX + dx,
|
||||
util.stackFrame.startY + dy
|
||||
|
@ -140,22 +140,22 @@ Scratch3MotionBlocks.prototype.glide = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.ifOnEdgeBounce = function (args, util) {
|
||||
var bounds = util.target.getBounds();
|
||||
const bounds = util.target.getBounds();
|
||||
if (!bounds) {
|
||||
return;
|
||||
}
|
||||
// Measure distance to edges.
|
||||
// Values are positive when the sprite is far away,
|
||||
// and clamped to zero when the sprite is beyond.
|
||||
var stageWidth = this.runtime.constructor.STAGE_WIDTH;
|
||||
var stageHeight = this.runtime.constructor.STAGE_HEIGHT;
|
||||
var distLeft = Math.max(0, (stageWidth / 2) + bounds.left);
|
||||
var distTop = Math.max(0, (stageHeight / 2) - bounds.top);
|
||||
var distRight = Math.max(0, (stageWidth / 2) - bounds.right);
|
||||
var distBottom = Math.max(0, (stageHeight / 2) + bounds.bottom);
|
||||
const stageWidth = this.runtime.constructor.STAGE_WIDTH;
|
||||
const stageHeight = this.runtime.constructor.STAGE_HEIGHT;
|
||||
const distLeft = Math.max(0, (stageWidth / 2) + bounds.left);
|
||||
const distTop = Math.max(0, (stageHeight / 2) - bounds.top);
|
||||
const distRight = Math.max(0, (stageWidth / 2) - bounds.right);
|
||||
const distBottom = Math.max(0, (stageHeight / 2) + bounds.bottom);
|
||||
// Find the nearest edge.
|
||||
var nearestEdge = '';
|
||||
var minDist = Infinity;
|
||||
let nearestEdge = '';
|
||||
let minDist = Infinity;
|
||||
if (distLeft < minDist) {
|
||||
minDist = distLeft;
|
||||
nearestEdge = 'left';
|
||||
|
@ -176,9 +176,9 @@ Scratch3MotionBlocks.prototype.ifOnEdgeBounce = function (args, util) {
|
|||
return; // Not touching any edge.
|
||||
}
|
||||
// Point away from the nearest edge.
|
||||
var radians = MathUtil.degToRad(90 - util.target.direction);
|
||||
var dx = Math.cos(radians);
|
||||
var dy = -Math.sin(radians);
|
||||
const radians = MathUtil.degToRad(90 - util.target.direction);
|
||||
let dx = Math.cos(radians);
|
||||
let dy = -Math.sin(radians);
|
||||
if (nearestEdge === 'left') {
|
||||
dx = Math.max(0.2, Math.abs(dx));
|
||||
} else if (nearestEdge === 'top') {
|
||||
|
@ -188,10 +188,10 @@ Scratch3MotionBlocks.prototype.ifOnEdgeBounce = function (args, util) {
|
|||
} else if (nearestEdge === 'bottom') {
|
||||
dy = 0 - Math.max(0.2, Math.abs(dy));
|
||||
}
|
||||
var newDirection = MathUtil.radToDeg(Math.atan2(dy, dx)) + 90;
|
||||
const newDirection = MathUtil.radToDeg(Math.atan2(dy, dx)) + 90;
|
||||
util.target.setDirection(newDirection);
|
||||
// Keep within the stage.
|
||||
var fencedPosition = util.target.keepInFence(util.target.x, util.target.y);
|
||||
const fencedPosition = util.target.keepInFence(util.target.x, util.target.y);
|
||||
util.target.setXY(fencedPosition[0], fencedPosition[1]);
|
||||
};
|
||||
|
||||
|
@ -200,22 +200,22 @@ Scratch3MotionBlocks.prototype.setRotationStyle = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.changeX = function (args, util) {
|
||||
var dx = Cast.toNumber(args.DX);
|
||||
const dx = Cast.toNumber(args.DX);
|
||||
util.target.setXY(util.target.x + dx, util.target.y);
|
||||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.setX = function (args, util) {
|
||||
var x = Cast.toNumber(args.X);
|
||||
const x = Cast.toNumber(args.X);
|
||||
util.target.setXY(x, util.target.y);
|
||||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.changeY = function (args, util) {
|
||||
var dy = Cast.toNumber(args.DY);
|
||||
const dy = Cast.toNumber(args.DY);
|
||||
util.target.setXY(util.target.x, util.target.y + dy);
|
||||
};
|
||||
|
||||
Scratch3MotionBlocks.prototype.setY = function (args, util) {
|
||||
var y = Cast.toNumber(args.Y);
|
||||
const y = Cast.toNumber(args.Y);
|
||||
util.target.setXY(util.target.x, y);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
var Cast = require('../util/cast.js');
|
||||
var MathUtil = require('../util/math-util.js');
|
||||
const Cast = require('../util/cast.js');
|
||||
const MathUtil = require('../util/math-util.js');
|
||||
|
||||
var Scratch3OperatorsBlocks = function (runtime) {
|
||||
const Scratch3OperatorsBlocks = function (runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
|
@ -76,10 +76,10 @@ Scratch3OperatorsBlocks.prototype.not = function (args) {
|
|||
};
|
||||
|
||||
Scratch3OperatorsBlocks.prototype.random = function (args) {
|
||||
var nFrom = Cast.toNumber(args.FROM);
|
||||
var nTo = Cast.toNumber(args.TO);
|
||||
var low = nFrom <= nTo ? nFrom : nTo;
|
||||
var high = nFrom <= nTo ? nTo : nFrom;
|
||||
const nFrom = Cast.toNumber(args.FROM);
|
||||
const nTo = Cast.toNumber(args.TO);
|
||||
const low = nFrom <= nTo ? nFrom : nTo;
|
||||
const high = nFrom <= nTo ? nTo : nFrom;
|
||||
if (low === high) return low;
|
||||
// If both arguments are ints, truncate the result to an int.
|
||||
if (Cast.isInt(args.FROM) && Cast.isInt(args.TO)) {
|
||||
|
@ -93,8 +93,8 @@ Scratch3OperatorsBlocks.prototype.join = function (args) {
|
|||
};
|
||||
|
||||
Scratch3OperatorsBlocks.prototype.letterOf = function (args) {
|
||||
var index = Cast.toNumber(args.LETTER) - 1;
|
||||
var str = Cast.toString(args.STRING);
|
||||
const index = Cast.toNumber(args.LETTER) - 1;
|
||||
const str = Cast.toString(args.STRING);
|
||||
// Out of bounds?
|
||||
if (index < 0 || index >= str.length) {
|
||||
return '';
|
||||
|
@ -107,9 +107,9 @@ Scratch3OperatorsBlocks.prototype.length = function (args) {
|
|||
};
|
||||
|
||||
Scratch3OperatorsBlocks.prototype.mod = function (args) {
|
||||
var n = Cast.toNumber(args.NUM1);
|
||||
var modulus = Cast.toNumber(args.NUM2);
|
||||
var result = n % modulus;
|
||||
const n = Cast.toNumber(args.NUM1);
|
||||
const modulus = Cast.toNumber(args.NUM2);
|
||||
let result = n % modulus;
|
||||
// Scratch mod is kept positive.
|
||||
if (result / modulus < 0) result += modulus;
|
||||
return result;
|
||||
|
@ -120,8 +120,8 @@ Scratch3OperatorsBlocks.prototype.round = function (args) {
|
|||
};
|
||||
|
||||
Scratch3OperatorsBlocks.prototype.mathop = function (args) {
|
||||
var operator = Cast.toString(args.OPERATOR).toLowerCase();
|
||||
var n = Cast.toNumber(args.NUM);
|
||||
const operator = Cast.toString(args.OPERATOR).toLowerCase();
|
||||
const n = Cast.toNumber(args.NUM);
|
||||
switch (operator) {
|
||||
case 'abs': return Math.abs(n);
|
||||
case 'floor': return Math.floor(n);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
var Cast = require('../util/cast');
|
||||
var Clone = require('../util/clone');
|
||||
var Color = require('../util/color');
|
||||
var MathUtil = require('../util/math-util');
|
||||
var RenderedTarget = require('../sprites/rendered-target');
|
||||
const Cast = require('../util/cast');
|
||||
const Clone = require('../util/clone');
|
||||
const Color = require('../util/color');
|
||||
const MathUtil = require('../util/math-util');
|
||||
const RenderedTarget = require('../sprites/rendered-target');
|
||||
|
||||
/**
|
||||
* @typedef {object} PenState - the pen state associated with a particular target.
|
||||
|
@ -18,7 +18,7 @@ var RenderedTarget = require('../sprites/rendered-target');
|
|||
* @param {Runtime} runtime - the runtime instantiating this block package.
|
||||
* @constructor
|
||||
*/
|
||||
var Scratch3PenBlocks = function (runtime) {
|
||||
const Scratch3PenBlocks = function (runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
|
@ -107,7 +107,7 @@ Scratch3PenBlocks.prototype._getPenLayerID = function () {
|
|||
* @private
|
||||
*/
|
||||
Scratch3PenBlocks.prototype._getPenState = function (target) {
|
||||
var penState = target.getCustomState(Scratch3PenBlocks.STATE_KEY);
|
||||
let penState = target.getCustomState(Scratch3PenBlocks.STATE_KEY);
|
||||
if (!penState) {
|
||||
penState = Clone.simple(Scratch3PenBlocks.DEFAULT_PEN_STATE);
|
||||
target.setCustomState(Scratch3PenBlocks.STATE_KEY, penState);
|
||||
|
@ -123,9 +123,9 @@ Scratch3PenBlocks.prototype._getPenState = function (target) {
|
|||
* @private
|
||||
*/
|
||||
Scratch3PenBlocks.prototype._onTargetMoved = function (target, oldX, oldY) {
|
||||
var penSkinId = this._getPenLayerID();
|
||||
const penSkinId = this._getPenLayerID();
|
||||
if (penSkinId >= 0) {
|
||||
var penState = this._getPenState(target);
|
||||
const penState = this._getPenState(target);
|
||||
this.runtime.renderer.penLine(penSkinId, penState.penAttributes, oldX, oldY, target.x, target.y);
|
||||
this.runtime.requestRedraw();
|
||||
}
|
||||
|
@ -137,8 +137,8 @@ Scratch3PenBlocks.prototype._onTargetMoved = function (target, oldX, oldY) {
|
|||
* @private
|
||||
*/
|
||||
Scratch3PenBlocks.prototype._updatePenColor = function (penState) {
|
||||
var rgb = Color.hsvToRgb({h: penState.hue * 180 / 100, s: 1, v: 1});
|
||||
var shade = (penState.shade > 100) ? 200 - penState.shade : penState.shade;
|
||||
let rgb = Color.hsvToRgb({h: penState.hue * 180 / 100, s: 1, v: 1});
|
||||
const shade = (penState.shade > 100) ? 200 - penState.shade : penState.shade;
|
||||
if (shade < 50) {
|
||||
rgb = Color.mixRgb(Color.RGB_BLACK, rgb, (10 + shade) / 60);
|
||||
} else {
|
||||
|
@ -186,7 +186,7 @@ Scratch3PenBlocks.prototype.getPrimitives = function () {
|
|||
* The pen "clear" block clears the pen layer's contents.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.clear = function () {
|
||||
var penSkinId = this._getPenLayerID();
|
||||
const penSkinId = this._getPenLayerID();
|
||||
if (penSkinId >= 0) {
|
||||
this.runtime.renderer.penClear(penSkinId);
|
||||
this.runtime.requestRedraw();
|
||||
|
@ -199,9 +199,9 @@ Scratch3PenBlocks.prototype.clear = function () {
|
|||
* @param {object} util - utility object provided by the runtime.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.stamp = function (args, util) {
|
||||
var penSkinId = this._getPenLayerID();
|
||||
const penSkinId = this._getPenLayerID();
|
||||
if (penSkinId >= 0) {
|
||||
var target = util.target;
|
||||
const target = util.target;
|
||||
this.runtime.renderer.penStamp(penSkinId, target.drawableID);
|
||||
this.runtime.requestRedraw();
|
||||
}
|
||||
|
@ -213,15 +213,15 @@ Scratch3PenBlocks.prototype.stamp = function (args, util) {
|
|||
* @param {object} util - utility object provided by the runtime.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.penDown = function (args, util) {
|
||||
var target = util.target;
|
||||
var penState = this._getPenState(target);
|
||||
const target = util.target;
|
||||
const penState = this._getPenState(target);
|
||||
|
||||
if (!penState.penDown) {
|
||||
penState.penDown = true;
|
||||
target.addListener(RenderedTarget.EVENT_TARGET_MOVED, this._onTargetMoved);
|
||||
}
|
||||
|
||||
var penSkinId = this._getPenLayerID();
|
||||
const penSkinId = this._getPenLayerID();
|
||||
if (penSkinId >= 0) {
|
||||
this.runtime.renderer.penPoint(penSkinId, penState.penAttributes, target.x, target.y);
|
||||
this.runtime.requestRedraw();
|
||||
|
@ -234,8 +234,8 @@ Scratch3PenBlocks.prototype.penDown = function (args, util) {
|
|||
* @param {object} util - utility object provided by the runtime.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.penUp = function (args, util) {
|
||||
var target = util.target;
|
||||
var penState = this._getPenState(target);
|
||||
const target = util.target;
|
||||
const penState = this._getPenState(target);
|
||||
|
||||
if (penState.penDown) {
|
||||
penState.penDown = false;
|
||||
|
@ -250,9 +250,9 @@ Scratch3PenBlocks.prototype.penUp = function (args, util) {
|
|||
* @param {object} util - utility object provided by the runtime.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.setPenColorToColor = function (args, util) {
|
||||
var penState = this._getPenState(util.target);
|
||||
var rgb = Cast.toRgbColorObject(args.COLOR);
|
||||
var hsv = Color.rgbToHsv(rgb);
|
||||
const penState = this._getPenState(util.target);
|
||||
const rgb = Cast.toRgbColorObject(args.COLOR);
|
||||
const hsv = Color.rgbToHsv(rgb);
|
||||
|
||||
penState.hue = 200 * hsv.h / 360;
|
||||
penState.shade = 50 * hsv.v;
|
||||
|
@ -273,7 +273,7 @@ Scratch3PenBlocks.prototype.setPenColorToColor = function (args, util) {
|
|||
* @param {object} util - utility object provided by the runtime.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.changePenHueBy = function (args, util) {
|
||||
var penState = this._getPenState(util.target);
|
||||
const penState = this._getPenState(util.target);
|
||||
penState.hue = this._wrapHueOrShade(penState.hue + Cast.toNumber(args.COLOR));
|
||||
this._updatePenColor(penState);
|
||||
};
|
||||
|
@ -285,7 +285,7 @@ Scratch3PenBlocks.prototype.changePenHueBy = function (args, util) {
|
|||
* @param {object} util - utility object provided by the runtime.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.setPenHueToNumber = function (args, util) {
|
||||
var penState = this._getPenState(util.target);
|
||||
const penState = this._getPenState(util.target);
|
||||
penState.hue = this._wrapHueOrShade(Cast.toNumber(args.COLOR));
|
||||
this._updatePenColor(penState);
|
||||
};
|
||||
|
@ -297,7 +297,7 @@ Scratch3PenBlocks.prototype.setPenHueToNumber = function (args, util) {
|
|||
* @param {object} util - utility object provided by the runtime.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.changePenShadeBy = function (args, util) {
|
||||
var penState = this._getPenState(util.target);
|
||||
const penState = this._getPenState(util.target);
|
||||
penState.shade = this._wrapHueOrShade(penState.shade + Cast.toNumber(args.SHADE));
|
||||
this._updatePenColor(penState);
|
||||
};
|
||||
|
@ -309,7 +309,7 @@ Scratch3PenBlocks.prototype.changePenShadeBy = function (args, util) {
|
|||
* @param {object} util - utility object provided by the runtime.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.setPenShadeToNumber = function (args, util) {
|
||||
var penState = this._getPenState(util.target);
|
||||
const penState = this._getPenState(util.target);
|
||||
penState.shade = this._wrapHueOrShade(Cast.toNumber(args.SHADE));
|
||||
this._updatePenColor(penState);
|
||||
};
|
||||
|
@ -321,7 +321,7 @@ Scratch3PenBlocks.prototype.setPenShadeToNumber = function (args, util) {
|
|||
* @param {object} util - utility object provided by the runtime.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.changePenSizeBy = function (args, util) {
|
||||
var penAttributes = this._getPenState(util.target).penAttributes;
|
||||
const penAttributes = this._getPenState(util.target).penAttributes;
|
||||
penAttributes.diameter = this._clampPenSize(penAttributes.diameter + Cast.toNumber(args.SIZE));
|
||||
};
|
||||
|
||||
|
@ -332,7 +332,7 @@ Scratch3PenBlocks.prototype.changePenSizeBy = function (args, util) {
|
|||
* @param {object} util - utility object provided by the runtime.
|
||||
*/
|
||||
Scratch3PenBlocks.prototype.setPenSizeTo = function (args, util) {
|
||||
var penAttributes = this._getPenState(util.target).penAttributes;
|
||||
const penAttributes = this._getPenState(util.target).penAttributes;
|
||||
penAttributes.diameter = this._clampPenSize(Cast.toNumber(args.SIZE));
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var Scratch3ProcedureBlocks = function (runtime) {
|
||||
const Scratch3ProcedureBlocks = function (runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
|
@ -24,11 +24,11 @@ Scratch3ProcedureBlocks.prototype.defNoReturn = function () {
|
|||
|
||||
Scratch3ProcedureBlocks.prototype.callNoReturn = function (args, util) {
|
||||
if (!util.stackFrame.executed) {
|
||||
var procedureCode = args.mutation.proccode;
|
||||
var paramNames = util.getProcedureParamNames(procedureCode);
|
||||
for (var i = 0; i < paramNames.length; i++) {
|
||||
if (args.hasOwnProperty('input' + i)) {
|
||||
util.pushParam(paramNames[i], args['input' + i]);
|
||||
const procedureCode = args.mutation.proccode;
|
||||
const paramNames = util.getProcedureParamNames(procedureCode);
|
||||
for (let i = 0; i < paramNames.length; i++) {
|
||||
if (args.hasOwnProperty(`input${i}`)) {
|
||||
util.pushParam(paramNames[i], args[`input${i}`]);
|
||||
}
|
||||
}
|
||||
util.stackFrame.executed = true;
|
||||
|
@ -37,7 +37,7 @@ Scratch3ProcedureBlocks.prototype.callNoReturn = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3ProcedureBlocks.prototype.param = function (args, util) {
|
||||
var value = util.getParam(args.mutation.paramname);
|
||||
const value = util.getParam(args.mutation.paramname);
|
||||
return value;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var Cast = require('../util/cast');
|
||||
const Cast = require('../util/cast');
|
||||
|
||||
var Scratch3SensingBlocks = function (runtime) {
|
||||
const Scratch3SensingBlocks = function (runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
|
@ -32,39 +32,39 @@ Scratch3SensingBlocks.prototype.getPrimitives = function () {
|
|||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.touchingObject = function (args, util) {
|
||||
var requestedObject = args.TOUCHINGOBJECTMENU;
|
||||
const requestedObject = args.TOUCHINGOBJECTMENU;
|
||||
if (requestedObject === '_mouse_') {
|
||||
var mouseX = util.ioQuery('mouse', 'getX');
|
||||
var mouseY = util.ioQuery('mouse', 'getY');
|
||||
const mouseX = util.ioQuery('mouse', 'getX');
|
||||
const mouseY = util.ioQuery('mouse', 'getY');
|
||||
return util.target.isTouchingPoint(mouseX, mouseY);
|
||||
} else if (requestedObject === '_edge_') {
|
||||
return util.target.isTouchingEdge();
|
||||
} else {
|
||||
return util.target.isTouchingSprite(requestedObject);
|
||||
}
|
||||
return util.target.isTouchingSprite(requestedObject);
|
||||
|
||||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.touchingColor = function (args, util) {
|
||||
var color = Cast.toRgbColorList(args.COLOR);
|
||||
const color = Cast.toRgbColorList(args.COLOR);
|
||||
return util.target.isTouchingColor(color);
|
||||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.colorTouchingColor = function (args, util) {
|
||||
var maskColor = Cast.toRgbColorList(args.COLOR);
|
||||
var targetColor = Cast.toRgbColorList(args.COLOR2);
|
||||
const maskColor = Cast.toRgbColorList(args.COLOR);
|
||||
const targetColor = Cast.toRgbColorList(args.COLOR2);
|
||||
return util.target.colorIsTouchingColor(targetColor, maskColor);
|
||||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.distanceTo = function (args, util) {
|
||||
if (util.target.isStage) return 10000;
|
||||
|
||||
var targetX = 0;
|
||||
var targetY = 0;
|
||||
let targetX = 0;
|
||||
let targetY = 0;
|
||||
if (args.DISTANCETOMENU === '_mouse_') {
|
||||
targetX = util.ioQuery('mouse', 'getX');
|
||||
targetY = util.ioQuery('mouse', 'getY');
|
||||
} else {
|
||||
var distTarget = this.runtime.getSpriteTargetByName(
|
||||
const distTarget = this.runtime.getSpriteTargetByName(
|
||||
args.DISTANCETOMENU
|
||||
);
|
||||
if (!distTarget) return 10000;
|
||||
|
@ -72,8 +72,8 @@ Scratch3SensingBlocks.prototype.distanceTo = function (args, util) {
|
|||
targetY = distTarget.y;
|
||||
}
|
||||
|
||||
var dx = util.target.x - targetX;
|
||||
var dy = util.target.y - targetY;
|
||||
const dx = util.target.x - targetX;
|
||||
const dy = util.target.y - targetY;
|
||||
return Math.sqrt((dx * dx) + (dy * dy));
|
||||
};
|
||||
|
||||
|
@ -98,8 +98,8 @@ Scratch3SensingBlocks.prototype.getMouseDown = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.current = function (args) {
|
||||
var menuOption = Cast.toString(args.CURRENTMENU).toLowerCase();
|
||||
var date = new Date();
|
||||
const menuOption = Cast.toString(args.CURRENTMENU).toLowerCase();
|
||||
const date = new Date();
|
||||
switch (menuOption) {
|
||||
case 'year': return date.getFullYear();
|
||||
case 'month': return date.getMonth() + 1; // getMonth is zero-based
|
||||
|
@ -117,11 +117,11 @@ Scratch3SensingBlocks.prototype.getKeyPressed = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.daysSince2000 = function () {
|
||||
var msPerDay = 24 * 60 * 60 * 1000;
|
||||
var start = new Date(2000, 0, 1); // Months are 0-indexed.
|
||||
var today = new Date();
|
||||
var dstAdjust = today.getTimezoneOffset() - start.getTimezoneOffset();
|
||||
var mSecsSinceStart = today.valueOf() - start.valueOf();
|
||||
const msPerDay = 24 * 60 * 60 * 1000;
|
||||
const start = new Date(2000, 0, 1); // Months are 0-indexed.
|
||||
const today = new Date();
|
||||
const dstAdjust = today.getTimezoneOffset() - start.getTimezoneOffset();
|
||||
let mSecsSinceStart = today.valueOf() - start.valueOf();
|
||||
mSecsSinceStart += ((today.getTimezoneOffset() - dstAdjust) * 60 * 1000);
|
||||
return mSecsSinceStart / msPerDay;
|
||||
};
|
||||
|
@ -132,7 +132,7 @@ Scratch3SensingBlocks.prototype.getLoudness = function () {
|
|||
};
|
||||
|
||||
Scratch3SensingBlocks.prototype.getAttributeOf = function (args) {
|
||||
var attrTarget;
|
||||
let attrTarget;
|
||||
|
||||
if (args.OBJECT === '_stage_') {
|
||||
attrTarget = this.runtime.getTargetForStage();
|
||||
|
@ -165,7 +165,7 @@ Scratch3SensingBlocks.prototype.getAttributeOf = function (args) {
|
|||
}
|
||||
|
||||
// Variables
|
||||
var varName = args.PROPERTY;
|
||||
const varName = args.PROPERTY;
|
||||
if (attrTarget.variables.hasOwnProperty(varName)) {
|
||||
return attrTarget.variables[varName].value;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
var MathUtil = require('../util/math-util');
|
||||
var Cast = require('../util/cast');
|
||||
var Clone = require('../util/clone');
|
||||
const MathUtil = require('../util/math-util');
|
||||
const Cast = require('../util/cast');
|
||||
const Clone = require('../util/clone');
|
||||
|
||||
var Scratch3SoundBlocks = function (runtime) {
|
||||
const Scratch3SoundBlocks = function (runtime) {
|
||||
/**
|
||||
* The runtime instantiating this block package.
|
||||
* @type {Runtime}
|
||||
|
@ -69,7 +69,7 @@ Scratch3SoundBlocks.EFFECT_RANGE = {
|
|||
* @private
|
||||
*/
|
||||
Scratch3SoundBlocks.prototype._getSoundState = function (target) {
|
||||
var soundState = target.getCustomState(Scratch3SoundBlocks.STATE_KEY);
|
||||
let soundState = target.getCustomState(Scratch3SoundBlocks.STATE_KEY);
|
||||
if (!soundState) {
|
||||
soundState = Clone.simple(Scratch3SoundBlocks.DEFAULT_SOUND_STATE);
|
||||
target.setCustomState(Scratch3SoundBlocks.STATE_KEY, soundState);
|
||||
|
@ -106,18 +106,18 @@ Scratch3SoundBlocks.prototype.getPrimitives = function () {
|
|||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.playSound = function (args, util) {
|
||||
var index = this._getSoundIndex(args.SOUND_MENU, util);
|
||||
const index = this._getSoundIndex(args.SOUND_MENU, util);
|
||||
if (index >= 0) {
|
||||
var md5 = util.target.sprite.sounds[index].md5;
|
||||
const md5 = util.target.sprite.sounds[index].md5;
|
||||
if (util.target.audioPlayer === null) return;
|
||||
util.target.audioPlayer.playSound(md5);
|
||||
}
|
||||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.playSoundAndWait = function (args, util) {
|
||||
var index = this._getSoundIndex(args.SOUND_MENU, util);
|
||||
const index = this._getSoundIndex(args.SOUND_MENU, util);
|
||||
if (index >= 0) {
|
||||
var md5 = util.target.sprite.sounds[index].md5;
|
||||
const md5 = util.target.sprite.sounds[index].md5;
|
||||
if (util.target.audioPlayer === null) return;
|
||||
return util.target.audioPlayer.playSound(md5);
|
||||
}
|
||||
|
@ -125,15 +125,15 @@ Scratch3SoundBlocks.prototype.playSoundAndWait = function (args, util) {
|
|||
|
||||
Scratch3SoundBlocks.prototype._getSoundIndex = function (soundName, util) {
|
||||
// if the sprite has no sounds, return -1
|
||||
var len = util.target.sprite.sounds.length;
|
||||
const len = util.target.sprite.sounds.length;
|
||||
if (len === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var index;
|
||||
let index;
|
||||
|
||||
// try to convert to a number and use that as an index
|
||||
var num = parseInt(soundName, 10);
|
||||
const num = parseInt(soundName, 10);
|
||||
if (!isNaN(num)) {
|
||||
index = MathUtil.wrapClamp(num, 0, len - 1);
|
||||
return index;
|
||||
|
@ -145,8 +145,8 @@ Scratch3SoundBlocks.prototype._getSoundIndex = function (soundName, util) {
|
|||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.getSoundIndexByName = function (soundName, util) {
|
||||
var sounds = util.target.sprite.sounds;
|
||||
for (var i = 0; i < sounds.length; i++) {
|
||||
const sounds = util.target.sprite.sounds;
|
||||
for (let i = 0; i < sounds.length; i++) {
|
||||
if (sounds[i].name === soundName) {
|
||||
return i;
|
||||
}
|
||||
|
@ -161,30 +161,30 @@ Scratch3SoundBlocks.prototype.stopAllSounds = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.playNoteForBeats = function (args, util) {
|
||||
var note = Cast.toNumber(args.NOTE);
|
||||
let note = Cast.toNumber(args.NOTE);
|
||||
note = MathUtil.clamp(note, Scratch3SoundBlocks.MIDI_NOTE_RANGE.min, Scratch3SoundBlocks.MIDI_NOTE_RANGE.max);
|
||||
var beats = Cast.toNumber(args.BEATS);
|
||||
let beats = Cast.toNumber(args.BEATS);
|
||||
beats = this._clampBeats(beats);
|
||||
var soundState = this._getSoundState(util.target);
|
||||
var inst = soundState.currentInstrument;
|
||||
var vol = soundState.volume;
|
||||
const soundState = this._getSoundState(util.target);
|
||||
const inst = soundState.currentInstrument;
|
||||
const vol = soundState.volume;
|
||||
if (typeof this.runtime.audioEngine === 'undefined') return;
|
||||
return this.runtime.audioEngine.playNoteForBeatsWithInstAndVol(note, beats, inst, vol);
|
||||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.playDrumForBeats = function (args, util) {
|
||||
var drum = Cast.toNumber(args.DRUM);
|
||||
let drum = Cast.toNumber(args.DRUM);
|
||||
drum -= 1; // drums are one-indexed
|
||||
if (typeof this.runtime.audioEngine === 'undefined') return;
|
||||
drum = MathUtil.wrapClamp(drum, 0, this.runtime.audioEngine.numDrums);
|
||||
var beats = Cast.toNumber(args.BEATS);
|
||||
let beats = Cast.toNumber(args.BEATS);
|
||||
beats = this._clampBeats(beats);
|
||||
if (util.target.audioPlayer === null) return;
|
||||
return util.target.audioPlayer.playDrumForBeats(drum, beats);
|
||||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.restForBeats = function (args) {
|
||||
var beats = Cast.toNumber(args.BEATS);
|
||||
let beats = Cast.toNumber(args.BEATS);
|
||||
beats = this._clampBeats(beats);
|
||||
if (typeof this.runtime.audioEngine === 'undefined') return;
|
||||
return this.runtime.audioEngine.waitForBeats(beats);
|
||||
|
@ -195,8 +195,8 @@ Scratch3SoundBlocks.prototype._clampBeats = function (beats) {
|
|||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.setInstrument = function (args, util) {
|
||||
var soundState = this._getSoundState(util.target);
|
||||
var instNum = Cast.toNumber(args.INSTRUMENT);
|
||||
const soundState = this._getSoundState(util.target);
|
||||
let instNum = Cast.toNumber(args.INSTRUMENT);
|
||||
instNum -= 1; // instruments are one-indexed
|
||||
if (typeof this.runtime.audioEngine === 'undefined') return;
|
||||
instNum = MathUtil.wrapClamp(instNum, 0, this.runtime.audioEngine.numInstruments);
|
||||
|
@ -213,10 +213,10 @@ Scratch3SoundBlocks.prototype.changeEffect = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype._updateEffect = function (args, util, change) {
|
||||
var effect = Cast.toString(args.EFFECT).toLowerCase();
|
||||
var value = Cast.toNumber(args.VALUE);
|
||||
const effect = Cast.toString(args.EFFECT).toLowerCase();
|
||||
const value = Cast.toNumber(args.VALUE);
|
||||
|
||||
var soundState = this._getSoundState(util.target);
|
||||
const soundState = this._getSoundState(util.target);
|
||||
if (!soundState.effects.hasOwnProperty(effect)) return;
|
||||
|
||||
if (change) {
|
||||
|
@ -225,7 +225,7 @@ Scratch3SoundBlocks.prototype._updateEffect = function (args, util, change) {
|
|||
soundState.effects[effect] = value;
|
||||
}
|
||||
|
||||
var effectRange = Scratch3SoundBlocks.EFFECT_RANGE[effect];
|
||||
const effectRange = Scratch3SoundBlocks.EFFECT_RANGE[effect];
|
||||
soundState.effects[effect] = MathUtil.clamp(soundState.effects[effect], effectRange.min, effectRange.max);
|
||||
|
||||
if (util.target.audioPlayer === null) return;
|
||||
|
@ -233,8 +233,8 @@ Scratch3SoundBlocks.prototype._updateEffect = function (args, util, change) {
|
|||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.clearEffects = function (args, util) {
|
||||
var soundState = this._getSoundState(util.target);
|
||||
for (var effect in soundState.effects) {
|
||||
const soundState = this._getSoundState(util.target);
|
||||
for (const effect in soundState.effects) {
|
||||
if (!soundState.effects.hasOwnProperty(effect)) continue;
|
||||
soundState.effects[effect] = 0;
|
||||
}
|
||||
|
@ -243,18 +243,18 @@ Scratch3SoundBlocks.prototype.clearEffects = function (args, util) {
|
|||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.setVolume = function (args, util) {
|
||||
var volume = Cast.toNumber(args.VOLUME);
|
||||
const volume = Cast.toNumber(args.VOLUME);
|
||||
this._updateVolume(volume, util);
|
||||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.changeVolume = function (args, util) {
|
||||
var soundState = this._getSoundState(util.target);
|
||||
var volume = Cast.toNumber(args.VOLUME) + soundState.volume;
|
||||
const soundState = this._getSoundState(util.target);
|
||||
const volume = Cast.toNumber(args.VOLUME) + soundState.volume;
|
||||
this._updateVolume(volume, util);
|
||||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype._updateVolume = function (volume, util) {
|
||||
var soundState = this._getSoundState(util.target);
|
||||
const soundState = this._getSoundState(util.target);
|
||||
volume = MathUtil.clamp(volume, 0, 100);
|
||||
soundState.volume = volume;
|
||||
if (util.target.audioPlayer === null) return;
|
||||
|
@ -262,19 +262,19 @@ Scratch3SoundBlocks.prototype._updateVolume = function (volume, util) {
|
|||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.getVolume = function (args, util) {
|
||||
var soundState = this._getSoundState(util.target);
|
||||
const soundState = this._getSoundState(util.target);
|
||||
return soundState.volume;
|
||||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.setTempo = function (args) {
|
||||
var tempo = Cast.toNumber(args.TEMPO);
|
||||
const tempo = Cast.toNumber(args.TEMPO);
|
||||
this._updateTempo(tempo);
|
||||
};
|
||||
|
||||
Scratch3SoundBlocks.prototype.changeTempo = function (args) {
|
||||
var change = Cast.toNumber(args.TEMPO);
|
||||
const change = Cast.toNumber(args.TEMPO);
|
||||
if (typeof this.runtime.audioEngine === 'undefined') return;
|
||||
var tempo = change + this.runtime.audioEngine.currentTempo;
|
||||
const tempo = change + this.runtime.audioEngine.currentTempo;
|
||||
this._updateTempo(tempo);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var mutationAdapter = require('./mutation-adapter');
|
||||
var html = require('htmlparser2');
|
||||
const mutationAdapter = require('./mutation-adapter');
|
||||
const html = require('htmlparser2');
|
||||
|
||||
/**
|
||||
* Convert outer blocks DOM from a Blockly CREATE event
|
||||
|
@ -8,22 +8,22 @@ var html = require('htmlparser2');
|
|||
* @param {Element} blocksDOM DOM tree for this event.
|
||||
* @return {Array.<object>} Usable list of blocks from this CREATE event.
|
||||
*/
|
||||
var domToBlocks = function (blocksDOM) {
|
||||
const domToBlocks = function (blocksDOM) {
|
||||
// At this level, there could be multiple blocks adjacent in the DOM tree.
|
||||
var blocks = {};
|
||||
for (var i = 0; i < blocksDOM.length; i++) {
|
||||
var block = blocksDOM[i];
|
||||
const blocks = {};
|
||||
for (let i = 0; i < blocksDOM.length; i++) {
|
||||
const block = blocksDOM[i];
|
||||
if (!block.name || !block.attribs) {
|
||||
continue;
|
||||
}
|
||||
var tagName = block.name.toLowerCase();
|
||||
const tagName = block.name.toLowerCase();
|
||||
if (tagName === 'block' || tagName === 'shadow') {
|
||||
domToBlock(block, blocks, true, null);
|
||||
}
|
||||
}
|
||||
// Flatten blocks object into a list.
|
||||
var blocksList = [];
|
||||
for (var b in blocks) {
|
||||
const blocksList = [];
|
||||
for (const b in blocks) {
|
||||
if (!blocks.hasOwnProperty(b)) continue;
|
||||
blocksList.push(blocks[b]);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ var domToBlocks = function (blocksDOM) {
|
|||
* @param {object} e `Blockly.events.create`
|
||||
* @return {Array.<object>} List of blocks from this CREATE event.
|
||||
*/
|
||||
var adapter = function (e) {
|
||||
const adapter = function (e) {
|
||||
// Validate input
|
||||
if (typeof e !== 'object') return;
|
||||
if (typeof e.xml !== 'object') return;
|
||||
|
@ -55,7 +55,7 @@ var adapter = function (e) {
|
|||
*/
|
||||
var domToBlock = function (blockDOM, blocks, isTopBlock, parent) {
|
||||
// Block skeleton.
|
||||
var block = {
|
||||
const block = {
|
||||
id: blockDOM.attribs.id, // Block ID
|
||||
opcode: blockDOM.attribs.type, // For execution, "event_whengreenflag".
|
||||
inputs: {}, // Inputs to this block and the blocks they point to.
|
||||
|
@ -72,18 +72,18 @@ var domToBlock = function (blockDOM, blocks, isTopBlock, parent) {
|
|||
blocks[block.id] = block;
|
||||
|
||||
// Process XML children and find enclosed blocks, fields, etc.
|
||||
for (var i = 0; i < blockDOM.children.length; i++) {
|
||||
var xmlChild = blockDOM.children[i];
|
||||
for (let i = 0; i < blockDOM.children.length; i++) {
|
||||
const xmlChild = blockDOM.children[i];
|
||||
// Enclosed blocks and shadows
|
||||
var childBlockNode = null;
|
||||
var childShadowNode = null;
|
||||
for (var j = 0; j < xmlChild.children.length; j++) {
|
||||
var grandChildNode = xmlChild.children[j];
|
||||
let childBlockNode = null;
|
||||
let childShadowNode = null;
|
||||
for (let j = 0; j < xmlChild.children.length; j++) {
|
||||
const grandChildNode = xmlChild.children[j];
|
||||
if (!grandChildNode.name) {
|
||||
// Non-XML tag node.
|
||||
continue;
|
||||
}
|
||||
var grandChildNodeName = grandChildNode.name.toLowerCase();
|
||||
const grandChildNodeName = grandChildNode.name.toLowerCase();
|
||||
if (grandChildNodeName === 'block') {
|
||||
childBlockNode = grandChildNode;
|
||||
} else if (grandChildNodeName === 'shadow') {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var adapter = require('./adapter');
|
||||
var mutationAdapter = require('./mutation-adapter');
|
||||
var xmlEscape = require('../util/xml-escape');
|
||||
const adapter = require('./adapter');
|
||||
const mutationAdapter = require('./mutation-adapter');
|
||||
const xmlEscape = require('../util/xml-escape');
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
|
@ -8,7 +8,7 @@ var xmlEscape = require('../util/xml-escape');
|
|||
* and handle updates from Scratch Blocks events.
|
||||
*/
|
||||
|
||||
var Blocks = function () {
|
||||
const Blocks = function () {
|
||||
/**
|
||||
* All blocks in the workspace.
|
||||
* Keys are block IDs, values are metadata about the block.
|
||||
|
@ -54,7 +54,7 @@ Blocks.prototype.getScripts = function () {
|
|||
* @return {?string} ID of next block in the sequence
|
||||
*/
|
||||
Blocks.prototype.getNextBlock = function (id) {
|
||||
var block = this._blocks[id];
|
||||
const block = this._blocks[id];
|
||||
return (typeof block === 'undefined') ? null : block.next;
|
||||
};
|
||||
|
||||
|
@ -65,17 +65,17 @@ Blocks.prototype.getNextBlock = function (id) {
|
|||
* @return {?string} ID of block in the branch.
|
||||
*/
|
||||
Blocks.prototype.getBranch = function (id, branchNum) {
|
||||
var block = this._blocks[id];
|
||||
const block = this._blocks[id];
|
||||
if (typeof block === 'undefined') return null;
|
||||
if (!branchNum) branchNum = 1;
|
||||
|
||||
var inputName = Blocks.BRANCH_INPUT_PREFIX;
|
||||
let inputName = Blocks.BRANCH_INPUT_PREFIX;
|
||||
if (branchNum > 1) {
|
||||
inputName += branchNum;
|
||||
}
|
||||
|
||||
// Empty C-block?
|
||||
var input = block.inputs[inputName];
|
||||
const input = block.inputs[inputName];
|
||||
return (typeof input === 'undefined') ? null : input.block;
|
||||
};
|
||||
|
||||
|
@ -104,8 +104,8 @@ Blocks.prototype.getFields = function (block) {
|
|||
*/
|
||||
Blocks.prototype.getInputs = function (block) {
|
||||
if (typeof block === 'undefined') return null;
|
||||
var inputs = {};
|
||||
for (var input in block.inputs) {
|
||||
const inputs = {};
|
||||
for (const input in block.inputs) {
|
||||
// Ignore blocks prefixed with branch prefix.
|
||||
if (input.substring(0, Blocks.BRANCH_INPUT_PREFIX.length) !==
|
||||
Blocks.BRANCH_INPUT_PREFIX) {
|
||||
|
@ -130,7 +130,7 @@ Blocks.prototype.getMutation = function (block) {
|
|||
* @return {?string} ID of top-level script block.
|
||||
*/
|
||||
Blocks.prototype.getTopLevelScript = function (id) {
|
||||
var block = this._blocks[id];
|
||||
let block = this._blocks[id];
|
||||
if (typeof block === 'undefined') return null;
|
||||
while (block.parent !== null) {
|
||||
block = this._blocks[block.parent];
|
||||
|
@ -144,9 +144,9 @@ Blocks.prototype.getTopLevelScript = function (id) {
|
|||
* @return {?string} ID of procedure definition.
|
||||
*/
|
||||
Blocks.prototype.getProcedureDefinition = function (name) {
|
||||
for (var id in this._blocks) {
|
||||
for (const id in this._blocks) {
|
||||
if (!this._blocks.hasOwnProperty(id)) continue;
|
||||
var block = this._blocks[id];
|
||||
const block = this._blocks[id];
|
||||
if ((block.opcode === 'procedures_defnoreturn' ||
|
||||
block.opcode === 'procedures_defreturn') &&
|
||||
block.mutation.proccode === name) {
|
||||
|
@ -162,9 +162,9 @@ Blocks.prototype.getProcedureDefinition = function (name) {
|
|||
* @return {?string} ID of procedure definition.
|
||||
*/
|
||||
Blocks.prototype.getProcedureParamNames = function (name) {
|
||||
for (var id in this._blocks) {
|
||||
for (const id in this._blocks) {
|
||||
if (!this._blocks.hasOwnProperty(id)) continue;
|
||||
var block = this._blocks[id];
|
||||
const block = this._blocks[id];
|
||||
if ((block.opcode === 'procedures_defnoreturn' ||
|
||||
block.opcode === 'procedures_defreturn') &&
|
||||
block.mutation.proccode === name) {
|
||||
|
@ -201,7 +201,7 @@ Blocks.prototype.blocklyListen = function (e, optRuntime) {
|
|||
case 'create':
|
||||
var newBlocks = adapter(e);
|
||||
// A create event can create many blocks. Add them all.
|
||||
for (var i = 0; i < newBlocks.length; i++) {
|
||||
for (let i = 0; i < newBlocks.length; i++) {
|
||||
this.createBlock(newBlocks[i]);
|
||||
}
|
||||
break;
|
||||
|
@ -270,7 +270,7 @@ Blocks.prototype.createBlock = function (block) {
|
|||
Blocks.prototype.changeBlock = function (args) {
|
||||
// Validate
|
||||
if (args.element !== 'field' && args.element !== 'mutation') return;
|
||||
var block = this._blocks[args.id];
|
||||
const block = this._blocks[args.id];
|
||||
if (typeof block === 'undefined') return;
|
||||
|
||||
if (args.element === 'field') {
|
||||
|
@ -299,7 +299,7 @@ Blocks.prototype.moveBlock = function (e) {
|
|||
|
||||
// Remove from any old parent.
|
||||
if (typeof e.oldParent !== 'undefined') {
|
||||
var oldParent = this._blocks[e.oldParent];
|
||||
const oldParent = this._blocks[e.oldParent];
|
||||
if (typeof e.oldInput !== 'undefined' &&
|
||||
oldParent.inputs[e.oldInput].block === e.id) {
|
||||
// This block was connected to the old parent's input.
|
||||
|
@ -324,7 +324,7 @@ Blocks.prototype.moveBlock = function (e) {
|
|||
} else {
|
||||
// Moved to the new parent's input.
|
||||
// Don't obscure the shadow block.
|
||||
var oldShadow = null;
|
||||
let oldShadow = null;
|
||||
if (this._blocks[e.newParent].inputs.hasOwnProperty(e.newInput)) {
|
||||
oldShadow = this._blocks[e.newParent].inputs[e.newInput].shadow;
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ Blocks.prototype.deleteBlock = function (e) {
|
|||
// @todo In runtime, stop threads running on this script.
|
||||
|
||||
// Get block
|
||||
var block = this._blocks[e.id];
|
||||
const block = this._blocks[e.id];
|
||||
|
||||
// Delete children
|
||||
if (block.next !== null) {
|
||||
|
@ -354,7 +354,7 @@ Blocks.prototype.deleteBlock = function (e) {
|
|||
}
|
||||
|
||||
// Delete inputs (including branches)
|
||||
for (var input in block.inputs) {
|
||||
for (const input in block.inputs) {
|
||||
// If it's null, the block in this input moved away.
|
||||
if (block.inputs[input].block !== null) {
|
||||
this.deleteBlock({id: block.inputs[input].block});
|
||||
|
@ -381,11 +381,11 @@ Blocks.prototype.deleteBlock = function (e) {
|
|||
* @return {string} String of XML representing this object's blocks.
|
||||
*/
|
||||
Blocks.prototype.toXML = function () {
|
||||
var xmlString = '<xml xmlns="http://www.w3.org/1999/xhtml">';
|
||||
for (var i = 0; i < this._scripts.length; i++) {
|
||||
let xmlString = '<xml xmlns="http://www.w3.org/1999/xhtml">';
|
||||
for (let i = 0; i < this._scripts.length; i++) {
|
||||
xmlString += this.blockToXML(this._scripts[i]);
|
||||
}
|
||||
return xmlString + '</xml>';
|
||||
return `${xmlString}</xml>`;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -395,29 +395,29 @@ Blocks.prototype.toXML = function () {
|
|||
* @return {string} String of XML representing this block and any children.
|
||||
*/
|
||||
Blocks.prototype.blockToXML = function (blockId) {
|
||||
var block = this._blocks[blockId];
|
||||
const block = this._blocks[blockId];
|
||||
// Encode properties of this block.
|
||||
var tagName = (block.shadow) ? 'shadow' : 'block';
|
||||
var xy = (block.topLevel) ?
|
||||
' x="' + block.x + '" y="' + block.y + '"' :
|
||||
const tagName = (block.shadow) ? 'shadow' : 'block';
|
||||
const xy = (block.topLevel) ?
|
||||
` x="${block.x}" y="${block.y}"` :
|
||||
'';
|
||||
var xmlString = '';
|
||||
xmlString += '<' + tagName +
|
||||
' id="' + block.id + '"' +
|
||||
' type="' + block.opcode + '"' +
|
||||
xy +
|
||||
'>';
|
||||
let xmlString = '';
|
||||
xmlString += `<${tagName
|
||||
} id="${block.id}"` +
|
||||
` type="${block.opcode}"${
|
||||
xy
|
||||
}>`;
|
||||
// Add any mutation. Must come before inputs.
|
||||
if (block.mutation) {
|
||||
xmlString += this.mutationToXML(block.mutation);
|
||||
}
|
||||
// Add any inputs on this block.
|
||||
for (var input in block.inputs) {
|
||||
for (const input in block.inputs) {
|
||||
if (!block.inputs.hasOwnProperty(input)) continue;
|
||||
var blockInput = block.inputs[input];
|
||||
const blockInput = block.inputs[input];
|
||||
// Only encode a value tag if the value input is occupied.
|
||||
if (blockInput.block || blockInput.shadow) {
|
||||
xmlString += '<value name="' + blockInput.name + '">';
|
||||
xmlString += `<value name="${blockInput.name}">`;
|
||||
if (blockInput.block) {
|
||||
xmlString += this.blockToXML(blockInput.block);
|
||||
}
|
||||
|
@ -429,21 +429,21 @@ Blocks.prototype.blockToXML = function (blockId) {
|
|||
}
|
||||
}
|
||||
// Add any fields on this block.
|
||||
for (var field in block.fields) {
|
||||
for (const field in block.fields) {
|
||||
if (!block.fields.hasOwnProperty(field)) continue;
|
||||
var blockField = block.fields[field];
|
||||
var value = blockField.value;
|
||||
const blockField = block.fields[field];
|
||||
let value = blockField.value;
|
||||
if (typeof value === 'string') {
|
||||
value = xmlEscape(blockField.value);
|
||||
}
|
||||
xmlString += '<field name="' + blockField.name + '">' +
|
||||
value + '</field>';
|
||||
xmlString += `<field name="${blockField.name}">${
|
||||
value}</field>`;
|
||||
}
|
||||
// Add blocks connected to the next connection.
|
||||
if (block.next) {
|
||||
xmlString += '<next>' + this.blockToXML(block.next) + '</next>';
|
||||
xmlString += `<next>${this.blockToXML(block.next)}</next>`;
|
||||
}
|
||||
xmlString += '</' + tagName + '>';
|
||||
xmlString += `</${tagName}>`;
|
||||
return xmlString;
|
||||
};
|
||||
|
||||
|
@ -453,18 +453,18 @@ Blocks.prototype.blockToXML = function (blockId) {
|
|||
* @return {string} XML string representing a mutation.
|
||||
*/
|
||||
Blocks.prototype.mutationToXML = function (mutation) {
|
||||
var mutationString = '<' + mutation.tagName;
|
||||
for (var prop in mutation) {
|
||||
let mutationString = `<${mutation.tagName}`;
|
||||
for (const prop in mutation) {
|
||||
if (prop === 'children' || prop === 'tagName') continue;
|
||||
var mutationValue = (typeof mutation[prop] === 'string') ?
|
||||
const mutationValue = (typeof mutation[prop] === 'string') ?
|
||||
xmlEscape(mutation[prop]) : mutation[prop];
|
||||
mutationString += ' ' + prop + '="' + mutationValue + '"';
|
||||
mutationString += ` ${prop}="${mutationValue}"`;
|
||||
}
|
||||
mutationString += '>';
|
||||
for (var i = 0; i < mutation.children.length; i++) {
|
||||
for (let i = 0; i < mutation.children.length; i++) {
|
||||
mutationString += this.mutationToXML(mutation.children[i]);
|
||||
}
|
||||
mutationString += '</' + mutation.tagName + '>';
|
||||
mutationString += `</${mutation.tagName}>`;
|
||||
return mutationString;
|
||||
};
|
||||
|
||||
|
@ -475,7 +475,7 @@ Blocks.prototype.mutationToXML = function (mutation) {
|
|||
* @param {?string} topBlockId ID of block that starts the script.
|
||||
*/
|
||||
Blocks.prototype._addScript = function (topBlockId) {
|
||||
var i = this._scripts.indexOf(topBlockId);
|
||||
const i = this._scripts.indexOf(topBlockId);
|
||||
if (i > -1) return; // Already in scripts.
|
||||
this._scripts.push(topBlockId);
|
||||
// Update `topLevel` property on the top block.
|
||||
|
@ -487,7 +487,7 @@ Blocks.prototype._addScript = function (topBlockId) {
|
|||
* @param {?string} topBlockId ID of block that starts the script.
|
||||
*/
|
||||
Blocks.prototype._deleteScript = function (topBlockId) {
|
||||
var i = this._scripts.indexOf(topBlockId);
|
||||
const i = this._scripts.indexOf(topBlockId);
|
||||
if (i > -1) this._scripts.splice(i, 1);
|
||||
// Update `topLevel` property on the top block.
|
||||
if (this._blocks[topBlockId]) this._blocks[topBlockId].topLevel = false;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
var log = require('../util/log');
|
||||
var Thread = require('./thread');
|
||||
const log = require('../util/log');
|
||||
const Thread = require('./thread');
|
||||
|
||||
/**
|
||||
* Utility function to determine if a value is a Promise.
|
||||
* @param {*} value Value to check for a Promise.
|
||||
* @return {boolean} True if the value appears to be a Promise.
|
||||
*/
|
||||
var isPromise = function (value) {
|
||||
const isPromise = function (value) {
|
||||
return value && value.then && typeof value.then === 'function';
|
||||
};
|
||||
|
||||
|
@ -16,8 +16,8 @@ var isPromise = function (value) {
|
|||
* @param {!Thread} thread Thread which to read and execute.
|
||||
*/
|
||||
var execute = function (sequencer, thread) {
|
||||
var runtime = sequencer.runtime;
|
||||
var target = thread.target;
|
||||
const runtime = sequencer.runtime;
|
||||
const target = thread.target;
|
||||
|
||||
// Stop if block or target no longer exists.
|
||||
if (target === null) {
|
||||
|
@ -27,11 +27,11 @@ var execute = function (sequencer, thread) {
|
|||
}
|
||||
|
||||
// Current block to execute is the one on the top of the stack.
|
||||
var currentBlockId = thread.peekStack();
|
||||
var currentStackFrame = thread.peekStackFrame();
|
||||
const currentBlockId = thread.peekStack();
|
||||
const currentStackFrame = thread.peekStackFrame();
|
||||
|
||||
var blockContainer = target.blocks;
|
||||
var block = blockContainer.getBlock(currentBlockId);
|
||||
let blockContainer = target.blocks;
|
||||
let block = blockContainer.getBlock(currentBlockId);
|
||||
if (typeof block === 'undefined') {
|
||||
blockContainer = runtime.flyoutBlocks;
|
||||
block = blockContainer.getBlock(currentBlockId);
|
||||
|
@ -43,15 +43,15 @@ var execute = function (sequencer, thread) {
|
|||
}
|
||||
}
|
||||
|
||||
var opcode = blockContainer.getOpcode(block);
|
||||
var fields = blockContainer.getFields(block);
|
||||
var inputs = blockContainer.getInputs(block);
|
||||
var blockFunction = runtime.getOpcodeFunction(opcode);
|
||||
var isHat = runtime.getIsHat(opcode);
|
||||
const opcode = blockContainer.getOpcode(block);
|
||||
const fields = blockContainer.getFields(block);
|
||||
const inputs = blockContainer.getInputs(block);
|
||||
const blockFunction = runtime.getOpcodeFunction(opcode);
|
||||
const isHat = runtime.getIsHat(opcode);
|
||||
|
||||
|
||||
if (!opcode) {
|
||||
log.warn('Could not get opcode for block: ' + currentBlockId);
|
||||
log.warn(`Could not get opcode for block: ${currentBlockId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -60,18 +60,18 @@ var execute = function (sequencer, thread) {
|
|||
* or after a promise resolves.
|
||||
* @param {*} resolvedValue Value eventually returned from the primitive.
|
||||
*/
|
||||
var handleReport = function (resolvedValue) {
|
||||
const handleReport = function (resolvedValue) {
|
||||
thread.pushReportedValue(resolvedValue);
|
||||
if (isHat) {
|
||||
// Hat predicate was evaluated.
|
||||
if (runtime.getIsEdgeActivatedHat(opcode)) {
|
||||
// If this is an edge-activated hat, only proceed if
|
||||
// the value is true and used to be false.
|
||||
var oldEdgeValue = runtime.updateEdgeActivatedValue(
|
||||
const oldEdgeValue = runtime.updateEdgeActivatedValue(
|
||||
currentBlockId,
|
||||
resolvedValue
|
||||
);
|
||||
var edgeWasActivated = !oldEdgeValue && resolvedValue;
|
||||
const edgeWasActivated = !oldEdgeValue && resolvedValue;
|
||||
if (!edgeWasActivated) {
|
||||
sequencer.retireThread(thread);
|
||||
}
|
||||
|
@ -104,31 +104,31 @@ var execute = function (sequencer, thread) {
|
|||
// Skip through the block (hat with no predicate).
|
||||
return;
|
||||
}
|
||||
var keys = Object.keys(fields);
|
||||
const keys = Object.keys(fields);
|
||||
if (keys.length === 1 && Object.keys(inputs).length === 0) {
|
||||
// One field and no inputs - treat as arg.
|
||||
handleReport(fields[keys[0]].value);
|
||||
} else {
|
||||
log.warn('Could not get implementation for opcode: ' + opcode);
|
||||
log.warn(`Could not get implementation for opcode: ${opcode}`);
|
||||
}
|
||||
thread.requestScriptGlowInFrame = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate values for arguments (inputs).
|
||||
var argValues = {};
|
||||
const argValues = {};
|
||||
|
||||
// Add all fields on this block to the argValues.
|
||||
for (var fieldName in fields) {
|
||||
for (const fieldName in fields) {
|
||||
if (!fields.hasOwnProperty(fieldName)) continue;
|
||||
argValues[fieldName] = fields[fieldName].value;
|
||||
}
|
||||
|
||||
// Recursively evaluate input blocks.
|
||||
for (var inputName in inputs) {
|
||||
for (const inputName in inputs) {
|
||||
if (!inputs.hasOwnProperty(inputName)) continue;
|
||||
var input = inputs[inputName];
|
||||
var inputBlockId = input.block;
|
||||
const input = inputs[inputName];
|
||||
const inputBlockId = input.block;
|
||||
// Is there no value for this input waiting in the stack frame?
|
||||
if (inputBlockId !== null && typeof currentStackFrame.reported[inputName] === 'undefined') {
|
||||
// If there's not, we need to evaluate the block.
|
||||
|
@ -151,7 +151,7 @@ var execute = function (sequencer, thread) {
|
|||
}
|
||||
|
||||
// Add any mutation to args (e.g., for procedures).
|
||||
var mutation = blockContainer.getMutation(block);
|
||||
const mutation = blockContainer.getMutation(block);
|
||||
if (mutation !== null) {
|
||||
argValues.mutation = mutation;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ var execute = function (sequencer, thread) {
|
|||
// (e.g., on return from a branch) gets fresh inputs.
|
||||
currentStackFrame.reported = {};
|
||||
|
||||
var primitiveReportedValue = null;
|
||||
let primitiveReportedValue = null;
|
||||
primitiveReportedValue = blockFunction(argValues, {
|
||||
stackFrame: currentStackFrame.executionContext,
|
||||
target: target,
|
||||
|
@ -201,7 +201,7 @@ var execute = function (sequencer, thread) {
|
|||
ioQuery: function (device, func, args) {
|
||||
// Find the I/O device and execute the query/function call.
|
||||
if (runtime.ioDevices[device] && runtime.ioDevices[device][func]) {
|
||||
var devObject = runtime.ioDevices[device];
|
||||
const devObject = runtime.ioDevices[device];
|
||||
// @todo Figure out why eslint complains about no-useless-call
|
||||
// no-useless-call can't tell if the call is useless for dynamic
|
||||
// expressions... or something. Not exactly sure why it
|
||||
|
@ -225,13 +225,13 @@ var execute = function (sequencer, thread) {
|
|||
thread.status = Thread.STATUS_PROMISE_WAIT;
|
||||
}
|
||||
// Promise handlers
|
||||
primitiveReportedValue.then(function (resolvedValue) {
|
||||
primitiveReportedValue.then(resolvedValue => {
|
||||
handleReport(resolvedValue);
|
||||
if (typeof resolvedValue === 'undefined') {
|
||||
do {
|
||||
// In the case that the promise is the last block in the current thread stack
|
||||
// We need to pop out repeatedly until we find the next block.
|
||||
var popped = thread.popStack();
|
||||
const popped = thread.popStack();
|
||||
if (popped === null) {
|
||||
return;
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ var execute = function (sequencer, thread) {
|
|||
} else {
|
||||
thread.popStack();
|
||||
}
|
||||
}, function (rejectionReason) {
|
||||
}, rejectionReason => {
|
||||
// Promise rejected: the primitive had some error.
|
||||
// Log it and proceed.
|
||||
log.warn('Primitive rejected promise: ', rejectionReason);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* @param {Array} contents Contents of the list, as an array.
|
||||
* @constructor
|
||||
*/
|
||||
var List = function (name, contents) {
|
||||
const List = function (name, contents) {
|
||||
this.name = name;
|
||||
this.contents = contents;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var html = require('htmlparser2');
|
||||
const html = require('htmlparser2');
|
||||
|
||||
/**
|
||||
* Convert a part of a mutation DOM to a mutation VM object, recursively.
|
||||
|
@ -6,14 +6,14 @@ var html = require('htmlparser2');
|
|||
* @return {object} Object representing useful parts of this mutation.
|
||||
*/
|
||||
var mutatorTagToObject = function (dom) {
|
||||
var obj = Object.create(null);
|
||||
const obj = Object.create(null);
|
||||
obj.tagName = dom.name;
|
||||
obj.children = [];
|
||||
for (var prop in dom.attribs) {
|
||||
for (const prop in dom.attribs) {
|
||||
if (prop === 'xmlns') continue;
|
||||
obj[prop] = dom.attribs[prop];
|
||||
}
|
||||
for (var i = 0; i < dom.children.length; i++) {
|
||||
for (let i = 0; i < dom.children.length; i++) {
|
||||
obj.children.push(
|
||||
mutatorTagToObject(dom.children[i])
|
||||
);
|
||||
|
@ -27,8 +27,8 @@ var mutatorTagToObject = function (dom) {
|
|||
* @param {(object|string)} mutation Mutation XML string or DOM.
|
||||
* @return {object} Object representing the mutation.
|
||||
*/
|
||||
var mutationAdpater = function (mutation) {
|
||||
var mutationParsed;
|
||||
const mutationAdpater = function (mutation) {
|
||||
let mutationParsed;
|
||||
// Check if the mutation is already parsed; if not, parse it.
|
||||
if (typeof mutation === 'object') {
|
||||
mutationParsed = mutation;
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
var EventEmitter = require('events');
|
||||
var Sequencer = require('./sequencer');
|
||||
var Blocks = require('./blocks');
|
||||
var Thread = require('./thread');
|
||||
var util = require('util');
|
||||
const EventEmitter = require('events');
|
||||
const Sequencer = require('./sequencer');
|
||||
const Blocks = require('./blocks');
|
||||
const Thread = require('./thread');
|
||||
const util = require('util');
|
||||
|
||||
// Virtual I/O devices.
|
||||
var Clock = require('../io/clock');
|
||||
var Keyboard = require('../io/keyboard');
|
||||
var Mouse = require('../io/mouse');
|
||||
const Clock = require('../io/clock');
|
||||
const Keyboard = require('../io/keyboard');
|
||||
const Mouse = require('../io/mouse');
|
||||
|
||||
var defaultBlockPackages = {
|
||||
const defaultBlockPackages = {
|
||||
scratch3_control: require('../blocks/scratch3_control'),
|
||||
scratch3_event: require('../blocks/scratch3_event'),
|
||||
scratch3_looks: require('../blocks/scratch3_looks'),
|
||||
|
@ -26,7 +26,7 @@ var defaultBlockPackages = {
|
|||
* Manages targets, scripts, and the sequencer.
|
||||
* @constructor
|
||||
*/
|
||||
var Runtime = function () {
|
||||
const Runtime = function () {
|
||||
// Bind event emitter
|
||||
EventEmitter.call(this);
|
||||
|
||||
|
@ -237,14 +237,14 @@ Runtime.MAX_CLONES = 300;
|
|||
* @private
|
||||
*/
|
||||
Runtime.prototype._registerBlockPackages = function () {
|
||||
for (var packageName in defaultBlockPackages) {
|
||||
for (const packageName in defaultBlockPackages) {
|
||||
if (defaultBlockPackages.hasOwnProperty(packageName)) {
|
||||
// @todo pass a different runtime depending on package privilege?
|
||||
var packageObject = new (defaultBlockPackages[packageName])(this);
|
||||
const packageObject = new (defaultBlockPackages[packageName])(this);
|
||||
// Collect primitives from package.
|
||||
if (packageObject.getPrimitives) {
|
||||
var packagePrimitives = packageObject.getPrimitives();
|
||||
for (var op in packagePrimitives) {
|
||||
const packagePrimitives = packageObject.getPrimitives();
|
||||
for (const op in packagePrimitives) {
|
||||
if (packagePrimitives.hasOwnProperty(op)) {
|
||||
this._primitives[op] =
|
||||
packagePrimitives[op].bind(packageObject);
|
||||
|
@ -253,8 +253,8 @@ Runtime.prototype._registerBlockPackages = function () {
|
|||
}
|
||||
// Collect hat metadata from package.
|
||||
if (packageObject.getHats) {
|
||||
var packageHats = packageObject.getHats();
|
||||
for (var hatName in packageHats) {
|
||||
const packageHats = packageObject.getHats();
|
||||
for (const hatName in packageHats) {
|
||||
if (packageHats.hasOwnProperty(hatName)) {
|
||||
this._hats[hatName] = packageHats[hatName];
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ Runtime.prototype.getIsEdgeActivatedHat = function (opcode) {
|
|||
* @return {*} The old value for the edge-activated hat.
|
||||
*/
|
||||
Runtime.prototype.updateEdgeActivatedValue = function (blockId, newValue) {
|
||||
var oldValue = this._edgeActivatedHatValues[blockId];
|
||||
const oldValue = this._edgeActivatedHatValues[blockId];
|
||||
this._edgeActivatedHatValues[blockId] = newValue;
|
||||
return oldValue;
|
||||
};
|
||||
|
@ -345,7 +345,7 @@ Runtime.prototype.attachStorage = function (storage) {
|
|||
* @return {!Thread} The newly created thread.
|
||||
*/
|
||||
Runtime.prototype._pushThread = function (id, target) {
|
||||
var thread = new Thread(id);
|
||||
const thread = new Thread(id);
|
||||
thread.target = target;
|
||||
thread.pushStack(id);
|
||||
this.threads.push(thread);
|
||||
|
@ -360,7 +360,7 @@ Runtime.prototype._removeThread = function (thread) {
|
|||
// Inform sequencer to stop executing that thread.
|
||||
this.sequencer.retireThread(thread);
|
||||
// Remove from the list.
|
||||
var i = this.threads.indexOf(thread);
|
||||
const i = this.threads.indexOf(thread);
|
||||
if (i > -1) {
|
||||
this.threads.splice(i, 1);
|
||||
}
|
||||
|
@ -373,10 +373,10 @@ Runtime.prototype._removeThread = function (thread) {
|
|||
* @param {!Thread} thread Thread object to restart.
|
||||
*/
|
||||
Runtime.prototype._restartThread = function (thread) {
|
||||
var newThread = new Thread(thread.topBlock);
|
||||
const newThread = new Thread(thread.topBlock);
|
||||
newThread.target = thread.target;
|
||||
newThread.pushStack(thread.topBlock);
|
||||
var i = this.threads.indexOf(thread);
|
||||
const i = this.threads.indexOf(thread);
|
||||
if (i > -1) {
|
||||
this.threads[i] = newThread;
|
||||
} else {
|
||||
|
@ -399,7 +399,7 @@ Runtime.prototype.isActiveThread = function (thread) {
|
|||
*/
|
||||
Runtime.prototype.toggleScript = function (topBlockId) {
|
||||
// Remove any existing thread.
|
||||
for (var i = 0; i < this.threads.length; i++) {
|
||||
for (let i = 0; i < this.threads.length; i++) {
|
||||
if (this.threads[i].topBlock === topBlockId) {
|
||||
this._removeThread(this.threads[i]);
|
||||
return;
|
||||
|
@ -418,15 +418,15 @@ Runtime.prototype.toggleScript = function (topBlockId) {
|
|||
* @param {Target=} optTarget Optionally, a target to restrict to.
|
||||
*/
|
||||
Runtime.prototype.allScriptsDo = function (f, optTarget) {
|
||||
var targets = this.targets;
|
||||
let targets = this.targets;
|
||||
if (optTarget) {
|
||||
targets = [optTarget];
|
||||
}
|
||||
for (var t = targets.length - 1; t >= 0; t--) {
|
||||
var target = targets[t];
|
||||
var scripts = target.blocks.getScripts();
|
||||
for (var j = 0; j < scripts.length; j++) {
|
||||
var topBlockId = scripts[j];
|
||||
for (let t = targets.length - 1; t >= 0; t--) {
|
||||
const target = targets[t];
|
||||
const scripts = target.blocks.getScripts();
|
||||
for (let j = 0; j < scripts.length; j++) {
|
||||
const topBlockId = scripts[j];
|
||||
f(topBlockId, target);
|
||||
}
|
||||
}
|
||||
|
@ -445,19 +445,19 @@ Runtime.prototype.startHats = function (requestedHatOpcode,
|
|||
// No known hat with this opcode.
|
||||
return;
|
||||
}
|
||||
var instance = this;
|
||||
var newThreads = [];
|
||||
const instance = this;
|
||||
const newThreads = [];
|
||||
|
||||
for (var opts in optMatchFields) {
|
||||
for (const opts in optMatchFields) {
|
||||
if (!optMatchFields.hasOwnProperty(opts)) continue;
|
||||
optMatchFields[opts] = optMatchFields[opts].toUpperCase();
|
||||
}
|
||||
|
||||
// Consider all scripts, looking for hats with opcode `requestedHatOpcode`.
|
||||
this.allScriptsDo(function (topBlockId, target) {
|
||||
var blocks = target.blocks;
|
||||
var block = blocks.getBlock(topBlockId);
|
||||
var potentialHatOpcode = block.opcode;
|
||||
this.allScriptsDo((topBlockId, target) => {
|
||||
const blocks = target.blocks;
|
||||
const block = blocks.getBlock(topBlockId);
|
||||
const potentialHatOpcode = block.opcode;
|
||||
if (potentialHatOpcode !== requestedHatOpcode) {
|
||||
// Not the right hat.
|
||||
return;
|
||||
|
@ -468,22 +468,22 @@ Runtime.prototype.startHats = function (requestedHatOpcode,
|
|||
// This needs to happen before the block is evaluated
|
||||
// (i.e., before the predicate can be run) because "broadcast and wait"
|
||||
// needs to have a precise collection of started threads.
|
||||
var hatFields = blocks.getFields(block);
|
||||
let hatFields = blocks.getFields(block);
|
||||
|
||||
// If no fields are present, check inputs (horizontal blocks)
|
||||
if (Object.keys(hatFields).length === 0) {
|
||||
var hatInputs = blocks.getInputs(block);
|
||||
for (var input in hatInputs) {
|
||||
const hatInputs = blocks.getInputs(block);
|
||||
for (const input in hatInputs) {
|
||||
if (!hatInputs.hasOwnProperty(input)) continue;
|
||||
var id = hatInputs[input].block;
|
||||
var inpBlock = blocks.getBlock(id);
|
||||
var fields = blocks.getFields(inpBlock);
|
||||
const id = hatInputs[input].block;
|
||||
const inpBlock = blocks.getBlock(id);
|
||||
const fields = blocks.getFields(inpBlock);
|
||||
hatFields = Object.assign(fields, hatFields);
|
||||
}
|
||||
}
|
||||
|
||||
if (optMatchFields) {
|
||||
for (var matchField in optMatchFields) {
|
||||
for (const matchField in optMatchFields) {
|
||||
if (hatFields[matchField].value.toUpperCase() !==
|
||||
optMatchFields[matchField]) {
|
||||
// Field mismatch.
|
||||
|
@ -493,11 +493,11 @@ Runtime.prototype.startHats = function (requestedHatOpcode,
|
|||
}
|
||||
|
||||
// Look up metadata for the relevant hat.
|
||||
var hatMeta = instance._hats[requestedHatOpcode];
|
||||
const hatMeta = instance._hats[requestedHatOpcode];
|
||||
if (hatMeta.restartExistingThreads) {
|
||||
// If `restartExistingThreads` is true, we should stop
|
||||
// any existing threads starting with the top block.
|
||||
for (var i = 0; i < instance.threads.length; i++) {
|
||||
for (let i = 0; i < instance.threads.length; i++) {
|
||||
if (instance.threads[i].topBlock === topBlockId &&
|
||||
instance.threads[i].target === target) {
|
||||
instance._restartThread(instance.threads[i]);
|
||||
|
@ -507,7 +507,7 @@ Runtime.prototype.startHats = function (requestedHatOpcode,
|
|||
} else {
|
||||
// If `restartExistingThreads` is false, we should
|
||||
// give up if any threads with the top block are running.
|
||||
for (var j = 0; j < instance.threads.length; j++) {
|
||||
for (let j = 0; j < instance.threads.length; j++) {
|
||||
if (instance.threads[j].topBlock === topBlockId &&
|
||||
instance.threads[j].target === target) {
|
||||
// Some thread is already running.
|
||||
|
@ -534,7 +534,7 @@ Runtime.prototype.dispose = function () {
|
|||
* @param {!Target} disposingTarget Target to dispose of.
|
||||
*/
|
||||
Runtime.prototype.disposeTarget = function (disposingTarget) {
|
||||
this.targets = this.targets.filter(function (target) {
|
||||
this.targets = this.targets.filter(target => {
|
||||
if (disposingTarget !== target) return true;
|
||||
// Allow target to do dispose actions.
|
||||
target.dispose();
|
||||
|
@ -550,7 +550,7 @@ Runtime.prototype.disposeTarget = function (disposingTarget) {
|
|||
*/
|
||||
Runtime.prototype.stopForTarget = function (target, optThreadException) {
|
||||
// Stop any threads on the target.
|
||||
for (var i = 0; i < this.threads.length; i++) {
|
||||
for (let i = 0; i < this.threads.length; i++) {
|
||||
if (this.threads[i] === optThreadException) {
|
||||
continue;
|
||||
}
|
||||
|
@ -568,7 +568,7 @@ Runtime.prototype.greenFlag = function () {
|
|||
this.ioDevices.clock.resetProjectTimer();
|
||||
this.clearEdgeActivatedValues();
|
||||
// Inform all targets of the green flag.
|
||||
for (var i = 0; i < this.targets.length; i++) {
|
||||
for (let i = 0; i < this.targets.length; i++) {
|
||||
this.targets[i].onGreenFlag();
|
||||
}
|
||||
this.startHats('event_whenflagclicked');
|
||||
|
@ -579,8 +579,8 @@ Runtime.prototype.greenFlag = function () {
|
|||
*/
|
||||
Runtime.prototype.stopAll = function () {
|
||||
// Dispose all clones.
|
||||
var newTargets = [];
|
||||
for (var i = 0; i < this.targets.length; i++) {
|
||||
const newTargets = [];
|
||||
for (let i = 0; i < this.targets.length; i++) {
|
||||
this.targets[i].onStopAll();
|
||||
if (this.targets[i].hasOwnProperty('isOriginal') &&
|
||||
!this.targets[i].isOriginal) {
|
||||
|
@ -591,9 +591,9 @@ Runtime.prototype.stopAll = function () {
|
|||
}
|
||||
this.targets = newTargets;
|
||||
// Dispose all threads.
|
||||
var threadsCopy = this.threads.slice();
|
||||
const threadsCopy = this.threads.slice();
|
||||
while (threadsCopy.length > 0) {
|
||||
var poppedThread = threadsCopy.pop();
|
||||
const poppedThread = threadsCopy.pop();
|
||||
this._removeThread(poppedThread);
|
||||
}
|
||||
};
|
||||
|
@ -604,15 +604,15 @@ Runtime.prototype.stopAll = function () {
|
|||
*/
|
||||
Runtime.prototype._step = function () {
|
||||
// Find all edge-activated hats, and add them to threads to be evaluated.
|
||||
for (var hatType in this._hats) {
|
||||
for (const hatType in this._hats) {
|
||||
if (!this._hats.hasOwnProperty(hatType)) continue;
|
||||
var hat = this._hats[hatType];
|
||||
const hat = this._hats[hatType];
|
||||
if (hat.edgeActivated) {
|
||||
this.startHats(hatType);
|
||||
}
|
||||
}
|
||||
this.redrawRequested = false;
|
||||
var doneThreads = this.sequencer.stepThreads();
|
||||
const doneThreads = this.sequencer.stepThreads();
|
||||
this._updateGlows(doneThreads);
|
||||
this._setThreadCount(this.threads.length + doneThreads.length);
|
||||
if (this.renderer) {
|
||||
|
@ -651,23 +651,23 @@ Runtime.prototype.setCompatibilityMode = function (compatibilityModeOn) {
|
|||
* @param {Array.<Thread>=} optExtraThreads Optional list of inactive threads.
|
||||
*/
|
||||
Runtime.prototype._updateGlows = function (optExtraThreads) {
|
||||
var searchThreads = [];
|
||||
const searchThreads = [];
|
||||
searchThreads.push.apply(searchThreads, this.threads);
|
||||
if (optExtraThreads) {
|
||||
searchThreads.push.apply(searchThreads, optExtraThreads);
|
||||
}
|
||||
// Set of scripts that request a glow this frame.
|
||||
var requestedGlowsThisFrame = [];
|
||||
const requestedGlowsThisFrame = [];
|
||||
// Final set of scripts glowing during this frame.
|
||||
var finalScriptGlows = [];
|
||||
const finalScriptGlows = [];
|
||||
// Find all scripts that should be glowing.
|
||||
for (var i = 0; i < searchThreads.length; i++) {
|
||||
var thread = searchThreads[i];
|
||||
var target = thread.target;
|
||||
for (let i = 0; i < searchThreads.length; i++) {
|
||||
const thread = searchThreads[i];
|
||||
const target = thread.target;
|
||||
if (target === this._editingTarget) {
|
||||
var blockForThread = thread.blockGlowInFrame;
|
||||
const blockForThread = thread.blockGlowInFrame;
|
||||
if (thread.requestScriptGlowInFrame) {
|
||||
var script = target.blocks.getTopLevelScript(blockForThread);
|
||||
let script = target.blocks.getTopLevelScript(blockForThread);
|
||||
if (!script) {
|
||||
// Attempt to find in flyout blocks.
|
||||
script = this.flyoutBlocks.getTopLevelScript(
|
||||
|
@ -681,8 +681,8 @@ Runtime.prototype._updateGlows = function (optExtraThreads) {
|
|||
}
|
||||
}
|
||||
// Compare to previous frame.
|
||||
for (var j = 0; j < this._scriptGlowsPreviousFrame.length; j++) {
|
||||
var previousFrameGlow = this._scriptGlowsPreviousFrame[j];
|
||||
for (let j = 0; j < this._scriptGlowsPreviousFrame.length; j++) {
|
||||
const previousFrameGlow = this._scriptGlowsPreviousFrame[j];
|
||||
if (requestedGlowsThisFrame.indexOf(previousFrameGlow) < 0) {
|
||||
// Glow turned off.
|
||||
this.glowScript(previousFrameGlow, false);
|
||||
|
@ -691,8 +691,8 @@ Runtime.prototype._updateGlows = function (optExtraThreads) {
|
|||
finalScriptGlows.push(previousFrameGlow);
|
||||
}
|
||||
}
|
||||
for (var k = 0; k < requestedGlowsThisFrame.length; k++) {
|
||||
var currentFrameGlow = requestedGlowsThisFrame[k];
|
||||
for (let k = 0; k < requestedGlowsThisFrame.length; k++) {
|
||||
const currentFrameGlow = requestedGlowsThisFrame[k];
|
||||
if (this._scriptGlowsPreviousFrame.indexOf(currentFrameGlow) < 0) {
|
||||
// Glow turned on.
|
||||
this.glowScript(currentFrameGlow, true);
|
||||
|
@ -725,7 +725,7 @@ Runtime.prototype._setThreadCount = function (threadCount) {
|
|||
* @param {!string} scriptBlockId Id of top-level block in script to quiet.
|
||||
*/
|
||||
Runtime.prototype.quietGlow = function (scriptBlockId) {
|
||||
var index = this._scriptGlowsPreviousFrame.indexOf(scriptBlockId);
|
||||
const index = this._scriptGlowsPreviousFrame.indexOf(scriptBlockId);
|
||||
if (index > -1) {
|
||||
this._scriptGlowsPreviousFrame.splice(index, 1);
|
||||
}
|
||||
|
@ -782,8 +782,8 @@ Runtime.prototype.spriteInfoReport = function (target) {
|
|||
* @return {?Target} The target, if found.
|
||||
*/
|
||||
Runtime.prototype.getTargetById = function (targetId) {
|
||||
for (var i = 0; i < this.targets.length; i++) {
|
||||
var target = this.targets[i];
|
||||
for (let i = 0; i < this.targets.length; i++) {
|
||||
const target = this.targets[i];
|
||||
if (target.id === targetId) {
|
||||
return target;
|
||||
}
|
||||
|
@ -796,8 +796,8 @@ Runtime.prototype.getTargetById = function (targetId) {
|
|||
* @return {?Target} Target representing a sprite of the given name.
|
||||
*/
|
||||
Runtime.prototype.getSpriteTargetByName = function (spriteName) {
|
||||
for (var i = 0; i < this.targets.length; i++) {
|
||||
var target = this.targets[i];
|
||||
for (let i = 0; i < this.targets.length; i++) {
|
||||
const target = this.targets[i];
|
||||
if (target.sprite && target.sprite.name === spriteName) {
|
||||
return target;
|
||||
}
|
||||
|
@ -810,8 +810,8 @@ Runtime.prototype.getSpriteTargetByName = function (spriteName) {
|
|||
* @return {?Target} The target, if found
|
||||
*/
|
||||
Runtime.prototype.getTargetByDrawableId = function (drawableID) {
|
||||
for (var i = 0; i < this.targets.length; i++) {
|
||||
var target = this.targets[i];
|
||||
for (let i = 0; i < this.targets.length; i++) {
|
||||
const target = this.targets[i];
|
||||
if (target.drawableID === drawableID) return target;
|
||||
}
|
||||
};
|
||||
|
@ -837,8 +837,8 @@ Runtime.prototype.clonesAvailable = function () {
|
|||
* @return {?Target} The target, if found.
|
||||
*/
|
||||
Runtime.prototype.getTargetForStage = function () {
|
||||
for (var i = 0; i < this.targets.length; i++) {
|
||||
var target = this.targets[i];
|
||||
for (let i = 0; i < this.targets.length; i++) {
|
||||
const target = this.targets[i];
|
||||
if (target.isStage) {
|
||||
return target;
|
||||
}
|
||||
|
@ -857,14 +857,14 @@ Runtime.prototype.requestRedraw = function () {
|
|||
* Set up timers to repeatedly step in a browser.
|
||||
*/
|
||||
Runtime.prototype.start = function () {
|
||||
var interval = Runtime.THREAD_STEP_INTERVAL;
|
||||
let interval = Runtime.THREAD_STEP_INTERVAL;
|
||||
if (this.compatibilityMode) {
|
||||
interval = Runtime.THREAD_STEP_INTERVAL_COMPATIBILITY;
|
||||
}
|
||||
this.currentStepTime = interval;
|
||||
this._steppingInterval = setInterval(function () {
|
||||
this._steppingInterval = setInterval(() => {
|
||||
this._step();
|
||||
}.bind(this), interval);
|
||||
}, interval);
|
||||
};
|
||||
|
||||
module.exports = Runtime;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
var Timer = require('../util/timer');
|
||||
var Thread = require('./thread');
|
||||
var execute = require('./execute.js');
|
||||
const Timer = require('../util/timer');
|
||||
const Thread = require('./thread');
|
||||
const execute = require('./execute.js');
|
||||
|
||||
var Sequencer = function (runtime) {
|
||||
const Sequencer = function (runtime) {
|
||||
/**
|
||||
* A utility timer for timing thread sequencing.
|
||||
* @type {!Timer}
|
||||
|
@ -28,14 +28,14 @@ Sequencer.WARP_TIME = 500;
|
|||
*/
|
||||
Sequencer.prototype.stepThreads = function () {
|
||||
// Work time is 75% of the thread stepping interval.
|
||||
var WORK_TIME = 0.75 * this.runtime.currentStepTime;
|
||||
const WORK_TIME = 0.75 * this.runtime.currentStepTime;
|
||||
// Start counting toward WORK_TIME.
|
||||
this.timer.start();
|
||||
// Count of active threads.
|
||||
var numActiveThreads = Infinity;
|
||||
let numActiveThreads = Infinity;
|
||||
// Whether `stepThreads` has run through a full single tick.
|
||||
var ranFirstTick = false;
|
||||
var doneThreads = [];
|
||||
let ranFirstTick = false;
|
||||
const doneThreads = [];
|
||||
// Conditions for continuing to stepping threads:
|
||||
// 1. We must have threads in the list, and some must be active.
|
||||
// 2. Time elapsed must be less than WORK_TIME.
|
||||
|
@ -46,8 +46,8 @@ Sequencer.prototype.stepThreads = function () {
|
|||
(this.runtime.turboMode || !this.runtime.redrawRequested)) {
|
||||
numActiveThreads = 0;
|
||||
// Attempt to run each thread one time.
|
||||
for (var i = 0; i < this.runtime.threads.length; i++) {
|
||||
var activeThread = this.runtime.threads[i];
|
||||
for (let i = 0; i < this.runtime.threads.length; i++) {
|
||||
const activeThread = this.runtime.threads[i];
|
||||
if (activeThread.stack.length === 0 ||
|
||||
activeThread.status === Thread.STATUS_DONE) {
|
||||
// Finished with this thread.
|
||||
|
@ -76,7 +76,7 @@ Sequencer.prototype.stepThreads = function () {
|
|||
ranFirstTick = true;
|
||||
}
|
||||
// Filter inactive threads from `this.runtime.threads`.
|
||||
this.runtime.threads = this.runtime.threads.filter(function (thread) {
|
||||
this.runtime.threads = this.runtime.threads.filter(thread => {
|
||||
if (doneThreads.indexOf(thread) > -1) {
|
||||
return false;
|
||||
}
|
||||
|
@ -90,13 +90,13 @@ Sequencer.prototype.stepThreads = function () {
|
|||
* @param {!Thread} thread Thread object to step.
|
||||
*/
|
||||
Sequencer.prototype.stepThread = function (thread) {
|
||||
var currentBlockId = thread.peekStack();
|
||||
let currentBlockId = thread.peekStack();
|
||||
if (!currentBlockId) {
|
||||
// A "null block" - empty branch.
|
||||
thread.popStack();
|
||||
}
|
||||
while (thread.peekStack()) {
|
||||
var isWarpMode = thread.peekStackFrame().warpMode;
|
||||
let isWarpMode = thread.peekStackFrame().warpMode;
|
||||
if (isWarpMode && !thread.warpTimer) {
|
||||
// Initialize warp-mode timer if it hasn't been already.
|
||||
// This will start counting the thread toward `Sequencer.WARP_TIME`.
|
||||
|
@ -138,7 +138,7 @@ Sequencer.prototype.stepThread = function (thread) {
|
|||
return;
|
||||
}
|
||||
|
||||
var stackFrame = thread.peekStackFrame();
|
||||
const stackFrame = thread.peekStackFrame();
|
||||
isWarpMode = stackFrame.warpMode;
|
||||
|
||||
if (stackFrame.isLoop) {
|
||||
|
@ -151,11 +151,11 @@ Sequencer.prototype.stepThread = function (thread) {
|
|||
// Don't do anything to the stack, since loops need
|
||||
// to be re-executed.
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
// Don't go to the next block for this level of the stack,
|
||||
// since loops need to be re-executed.
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
|
||||
} else if (stackFrame.waitingReporter) {
|
||||
// This level of the stack was waiting for a value.
|
||||
// This means a reporter has just returned - so don't go
|
||||
|
@ -178,8 +178,8 @@ Sequencer.prototype.stepToBranch = function (thread, branchNum, isLoop) {
|
|||
if (!branchNum) {
|
||||
branchNum = 1;
|
||||
}
|
||||
var currentBlockId = thread.peekStack();
|
||||
var branchId = thread.target.blocks.getBranch(
|
||||
const currentBlockId = thread.peekStack();
|
||||
const branchId = thread.target.blocks.getBranch(
|
||||
currentBlockId,
|
||||
branchNum
|
||||
);
|
||||
|
@ -198,13 +198,13 @@ Sequencer.prototype.stepToBranch = function (thread, branchNum, isLoop) {
|
|||
* @param {!string} procedureCode Procedure code of procedure to step to.
|
||||
*/
|
||||
Sequencer.prototype.stepToProcedure = function (thread, procedureCode) {
|
||||
var definition = thread.target.blocks.getProcedureDefinition(procedureCode);
|
||||
const definition = thread.target.blocks.getProcedureDefinition(procedureCode);
|
||||
if (!definition) {
|
||||
return;
|
||||
}
|
||||
// Check if the call is recursive.
|
||||
// If so, set the thread to yield after pushing.
|
||||
var isRecursive = thread.isRecursiveCall(procedureCode);
|
||||
const isRecursive = thread.isRecursiveCall(procedureCode);
|
||||
// To step to a procedure, we put its definition on the stack.
|
||||
// Execution for the thread will proceed through the definition hat
|
||||
// and on to the main definition of the procedure.
|
||||
|
@ -218,8 +218,8 @@ Sequencer.prototype.stepToProcedure = function (thread, procedureCode) {
|
|||
} else {
|
||||
// Look for warp-mode flag on definition, and set the thread
|
||||
// to warp-mode if needed.
|
||||
var definitionBlock = thread.target.blocks.getBlock(definition);
|
||||
var doWarp = definitionBlock.mutation.warp;
|
||||
const definitionBlock = thread.target.blocks.getBlock(definition);
|
||||
const doWarp = definitionBlock.mutation.warp;
|
||||
if (doWarp) {
|
||||
thread.peekStackFrame().warpMode = true;
|
||||
} else {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
var EventEmitter = require('events');
|
||||
var util = require('util');
|
||||
const EventEmitter = require('events');
|
||||
const util = require('util');
|
||||
|
||||
var Blocks = require('./blocks');
|
||||
var Variable = require('../engine/variable');
|
||||
var List = require('../engine/list');
|
||||
var uid = require('../util/uid');
|
||||
const Blocks = require('./blocks');
|
||||
const Variable = require('../engine/variable');
|
||||
const List = require('../engine/list');
|
||||
const uid = require('../util/uid');
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
|
@ -16,7 +16,7 @@ var uid = require('../util/uid');
|
|||
* @param {?Blocks} blocks Blocks instance for the blocks owned by this target.
|
||||
* @constructor
|
||||
*/
|
||||
var Target = function (blocks) {
|
||||
const Target = function (blocks) {
|
||||
EventEmitter.call(this);
|
||||
|
||||
if (!blocks) {
|
||||
|
@ -87,13 +87,13 @@ Target.prototype.lookupOrCreateVariable = function (name) {
|
|||
}
|
||||
// If the stage has a global copy, return it.
|
||||
if (this.runtime && !this.isStage) {
|
||||
var stage = this.runtime.getTargetForStage();
|
||||
const stage = this.runtime.getTargetForStage();
|
||||
if (stage.variables.hasOwnProperty(name)) {
|
||||
return stage.variables[name];
|
||||
}
|
||||
}
|
||||
// No variable with this name exists - create it locally.
|
||||
var newVariable = new Variable(name, 0, false);
|
||||
const newVariable = new Variable(name, 0, false);
|
||||
this.variables[name] = newVariable;
|
||||
return newVariable;
|
||||
};
|
||||
|
@ -111,13 +111,13 @@ Target.prototype.lookupOrCreateList = function (name) {
|
|||
}
|
||||
// If the stage has a global copy, return it.
|
||||
if (this.runtime && !this.isStage) {
|
||||
var stage = this.runtime.getTargetForStage();
|
||||
const stage = this.runtime.getTargetForStage();
|
||||
if (stage.lists.hasOwnProperty(name)) {
|
||||
return stage.lists[name];
|
||||
}
|
||||
}
|
||||
// No list with this name exists - create it locally.
|
||||
var newList = new List(name, []);
|
||||
const newList = new List(name, []);
|
||||
this.lists[name] = newList;
|
||||
return newList;
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @param {?string} firstBlock First block to execute in the thread.
|
||||
* @constructor
|
||||
*/
|
||||
var Thread = function (firstBlock) {
|
||||
const Thread = function (firstBlock) {
|
||||
/**
|
||||
* ID of top block of the thread
|
||||
* @type {!string}
|
||||
|
@ -100,7 +100,7 @@ Thread.prototype.pushStack = function (blockId) {
|
|||
// Might not, if we just popped the stack.
|
||||
if (this.stack.length > this.stackFrames.length) {
|
||||
// Copy warp mode from any higher level.
|
||||
var warpMode = false;
|
||||
let warpMode = false;
|
||||
if (this.stackFrames.length > 0 && this.stackFrames[this.stackFrames.length - 1]) {
|
||||
warpMode = this.stackFrames[this.stackFrames.length - 1].warpMode;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ Thread.prototype.pushStack = function (blockId) {
|
|||
*/
|
||||
Thread.prototype.reuseStackForNextBlock = function (blockId) {
|
||||
this.stack[this.stack.length - 1] = blockId;
|
||||
var frame = this.stackFrames[this.stackFrames.length - 1];
|
||||
const frame = this.stackFrames[this.stackFrames.length - 1];
|
||||
frame.isLoop = false;
|
||||
// frame.warpMode = warpMode; // warp mode stays the same when reusing the stack frame.
|
||||
frame.reported = {};
|
||||
|
@ -144,9 +144,9 @@ Thread.prototype.popStack = function () {
|
|||
* Pop back down the stack frame until we hit a procedure call or the stack frame is emptied
|
||||
*/
|
||||
Thread.prototype.stopThisScript = function () {
|
||||
var blockID = this.peekStack();
|
||||
let blockID = this.peekStack();
|
||||
while (blockID !== null) {
|
||||
var block = this.target.blocks.getBlock(blockID);
|
||||
const block = this.target.blocks.getBlock(blockID);
|
||||
if (typeof block !== 'undefined' && block.opcode === 'procedures_callnoreturn') {
|
||||
break;
|
||||
}
|
||||
|
@ -191,9 +191,9 @@ Thread.prototype.peekParentStackFrame = function () {
|
|||
* @param {*} value Reported value to push.
|
||||
*/
|
||||
Thread.prototype.pushReportedValue = function (value) {
|
||||
var parentStackFrame = this.peekParentStackFrame();
|
||||
const parentStackFrame = this.peekParentStackFrame();
|
||||
if (parentStackFrame) {
|
||||
var waitingReporter = parentStackFrame.waitingReporter;
|
||||
const waitingReporter = parentStackFrame.waitingReporter;
|
||||
parentStackFrame.reported[waitingReporter] = value;
|
||||
}
|
||||
};
|
||||
|
@ -205,7 +205,7 @@ Thread.prototype.pushReportedValue = function (value) {
|
|||
* @param {*} value Value to set for parameter.
|
||||
*/
|
||||
Thread.prototype.pushParam = function (paramName, value) {
|
||||
var stackFrame = this.peekStackFrame();
|
||||
const stackFrame = this.peekStackFrame();
|
||||
stackFrame.params[paramName] = value;
|
||||
};
|
||||
|
||||
|
@ -215,8 +215,8 @@ Thread.prototype.pushParam = function (paramName, value) {
|
|||
* @return {*} value Value for parameter.
|
||||
*/
|
||||
Thread.prototype.getParam = function (paramName) {
|
||||
for (var i = this.stackFrames.length - 1; i >= 0; i--) {
|
||||
var frame = this.stackFrames[i];
|
||||
for (let i = this.stackFrames.length - 1; i >= 0; i--) {
|
||||
const frame = this.stackFrames[i];
|
||||
if (frame.params.hasOwnProperty(paramName)) {
|
||||
return frame.params[paramName];
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ Thread.prototype.atStackTop = function () {
|
|||
* where execution proceeds from one block to the next.
|
||||
*/
|
||||
Thread.prototype.goToNextBlock = function () {
|
||||
var nextBlockId = this.target.blocks.getNextBlock(this.peekStack());
|
||||
const nextBlockId = this.target.blocks.getNextBlock(this.peekStack());
|
||||
this.reuseStackForNextBlock(nextBlockId);
|
||||
};
|
||||
|
||||
|
@ -250,10 +250,10 @@ Thread.prototype.goToNextBlock = function () {
|
|||
* @return {boolean} True if the call appears recursive.
|
||||
*/
|
||||
Thread.prototype.isRecursiveCall = function (procedureCode) {
|
||||
var callCount = 5; // Max number of enclosing procedure calls to examine.
|
||||
var sp = this.stack.length - 1;
|
||||
for (var i = sp - 1; i >= 0; i--) {
|
||||
var block = this.target.blocks.getBlock(this.stack[i]);
|
||||
let callCount = 5; // Max number of enclosing procedure calls to examine.
|
||||
const sp = this.stack.length - 1;
|
||||
for (let i = sp - 1; i >= 0; i--) {
|
||||
const block = this.target.blocks.getBlock(this.stack[i]);
|
||||
if (block.opcode === 'procedures_callnoreturn' &&
|
||||
block.mutation.proccode === procedureCode) {
|
||||
return true;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* @param {boolean} isCloud Whether the variable is stored in the cloud.
|
||||
* @constructor
|
||||
*/
|
||||
var Variable = function (name, value, isCloud) {
|
||||
const Variable = function (name, value, isCloud) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.isCloud = isCloud;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var AssetType = require('scratch-storage').AssetType;
|
||||
var log = require('../util/log');
|
||||
const AssetType = require('scratch-storage').AssetType;
|
||||
const log = require('../util/log');
|
||||
|
||||
/**
|
||||
* Load a costume's asset into memory asynchronously.
|
||||
|
@ -13,62 +13,58 @@ var log = require('../util/log');
|
|||
* @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
|
||||
* @returns {?Promise} - a promise which will resolve after skinId is set, or null on error.
|
||||
*/
|
||||
var loadCostume = function (md5ext, costume, runtime) {
|
||||
const loadCostume = function (md5ext, costume, runtime) {
|
||||
if (!runtime.storage) {
|
||||
log.error('No storage module present; cannot load costume asset: ', md5ext);
|
||||
return Promise.resolve(costume);
|
||||
}
|
||||
|
||||
|
||||
var idParts = md5ext.split('.');
|
||||
var md5 = idParts[0];
|
||||
var ext = idParts[1].toUpperCase();
|
||||
var assetType = (ext === 'SVG') ? AssetType.ImageVector : AssetType.ImageBitmap;
|
||||
const idParts = md5ext.split('.');
|
||||
const md5 = idParts[0];
|
||||
const ext = idParts[1].toUpperCase();
|
||||
const assetType = (ext === 'SVG') ? AssetType.ImageVector : AssetType.ImageBitmap;
|
||||
|
||||
var rotationCenter = [
|
||||
const rotationCenter = [
|
||||
costume.rotationCenterX / costume.bitmapResolution,
|
||||
costume.rotationCenterY / costume.bitmapResolution
|
||||
];
|
||||
|
||||
var promise = runtime.storage.load(assetType, md5).then(function (costumeAsset) {
|
||||
let promise = runtime.storage.load(assetType, md5).then(costumeAsset => {
|
||||
costume.url = costumeAsset.encodeDataURI();
|
||||
return costumeAsset;
|
||||
});
|
||||
|
||||
if (!runtime.renderer) {
|
||||
log.error('No rendering module present; cannot load costume asset: ', md5ext);
|
||||
return promise.then(function () {
|
||||
return costume;
|
||||
});
|
||||
return promise.then(() => costume);
|
||||
}
|
||||
|
||||
if (assetType === AssetType.ImageVector) {
|
||||
promise = promise.then(function (costumeAsset) {
|
||||
promise = promise.then(costumeAsset => {
|
||||
costume.skinId = runtime.renderer.createSVGSkin(costumeAsset.decodeText(), rotationCenter);
|
||||
return costume;
|
||||
});
|
||||
} else {
|
||||
promise = promise.then(function (costumeAsset) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var imageElement = new Image();
|
||||
var removeEventListeners; // fix no-use-before-define
|
||||
var onError = function () {
|
||||
removeEventListeners();
|
||||
reject();
|
||||
};
|
||||
var onLoad = function () {
|
||||
removeEventListeners();
|
||||
resolve(imageElement);
|
||||
};
|
||||
removeEventListeners = function () {
|
||||
imageElement.removeEventListener('error', onError);
|
||||
imageElement.removeEventListener('load', onLoad);
|
||||
};
|
||||
imageElement.addEventListener('error', onError);
|
||||
imageElement.addEventListener('load', onLoad);
|
||||
imageElement.src = costumeAsset.encodeDataURI();
|
||||
});
|
||||
}).then(function (imageElement) {
|
||||
promise = promise.then(costumeAsset => new Promise((resolve, reject) => {
|
||||
const imageElement = new Image();
|
||||
let removeEventListeners; // fix no-use-before-define
|
||||
const onError = function () {
|
||||
removeEventListeners();
|
||||
reject();
|
||||
};
|
||||
const onLoad = function () {
|
||||
removeEventListeners();
|
||||
resolve(imageElement);
|
||||
};
|
||||
removeEventListeners = function () {
|
||||
imageElement.removeEventListener('error', onError);
|
||||
imageElement.removeEventListener('load', onLoad);
|
||||
};
|
||||
imageElement.addEventListener('error', onError);
|
||||
imageElement.addEventListener('load', onLoad);
|
||||
imageElement.src = costumeAsset.encodeDataURI();
|
||||
})).then(imageElement => {
|
||||
costume.skinId = runtime.renderer.createBitmapSkin(imageElement, costume.bitmapResolution, rotationCenter);
|
||||
return costume;
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var AssetType = require('scratch-storage').AssetType;
|
||||
var log = require('../util/log');
|
||||
const AssetType = require('scratch-storage').AssetType;
|
||||
const log = require('../util/log');
|
||||
|
||||
/**
|
||||
* Load a sound's asset into memory asynchronously.
|
||||
|
@ -9,7 +9,7 @@ var log = require('../util/log');
|
|||
* @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
|
||||
* @returns {!Promise} - a promise which will resolve after sound is loaded
|
||||
*/
|
||||
var loadSound = function (sound, runtime) {
|
||||
const loadSound = function (sound, runtime) {
|
||||
if (!runtime.storage) {
|
||||
log.error('No storage module present; cannot load sound asset: ', sound.md5);
|
||||
return Promise.resolve(sound);
|
||||
|
@ -18,9 +18,9 @@ var loadSound = function (sound, runtime) {
|
|||
log.error('No audio engine present; cannot load sound asset: ', sound.md5);
|
||||
return Promise.resolve(sound);
|
||||
}
|
||||
var idParts = sound.md5.split('.');
|
||||
var md5 = idParts[0];
|
||||
return runtime.storage.load(AssetType.Sound, md5).then(function (soundAsset) {
|
||||
const idParts = sound.md5.split('.');
|
||||
const md5 = idParts[0];
|
||||
return runtime.storage.load(AssetType.Sound, md5).then(soundAsset => {
|
||||
sound.data = soundAsset.data;
|
||||
return runtime.audioEngine.decodeSound(sound);
|
||||
});
|
||||
|
|
|
@ -5,18 +5,18 @@
|
|||
* scratch-vm runtime structures.
|
||||
*/
|
||||
|
||||
var Blocks = require('../engine/blocks');
|
||||
var RenderedTarget = require('../sprites/rendered-target');
|
||||
var Sprite = require('../sprites/sprite');
|
||||
var Color = require('../util/color');
|
||||
var log = require('../util/log');
|
||||
var uid = require('../util/uid');
|
||||
var specMap = require('./sb2specmap');
|
||||
var Variable = require('../engine/variable');
|
||||
var List = require('../engine/list');
|
||||
const Blocks = require('../engine/blocks');
|
||||
const RenderedTarget = require('../sprites/rendered-target');
|
||||
const Sprite = require('../sprites/sprite');
|
||||
const Color = require('../util/color');
|
||||
const log = require('../util/log');
|
||||
const uid = require('../util/uid');
|
||||
const specMap = require('./sb2specmap');
|
||||
const Variable = require('../engine/variable');
|
||||
const List = require('../engine/list');
|
||||
|
||||
var loadCostume = require('./load-costume.js');
|
||||
var loadSound = require('./load-sound.js');
|
||||
const loadCostume = require('./load-costume.js');
|
||||
const loadSound = require('./load-sound.js');
|
||||
|
||||
/**
|
||||
* Parse a single "Scratch object" and create all its in-memory VM objects.
|
||||
|
@ -32,19 +32,19 @@ var parseScratchObject = function (object, runtime, topLevel) {
|
|||
return null;
|
||||
}
|
||||
// Blocks container for this object.
|
||||
var blocks = new Blocks();
|
||||
const blocks = new Blocks();
|
||||
// @todo: For now, load all Scratch objects (stage/sprites) as a Sprite.
|
||||
var sprite = new Sprite(blocks, runtime);
|
||||
const sprite = new Sprite(blocks, runtime);
|
||||
// Sprite/stage name from JSON.
|
||||
if (object.hasOwnProperty('objName')) {
|
||||
sprite.name = object.objName;
|
||||
}
|
||||
// Costumes from JSON.
|
||||
var costumePromises = [];
|
||||
const costumePromises = [];
|
||||
if (object.hasOwnProperty('costumes')) {
|
||||
for (var i = 0; i < object.costumes.length; i++) {
|
||||
var costumeSource = object.costumes[i];
|
||||
var costume = {
|
||||
for (let i = 0; i < object.costumes.length; i++) {
|
||||
const costumeSource = object.costumes[i];
|
||||
const costume = {
|
||||
name: costumeSource.costumeName,
|
||||
bitmapResolution: costumeSource.bitmapResolution || 1,
|
||||
rotationCenterX: costumeSource.rotationCenterX,
|
||||
|
@ -57,9 +57,9 @@ var parseScratchObject = function (object, runtime, topLevel) {
|
|||
}
|
||||
// Sounds from JSON
|
||||
if (object.hasOwnProperty('sounds')) {
|
||||
for (var s = 0; s < object.sounds.length; s++) {
|
||||
var soundSource = object.sounds[s];
|
||||
var sound = {
|
||||
for (let s = 0; s < object.sounds.length; s++) {
|
||||
const soundSource = object.sounds[s];
|
||||
const sound = {
|
||||
name: soundSource.soundName,
|
||||
format: soundSource.format,
|
||||
rate: soundSource.rate,
|
||||
|
@ -77,13 +77,13 @@ var parseScratchObject = function (object, runtime, topLevel) {
|
|||
parseScripts(object.scripts, blocks);
|
||||
}
|
||||
// Create the first clone, and load its run-state from JSON.
|
||||
var target = sprite.createClone();
|
||||
const target = sprite.createClone();
|
||||
// Add it to the runtime's list of targets.
|
||||
runtime.targets.push(target);
|
||||
// Load target properties from JSON.
|
||||
if (object.hasOwnProperty('variables')) {
|
||||
for (var j = 0; j < object.variables.length; j++) {
|
||||
var variable = object.variables[j];
|
||||
for (let j = 0; j < object.variables.length; j++) {
|
||||
const variable = object.variables[j];
|
||||
target.variables[variable.name] = new Variable(
|
||||
variable.name,
|
||||
variable.value,
|
||||
|
@ -92,8 +92,8 @@ var parseScratchObject = function (object, runtime, topLevel) {
|
|||
}
|
||||
}
|
||||
if (object.hasOwnProperty('lists')) {
|
||||
for (var k = 0; k < object.lists.length; k++) {
|
||||
var list = object.lists[k];
|
||||
for (let k = 0; k < object.lists.length; k++) {
|
||||
const list = object.lists[k];
|
||||
// @todo: monitor properties.
|
||||
target.lists[list.listName] = new List(
|
||||
list.listName,
|
||||
|
@ -133,13 +133,13 @@ var parseScratchObject = function (object, runtime, topLevel) {
|
|||
}
|
||||
}
|
||||
target.isStage = topLevel;
|
||||
Promise.all(costumePromises).then(function (costumes) {
|
||||
Promise.all(costumePromises).then(costumes => {
|
||||
sprite.costumes = costumes;
|
||||
target.updateAllDrawableProperties();
|
||||
});
|
||||
// The stage will have child objects; recursively process them.
|
||||
if (object.children) {
|
||||
for (var m = 0; m < object.children.length; m++) {
|
||||
for (let m = 0; m < object.children.length; m++) {
|
||||
parseScratchObject(object.children[m], runtime, false);
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ var parseScratchObject = function (object, runtime, topLevel) {
|
|||
* @param {boolean=} optForceSprite If set, treat as sprite (Sprite2).
|
||||
* @return {?Target} Top-level target created (stage or sprite).
|
||||
*/
|
||||
var sb2import = function (json, runtime, optForceSprite) {
|
||||
const sb2import = function (json, runtime, optForceSprite) {
|
||||
return parseScratchObject(
|
||||
JSON.parse(json),
|
||||
runtime,
|
||||
|
@ -169,12 +169,12 @@ var sb2import = function (json, runtime, optForceSprite) {
|
|||
* @param {!Blocks} blocks Blocks object to load parsed blocks into.
|
||||
*/
|
||||
var parseScripts = function (scripts, blocks) {
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
var script = scripts[i];
|
||||
var scriptX = script[0];
|
||||
var scriptY = script[1];
|
||||
var blockList = script[2];
|
||||
var parsedBlockList = parseBlockList(blockList);
|
||||
for (let i = 0; i < scripts.length; i++) {
|
||||
const script = scripts[i];
|
||||
const scriptX = script[0];
|
||||
const scriptY = script[1];
|
||||
const blockList = script[2];
|
||||
const parsedBlockList = parseBlockList(blockList);
|
||||
if (parsedBlockList[0]) {
|
||||
// Adjust script coordinates to account for
|
||||
// larger block size in scratch-blocks.
|
||||
|
@ -185,8 +185,8 @@ var parseScripts = function (scripts, blocks) {
|
|||
parsedBlockList[0].parent = null;
|
||||
}
|
||||
// Flatten children and create add the blocks.
|
||||
var convertedBlocks = flatten(parsedBlockList);
|
||||
for (var j = 0; j < convertedBlocks.length; j++) {
|
||||
const convertedBlocks = flatten(parsedBlockList);
|
||||
for (let j = 0; j < convertedBlocks.length; j++) {
|
||||
blocks.createBlock(convertedBlocks[j]);
|
||||
}
|
||||
}
|
||||
|
@ -201,11 +201,11 @@ var parseScripts = function (scripts, blocks) {
|
|||
* @return {Array.<object>} Scratch VM-format block list.
|
||||
*/
|
||||
var parseBlockList = function (blockList) {
|
||||
var resultingList = [];
|
||||
var previousBlock = null; // For setting next.
|
||||
for (var i = 0; i < blockList.length; i++) {
|
||||
var block = blockList[i];
|
||||
var parsedBlock = parseBlock(block);
|
||||
const resultingList = [];
|
||||
let previousBlock = null; // For setting next.
|
||||
for (let i = 0; i < blockList.length; i++) {
|
||||
const block = blockList[i];
|
||||
const parsedBlock = parseBlock(block);
|
||||
if (typeof parsedBlock === 'undefined') continue;
|
||||
if (previousBlock) {
|
||||
parsedBlock.parent = previousBlock.id;
|
||||
|
@ -224,9 +224,9 @@ var parseBlockList = function (blockList) {
|
|||
* @return {Array.<object>} Flattened list to be passed to `blocks.createBlock`.
|
||||
*/
|
||||
var flatten = function (blocks) {
|
||||
var finalBlocks = [];
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
var block = blocks[i];
|
||||
let finalBlocks = [];
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
const block = blocks[i];
|
||||
finalBlocks.push(block);
|
||||
if (block.children) {
|
||||
finalBlocks = finalBlocks.concat(flatten(block.children));
|
||||
|
@ -243,19 +243,19 @@ var flatten = function (blocks) {
|
|||
* @param {string} procCode Scratch 2.0 procedure string.
|
||||
* @return {object} Argument map compatible with those in sb2specmap.
|
||||
*/
|
||||
var parseProcedureArgMap = function (procCode) {
|
||||
var argMap = [
|
||||
const parseProcedureArgMap = function (procCode) {
|
||||
const argMap = [
|
||||
{} // First item in list is op string.
|
||||
];
|
||||
var INPUT_PREFIX = 'input';
|
||||
var inputCount = 0;
|
||||
const INPUT_PREFIX = 'input';
|
||||
let inputCount = 0;
|
||||
// Split by %n, %b, %s.
|
||||
var parts = procCode.split(/(?=[^\\]%[nbs])/);
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var part = parts[i].trim();
|
||||
const parts = procCode.split(/(?=[^\\]%[nbs])/);
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const part = parts[i].trim();
|
||||
if (part.substring(0, 1) === '%') {
|
||||
var argType = part.substring(1, 2);
|
||||
var arg = {
|
||||
const argType = part.substring(1, 2);
|
||||
const arg = {
|
||||
type: 'input',
|
||||
inputName: INPUT_PREFIX + (inputCount++)
|
||||
};
|
||||
|
@ -277,15 +277,15 @@ var parseProcedureArgMap = function (procCode) {
|
|||
*/
|
||||
var parseBlock = function (sb2block) {
|
||||
// First item in block object is the old opcode (e.g., 'forward:').
|
||||
var oldOpcode = sb2block[0];
|
||||
const oldOpcode = sb2block[0];
|
||||
// Convert the block using the specMap. See sb2specmap.js.
|
||||
if (!oldOpcode || !specMap[oldOpcode]) {
|
||||
log.warn('Couldn\'t find SB2 block: ', oldOpcode);
|
||||
return;
|
||||
}
|
||||
var blockMetadata = specMap[oldOpcode];
|
||||
const blockMetadata = specMap[oldOpcode];
|
||||
// Block skeleton.
|
||||
var activeBlock = {
|
||||
const activeBlock = {
|
||||
id: uid(), // Generate a new block unique ID.
|
||||
opcode: blockMetadata.opcode, // Converted, e.g. "motion_movesteps".
|
||||
inputs: {}, // Inputs to this block and the blocks they point to.
|
||||
|
@ -301,15 +301,15 @@ var parseBlock = function (sb2block) {
|
|||
// Look at the expected arguments in `blockMetadata.argMap.`
|
||||
// The basic problem here is to turn positional SB2 arguments into
|
||||
// non-positional named Scratch VM arguments.
|
||||
for (var i = 0; i < blockMetadata.argMap.length; i++) {
|
||||
var expectedArg = blockMetadata.argMap[i];
|
||||
var providedArg = sb2block[i + 1]; // (i = 0 is opcode)
|
||||
for (let i = 0; i < blockMetadata.argMap.length; i++) {
|
||||
const expectedArg = blockMetadata.argMap[i];
|
||||
const providedArg = sb2block[i + 1]; // (i = 0 is opcode)
|
||||
// Whether the input is obscuring a shadow.
|
||||
var shadowObscured = false;
|
||||
let shadowObscured = false;
|
||||
// Positional argument is an input.
|
||||
if (expectedArg.type === 'input') {
|
||||
// Create a new block and input metadata.
|
||||
var inputUid = uid();
|
||||
const inputUid = uid();
|
||||
activeBlock.inputs[expectedArg.inputName] = {
|
||||
name: expectedArg.inputName,
|
||||
block: null,
|
||||
|
@ -325,8 +325,8 @@ var parseBlock = function (sb2block) {
|
|||
// Single block occupies the input.
|
||||
innerBlocks = [parseBlock(providedArg)];
|
||||
}
|
||||
var previousBlock = null;
|
||||
for (var j = 0; j < innerBlocks.length; j++) {
|
||||
let previousBlock = null;
|
||||
for (let j = 0; j < innerBlocks.length; j++) {
|
||||
if (j === 0) {
|
||||
innerBlocks[j].parent = activeBlock.id;
|
||||
} else {
|
||||
|
@ -350,9 +350,9 @@ var parseBlock = function (sb2block) {
|
|||
}
|
||||
// Each shadow has a field generated for it automatically.
|
||||
// Value to be filled in the field.
|
||||
var fieldValue = providedArg;
|
||||
let fieldValue = providedArg;
|
||||
// Shadows' field names match the input name, except for these:
|
||||
var fieldName = expectedArg.inputName;
|
||||
let fieldName = expectedArg.inputName;
|
||||
if (expectedArg.inputOp === 'math_number' ||
|
||||
expectedArg.inputOp === 'math_whole_number' ||
|
||||
expectedArg.inputOp === 'math_positive_number' ||
|
||||
|
@ -379,7 +379,7 @@ var parseBlock = function (sb2block) {
|
|||
// Filled drop-down menu.
|
||||
fieldValue = '';
|
||||
}
|
||||
var fields = {};
|
||||
const fields = {};
|
||||
fields[fieldName] = {
|
||||
name: fieldName,
|
||||
value: fieldValue
|
||||
|
@ -422,7 +422,7 @@ var parseBlock = function (sb2block) {
|
|||
} else if (oldOpcode === 'procDef') {
|
||||
// Mutation for procedure definition:
|
||||
// store all 2.0 proc data.
|
||||
var procData = sb2block.slice(1);
|
||||
const procData = sb2block.slice(1);
|
||||
activeBlock.mutation = {
|
||||
tagName: 'mutation',
|
||||
proccode: procData[0], // e.g., "abc %n %b %s"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* properties. By hand, I matched the opcode name to the 3.0 opcode.
|
||||
* Finally, I filled in the expected arguments as below.
|
||||
*/
|
||||
var specMap = {
|
||||
const specMap = {
|
||||
'forward:': {
|
||||
opcode: 'motion_movesteps',
|
||||
argMap: [
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
var VirtualMachine = require('./virtual-machine');
|
||||
const VirtualMachine = require('./virtual-machine');
|
||||
|
||||
module.exports = VirtualMachine;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var Timer = require('../util/timer');
|
||||
const Timer = require('../util/timer');
|
||||
|
||||
var Clock = function (runtime) {
|
||||
const Clock = function (runtime) {
|
||||
this._projectTimer = new Timer();
|
||||
this._projectTimer.start();
|
||||
this._pausedTime = null;
|
||||
|
@ -26,7 +26,7 @@ Clock.prototype.pause = function () {
|
|||
|
||||
Clock.prototype.resume = function () {
|
||||
this._paused = false;
|
||||
var dt = this._projectTimer.timeElapsed() - this._pausedTime;
|
||||
const dt = this._projectTimer.timeElapsed() - this._pausedTime;
|
||||
this._projectTimer.startTime += dt;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var Cast = require('../util/cast');
|
||||
const Cast = require('../util/cast');
|
||||
|
||||
var Keyboard = function (runtime) {
|
||||
const Keyboard = function (runtime) {
|
||||
/**
|
||||
* List of currently pressed keys.
|
||||
* @type{Array.<number>}
|
||||
|
@ -25,7 +25,7 @@ Keyboard.prototype._scratchKeyToKeyCode = function (keyName) {
|
|||
// Key codes placed in with number blocks.
|
||||
return keyName;
|
||||
}
|
||||
var keyString = Cast.toString(keyName);
|
||||
const keyString = Cast.toString(keyName);
|
||||
switch (keyString) {
|
||||
case 'space': return 32;
|
||||
case 'left arrow': return 37;
|
||||
|
@ -65,7 +65,7 @@ Keyboard.prototype._keyCodeToScratchKey = function (keyCode) {
|
|||
*/
|
||||
Keyboard.prototype.postData = function (data) {
|
||||
if (data.keyCode) {
|
||||
var index = this._keysPressed.indexOf(data.keyCode);
|
||||
const index = this._keysPressed.indexOf(data.keyCode);
|
||||
if (data.isDown) {
|
||||
// If not already present, add to the list.
|
||||
if (index < 0) {
|
||||
|
@ -94,7 +94,7 @@ Keyboard.prototype.getKeyIsDown = function (key) {
|
|||
if (key === 'any') {
|
||||
return this._keysPressed.length > 0;
|
||||
}
|
||||
var keyCode = this._scratchKeyToKeyCode(key);
|
||||
const keyCode = this._scratchKeyToKeyCode(key);
|
||||
return this._keysPressed.indexOf(keyCode) > -1;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var MathUtil = require('../util/math-util');
|
||||
const MathUtil = require('../util/math-util');
|
||||
|
||||
var Mouse = function (runtime) {
|
||||
const Mouse = function (runtime) {
|
||||
this._x = 0;
|
||||
this._y = 0;
|
||||
this._isDown = false;
|
||||
|
@ -20,9 +20,9 @@ var Mouse = function (runtime) {
|
|||
*/
|
||||
Mouse.prototype._activateClickHats = function (x, y) {
|
||||
if (this.runtime.renderer) {
|
||||
var drawableID = this.runtime.renderer.pick(x, y);
|
||||
for (var i = 0; i < this.runtime.targets.length; i++) {
|
||||
var target = this.runtime.targets[i];
|
||||
const drawableID = this.runtime.renderer.pick(x, y);
|
||||
for (let i = 0; i < this.runtime.targets.length; i++) {
|
||||
const target = this.runtime.targets[i];
|
||||
if (target.hasOwnProperty('drawableID') &&
|
||||
target.drawableID === drawableID) {
|
||||
this.runtime.startHats('event_whenthisspriteclicked',
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
var Scratch = window.Scratch = window.Scratch || {};
|
||||
const Scratch = window.Scratch = window.Scratch || {};
|
||||
|
||||
var ASSET_SERVER = 'https://cdn.assets.scratch.mit.edu/';
|
||||
var PROJECT_SERVER = 'https://cdn.projects.scratch.mit.edu/';
|
||||
const ASSET_SERVER = 'https://cdn.assets.scratch.mit.edu/';
|
||||
const PROJECT_SERVER = 'https://cdn.projects.scratch.mit.edu/';
|
||||
|
||||
var loadProject = function () {
|
||||
var id = location.hash.substring(1);
|
||||
const loadProject = function () {
|
||||
let id = location.hash.substring(1);
|
||||
if (id.length < 1 || !isFinite(id)) {
|
||||
id = '119615668';
|
||||
}
|
||||
|
@ -15,9 +15,9 @@ var loadProject = function () {
|
|||
* @param {Asset} asset - calculate a URL for this asset.
|
||||
* @returns {string} a URL to download a project file.
|
||||
*/
|
||||
var getProjectUrl = function (asset) {
|
||||
var assetIdParts = asset.assetId.split('.');
|
||||
var assetUrlParts = [PROJECT_SERVER, 'internalapi/project/', assetIdParts[0], '/get/'];
|
||||
const getProjectUrl = function (asset) {
|
||||
const assetIdParts = asset.assetId.split('.');
|
||||
const assetUrlParts = [PROJECT_SERVER, 'internalapi/project/', assetIdParts[0], '/get/'];
|
||||
if (assetIdParts[1]) {
|
||||
assetUrlParts.push(assetIdParts[1]);
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ var getProjectUrl = function (asset) {
|
|||
* @param {Asset} asset - calculate a URL for this asset.
|
||||
* @returns {string} a URL to download a project asset (PNG, WAV, etc.)
|
||||
*/
|
||||
var getAssetUrl = function (asset) {
|
||||
var assetUrlParts = [
|
||||
const getAssetUrl = function (asset) {
|
||||
const assetUrlParts = [
|
||||
ASSET_SERVER,
|
||||
'internalapi/asset/',
|
||||
asset.assetId,
|
||||
|
@ -43,32 +43,32 @@ var getAssetUrl = function (asset) {
|
|||
window.onload = function () {
|
||||
// Lots of global variables to make debugging easier
|
||||
// Instantiate the VM.
|
||||
var vm = new window.VirtualMachine();
|
||||
const vm = new window.VirtualMachine();
|
||||
Scratch.vm = vm;
|
||||
|
||||
var storage = new Scratch.Storage();
|
||||
var AssetType = Scratch.Storage.AssetType;
|
||||
const storage = new Scratch.Storage();
|
||||
const AssetType = Scratch.Storage.AssetType;
|
||||
storage.addWebSource([AssetType.Project], getProjectUrl);
|
||||
storage.addWebSource([AssetType.ImageVector, AssetType.ImageBitmap, AssetType.Sound], getAssetUrl);
|
||||
vm.attachStorage(storage);
|
||||
|
||||
// Loading projects from the server.
|
||||
document.getElementById('projectLoadButton').onclick = function () {
|
||||
document.location = '#' + document.getElementById('projectId').value;
|
||||
document.location = `#${document.getElementById('projectId').value}`;
|
||||
location.reload();
|
||||
};
|
||||
loadProject();
|
||||
|
||||
// Instantiate the renderer and connect it to the VM.
|
||||
var canvas = document.getElementById('scratch-stage');
|
||||
var renderer = new window.RenderWebGL(canvas);
|
||||
const canvas = document.getElementById('scratch-stage');
|
||||
const renderer = new window.RenderWebGL(canvas);
|
||||
Scratch.renderer = renderer;
|
||||
vm.attachRenderer(renderer);
|
||||
var audioEngine = new window.AudioEngine();
|
||||
const audioEngine = new window.AudioEngine();
|
||||
vm.attachAudioEngine(audioEngine);
|
||||
|
||||
// Instantiate scratch-blocks and attach it to the DOM.
|
||||
var workspace = window.Blockly.inject('blocks', {
|
||||
const workspace = window.Blockly.inject('blocks', {
|
||||
media: './media/',
|
||||
zoom: {
|
||||
controls: true,
|
||||
|
@ -90,27 +90,27 @@ window.onload = function () {
|
|||
|
||||
// Attach scratch-blocks events to VM.
|
||||
workspace.addChangeListener(vm.blockListener);
|
||||
var flyoutWorkspace = workspace.getFlyout().getWorkspace();
|
||||
const flyoutWorkspace = workspace.getFlyout().getWorkspace();
|
||||
flyoutWorkspace.addChangeListener(vm.flyoutBlockListener);
|
||||
|
||||
// Create FPS counter.
|
||||
var stats = new window.Stats();
|
||||
const stats = new window.Stats();
|
||||
document.getElementById('tab-renderexplorer').appendChild(stats.dom);
|
||||
stats.dom.style.position = 'relative';
|
||||
stats.begin();
|
||||
|
||||
// Playground data tabs.
|
||||
// Block representation tab.
|
||||
var blockexplorer = document.getElementById('blockexplorer');
|
||||
var updateBlockExplorer = function (blocks) {
|
||||
const blockexplorer = document.getElementById('blockexplorer');
|
||||
const updateBlockExplorer = function (blocks) {
|
||||
blockexplorer.innerHTML = JSON.stringify(blocks, null, 2);
|
||||
window.hljs.highlightBlock(blockexplorer);
|
||||
};
|
||||
|
||||
// Thread representation tab.
|
||||
var threadexplorer = document.getElementById('threadexplorer');
|
||||
var cachedThreadJSON = '';
|
||||
var updateThreadExplorer = function (newJSON) {
|
||||
const threadexplorer = document.getElementById('threadexplorer');
|
||||
let cachedThreadJSON = '';
|
||||
const updateThreadExplorer = function (newJSON) {
|
||||
if (newJSON !== cachedThreadJSON) {
|
||||
cachedThreadJSON = newJSON;
|
||||
threadexplorer.innerHTML = cachedThreadJSON;
|
||||
|
@ -129,28 +129,28 @@ window.onload = function () {
|
|||
|
||||
// VM handlers.
|
||||
// Receipt of new playground data (thread, block representations).
|
||||
vm.on('playgroundData', function (data) {
|
||||
vm.on('playgroundData', data => {
|
||||
updateThreadExplorer(data.threads);
|
||||
updateBlockExplorer(data.blocks);
|
||||
});
|
||||
|
||||
// Receipt of new block XML for the selected target.
|
||||
vm.on('workspaceUpdate', function (data) {
|
||||
vm.on('workspaceUpdate', data => {
|
||||
workspace.clear();
|
||||
var dom = window.Blockly.Xml.textToDom(data.xml);
|
||||
const dom = window.Blockly.Xml.textToDom(data.xml);
|
||||
window.Blockly.Xml.domToWorkspace(dom, workspace);
|
||||
});
|
||||
|
||||
// Receipt of new list of targets, selected target update.
|
||||
var selectedTarget = document.getElementById('selectedTarget');
|
||||
vm.on('targetsUpdate', function (data) {
|
||||
const selectedTarget = document.getElementById('selectedTarget');
|
||||
vm.on('targetsUpdate', data => {
|
||||
// Clear select box.
|
||||
while (selectedTarget.firstChild) {
|
||||
selectedTarget.removeChild(selectedTarget.firstChild);
|
||||
}
|
||||
// Generate new select box.
|
||||
for (var i = 0; i < data.targetList.length; i++) {
|
||||
var targetOption = document.createElement('option');
|
||||
for (let i = 0; i < data.targetList.length; i++) {
|
||||
const targetOption = document.createElement('option');
|
||||
targetOption.setAttribute('value', data.targetList[i].id);
|
||||
// If target id matches editingTarget id, select it.
|
||||
if (data.targetList[i].id === data.editingTarget) {
|
||||
|
@ -167,23 +167,23 @@ window.onload = function () {
|
|||
};
|
||||
|
||||
// Feedback for stacks and blocks running.
|
||||
vm.on('SCRIPT_GLOW_ON', function (data) {
|
||||
vm.on('SCRIPT_GLOW_ON', data => {
|
||||
workspace.glowStack(data.id, true);
|
||||
});
|
||||
vm.on('SCRIPT_GLOW_OFF', function (data) {
|
||||
vm.on('SCRIPT_GLOW_OFF', data => {
|
||||
workspace.glowStack(data.id, false);
|
||||
});
|
||||
vm.on('BLOCK_GLOW_ON', function (data) {
|
||||
vm.on('BLOCK_GLOW_ON', data => {
|
||||
workspace.glowBlock(data.id, true);
|
||||
});
|
||||
vm.on('BLOCK_GLOW_OFF', function (data) {
|
||||
vm.on('BLOCK_GLOW_OFF', data => {
|
||||
workspace.glowBlock(data.id, false);
|
||||
});
|
||||
vm.on('VISUAL_REPORT', function (data) {
|
||||
vm.on('VISUAL_REPORT', data => {
|
||||
workspace.reportValue(data.id, data.value);
|
||||
});
|
||||
|
||||
vm.on('SPRITE_INFO_REPORT', function (data) {
|
||||
vm.on('SPRITE_INFO_REPORT', data => {
|
||||
if (data.id !== selectedTarget.value) return; // Not the editingTarget
|
||||
document.getElementById('sinfo-x').value = data.x;
|
||||
document.getElementById('sinfo-y').value = data.y;
|
||||
|
@ -193,8 +193,8 @@ window.onload = function () {
|
|||
document.getElementById('sinfo-visible').value = data.visible;
|
||||
});
|
||||
|
||||
document.getElementById('sinfo-post').addEventListener('click', function () {
|
||||
var data = {};
|
||||
document.getElementById('sinfo-post').addEventListener('click', () => {
|
||||
const data = {};
|
||||
data.x = document.getElementById('sinfo-x').value;
|
||||
data.y = document.getElementById('sinfo-y').value;
|
||||
data.direction = document.getElementById('sinfo-direction').value;
|
||||
|
@ -204,9 +204,9 @@ window.onload = function () {
|
|||
});
|
||||
|
||||
// Feed mouse events as VM I/O events.
|
||||
document.addEventListener('mousemove', function (e) {
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
var coordinates = {
|
||||
document.addEventListener('mousemove', e => {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const coordinates = {
|
||||
x: e.clientX - rect.left,
|
||||
y: e.clientY - rect.top,
|
||||
canvasWidth: rect.width,
|
||||
|
@ -214,9 +214,9 @@ window.onload = function () {
|
|||
};
|
||||
Scratch.vm.postIOData('mouse', coordinates);
|
||||
});
|
||||
canvas.addEventListener('mousedown', function (e) {
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
var data = {
|
||||
canvas.addEventListener('mousedown', e => {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const data = {
|
||||
isDown: true,
|
||||
x: e.clientX - rect.left,
|
||||
y: e.clientY - rect.top,
|
||||
|
@ -226,9 +226,9 @@ window.onload = function () {
|
|||
Scratch.vm.postIOData('mouse', data);
|
||||
e.preventDefault();
|
||||
});
|
||||
canvas.addEventListener('mouseup', function (e) {
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
var data = {
|
||||
canvas.addEventListener('mouseup', e => {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const data = {
|
||||
isDown: false,
|
||||
x: e.clientX - rect.left,
|
||||
y: e.clientY - rect.top,
|
||||
|
@ -240,7 +240,7 @@ window.onload = function () {
|
|||
});
|
||||
|
||||
// Feed keyboard events as VM I/O events.
|
||||
document.addEventListener('keydown', function (e) {
|
||||
document.addEventListener('keydown', e => {
|
||||
// Don't capture keys intended for Blockly inputs.
|
||||
if (e.target !== document && e.target !== document.body) {
|
||||
return;
|
||||
|
@ -251,7 +251,7 @@ window.onload = function () {
|
|||
});
|
||||
e.preventDefault();
|
||||
});
|
||||
document.addEventListener('keyup', function (e) {
|
||||
document.addEventListener('keyup', e => {
|
||||
// Always capture up events,
|
||||
// even those that have switched to other targets.
|
||||
Scratch.vm.postIOData('keyboard', {
|
||||
|
@ -275,29 +275,29 @@ window.onload = function () {
|
|||
requestAnimationFrame(animate);
|
||||
|
||||
// Handlers for green flag and stop all.
|
||||
document.getElementById('greenflag').addEventListener('click', function () {
|
||||
document.getElementById('greenflag').addEventListener('click', () => {
|
||||
vm.greenFlag();
|
||||
});
|
||||
document.getElementById('stopall').addEventListener('click', function () {
|
||||
document.getElementById('stopall').addEventListener('click', () => {
|
||||
vm.stopAll();
|
||||
});
|
||||
document.getElementById('turbomode').addEventListener('change', function () {
|
||||
var turboOn = document.getElementById('turbomode').checked;
|
||||
document.getElementById('turbomode').addEventListener('change', () => {
|
||||
const turboOn = document.getElementById('turbomode').checked;
|
||||
vm.setTurboMode(turboOn);
|
||||
});
|
||||
document.getElementById('compatmode').addEventListener('change',
|
||||
function () {
|
||||
var compatibilityMode = document.getElementById('compatmode').checked;
|
||||
() => {
|
||||
const compatibilityMode = document.getElementById('compatmode').checked;
|
||||
vm.setCompatibilityMode(compatibilityMode);
|
||||
});
|
||||
var tabBlockExplorer = document.getElementById('tab-blockexplorer');
|
||||
var tabThreadExplorer = document.getElementById('tab-threadexplorer');
|
||||
var tabRenderExplorer = document.getElementById('tab-renderexplorer');
|
||||
var tabImportExport = document.getElementById('tab-importexport');
|
||||
const tabBlockExplorer = document.getElementById('tab-blockexplorer');
|
||||
const tabThreadExplorer = document.getElementById('tab-threadexplorer');
|
||||
const tabRenderExplorer = document.getElementById('tab-renderexplorer');
|
||||
const tabImportExport = document.getElementById('tab-importexport');
|
||||
|
||||
// Handlers to show different explorers.
|
||||
document.getElementById('threadexplorer-link').addEventListener('click',
|
||||
function () {
|
||||
() => {
|
||||
Scratch.exploreTabOpen = true;
|
||||
getPlaygroundData();
|
||||
tabBlockExplorer.style.display = 'none';
|
||||
|
@ -306,7 +306,7 @@ window.onload = function () {
|
|||
tabImportExport.style.display = 'none';
|
||||
});
|
||||
document.getElementById('blockexplorer-link').addEventListener('click',
|
||||
function () {
|
||||
() => {
|
||||
Scratch.exploreTabOpen = true;
|
||||
getPlaygroundData();
|
||||
tabBlockExplorer.style.display = 'block';
|
||||
|
@ -315,7 +315,7 @@ window.onload = function () {
|
|||
tabImportExport.style.display = 'none';
|
||||
});
|
||||
document.getElementById('renderexplorer-link').addEventListener('click',
|
||||
function () {
|
||||
() => {
|
||||
Scratch.exploreTabOpen = false;
|
||||
tabBlockExplorer.style.display = 'none';
|
||||
tabRenderExplorer.style.display = 'block';
|
||||
|
@ -323,7 +323,7 @@ window.onload = function () {
|
|||
tabImportExport.style.display = 'none';
|
||||
});
|
||||
document.getElementById('importexport-link').addEventListener('click',
|
||||
function () {
|
||||
() => {
|
||||
Scratch.exploreTabOpen = false;
|
||||
tabBlockExplorer.style.display = 'none';
|
||||
tabRenderExplorer.style.display = 'none';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
var util = require('util');
|
||||
const util = require('util');
|
||||
|
||||
var log = require('../util/log');
|
||||
var MathUtil = require('../util/math-util');
|
||||
var Target = require('../engine/target');
|
||||
const log = require('../util/log');
|
||||
const MathUtil = require('../util/math-util');
|
||||
const Target = require('../engine/target');
|
||||
|
||||
/**
|
||||
* Rendered target: instance of a sprite (clone), or the stage.
|
||||
|
@ -10,7 +10,7 @@ var Target = require('../engine/target');
|
|||
* @param {Runtime} runtime Reference to the runtime.
|
||||
* @constructor
|
||||
*/
|
||||
var RenderedTarget = function (sprite, runtime) {
|
||||
const RenderedTarget = function (sprite, runtime) {
|
||||
Target.call(this, sprite.blocks);
|
||||
this.runtime = runtime;
|
||||
/**
|
||||
|
@ -175,10 +175,10 @@ RenderedTarget.prototype.rotationStyle = (
|
|||
RenderedTarget.prototype.setXY = function (x, y, force) {
|
||||
if (this.isStage) return;
|
||||
if (this.dragging && !force) return;
|
||||
var oldX = this.x;
|
||||
var oldY = this.y;
|
||||
const oldX = this.x;
|
||||
const oldY = this.y;
|
||||
if (this.renderer) {
|
||||
var position = this.renderer.getFencedPositionOfDrawable(this.drawableID, [x, y]);
|
||||
const position = this.renderer.getFencedPositionOfDrawable(this.drawableID, [x, y]);
|
||||
this.x = position[0];
|
||||
this.y = position[1];
|
||||
|
||||
|
@ -202,15 +202,15 @@ RenderedTarget.prototype.setXY = function (x, y, force) {
|
|||
*/
|
||||
RenderedTarget.prototype._getRenderedDirectionAndScale = function () {
|
||||
// Default: no changes to `this.direction` or `this.scale`.
|
||||
var finalDirection = this.direction;
|
||||
var finalScale = [this.size, this.size];
|
||||
let finalDirection = this.direction;
|
||||
let finalScale = [this.size, this.size];
|
||||
if (this.rotationStyle === RenderedTarget.ROTATION_STYLE_NONE) {
|
||||
// Force rendered direction to be 90.
|
||||
finalDirection = 90;
|
||||
} else if (this.rotationStyle === RenderedTarget.ROTATION_STYLE_LEFT_RIGHT) {
|
||||
// Force rendered direction to be 90, and flip drawable if needed.
|
||||
finalDirection = 90;
|
||||
var scaleFlip = (this.direction < 0) ? -1 : 1;
|
||||
const scaleFlip = (this.direction < 0) ? -1 : 1;
|
||||
finalScale = [scaleFlip * this.size, this.size];
|
||||
}
|
||||
return {direction: finalDirection, scale: finalScale};
|
||||
|
@ -227,7 +227,7 @@ RenderedTarget.prototype.setDirection = function (direction) {
|
|||
// Keep direction between -179 and +180.
|
||||
this.direction = MathUtil.wrapClamp(direction, -179, 180);
|
||||
if (this.renderer) {
|
||||
var renderedDirectionScale = this._getRenderedDirectionAndScale();
|
||||
const renderedDirectionScale = this._getRenderedDirectionAndScale();
|
||||
this.renderer.updateDrawableProperties(this.drawableID, {
|
||||
direction: renderedDirectionScale.direction,
|
||||
scale: renderedDirectionScale.scale
|
||||
|
@ -297,16 +297,16 @@ RenderedTarget.prototype.setSize = function (size) {
|
|||
if (this.renderer) {
|
||||
// Clamp to scales relative to costume and stage size.
|
||||
// See original ScratchSprite.as:setSize.
|
||||
var costumeSize = this.renderer.getSkinSize(this.drawableID);
|
||||
var origW = costumeSize[0];
|
||||
var origH = costumeSize[1];
|
||||
var minScale = Math.min(1, Math.max(5 / origW, 5 / origH));
|
||||
var maxScale = Math.min(
|
||||
const costumeSize = this.renderer.getSkinSize(this.drawableID);
|
||||
const origW = costumeSize[0];
|
||||
const origH = costumeSize[1];
|
||||
const minScale = Math.min(1, Math.max(5 / origW, 5 / origH));
|
||||
const maxScale = Math.min(
|
||||
(1.5 * this.runtime.constructor.STAGE_WIDTH) / origW,
|
||||
(1.5 * this.runtime.constructor.STAGE_HEIGHT) / origH
|
||||
);
|
||||
this.size = MathUtil.clamp(size / 100, minScale, maxScale) * 100;
|
||||
var renderedDirectionScale = this._getRenderedDirectionAndScale();
|
||||
const renderedDirectionScale = this._getRenderedDirectionAndScale();
|
||||
this.renderer.updateDrawableProperties(this.drawableID, {
|
||||
direction: renderedDirectionScale.direction,
|
||||
scale: renderedDirectionScale.scale
|
||||
|
@ -326,7 +326,7 @@ RenderedTarget.prototype.setEffect = function (effectName, value) {
|
|||
if (!this.effects.hasOwnProperty(effectName)) return;
|
||||
this.effects[effectName] = value;
|
||||
if (this.renderer) {
|
||||
var props = {};
|
||||
const props = {};
|
||||
props[effectName] = this.effects[effectName];
|
||||
this.renderer.updateDrawableProperties(this.drawableID, props);
|
||||
if (this.visible) {
|
||||
|
@ -339,7 +339,7 @@ RenderedTarget.prototype.setEffect = function (effectName, value) {
|
|||
* Clear all graphic effects on this rendered target.
|
||||
*/
|
||||
RenderedTarget.prototype.clearEffects = function () {
|
||||
for (var effectName in this.effects) {
|
||||
for (const effectName in this.effects) {
|
||||
if (!this.effects.hasOwnProperty(effectName)) continue;
|
||||
this.effects[effectName] = 0;
|
||||
}
|
||||
|
@ -362,8 +362,8 @@ RenderedTarget.prototype.setCostume = function (index) {
|
|||
index, 0, this.sprite.costumes.length - 1
|
||||
);
|
||||
if (this.renderer) {
|
||||
var costume = this.sprite.costumes[this.currentCostume];
|
||||
var drawableProperties = {
|
||||
const costume = this.sprite.costumes[this.currentCostume];
|
||||
const drawableProperties = {
|
||||
skinId: costume.skinId,
|
||||
costumeResolution: costume.bitmapResolution
|
||||
};
|
||||
|
@ -371,7 +371,7 @@ RenderedTarget.prototype.setCostume = function (index) {
|
|||
typeof costume.rotationCenterX !== 'undefined' &&
|
||||
typeof costume.rotationCenterY !== 'undefined'
|
||||
) {
|
||||
var scale = costume.bitmapResolution || 1;
|
||||
const scale = costume.bitmapResolution || 1;
|
||||
drawableProperties.rotationCenter = [
|
||||
costume.rotationCenterX / scale,
|
||||
costume.rotationCenterY / scale
|
||||
|
@ -398,7 +398,7 @@ RenderedTarget.prototype.setRotationStyle = function (rotationStyle) {
|
|||
this.rotationStyle = RenderedTarget.ROTATION_STYLE_LEFT_RIGHT;
|
||||
}
|
||||
if (this.renderer) {
|
||||
var renderedDirectionScale = this._getRenderedDirectionAndScale();
|
||||
const renderedDirectionScale = this._getRenderedDirectionAndScale();
|
||||
this.renderer.updateDrawableProperties(this.drawableID, {
|
||||
direction: renderedDirectionScale.direction,
|
||||
scale: renderedDirectionScale.scale
|
||||
|
@ -416,7 +416,7 @@ RenderedTarget.prototype.setRotationStyle = function (rotationStyle) {
|
|||
* @return {number} Index of the named costume, or -1 if not present.
|
||||
*/
|
||||
RenderedTarget.prototype.getCostumeIndexByName = function (costumeName) {
|
||||
for (var i = 0; i < this.sprite.costumes.length; i++) {
|
||||
for (let i = 0; i < this.sprite.costumes.length; i++) {
|
||||
if (this.sprite.costumes[i].name === costumeName) {
|
||||
return i;
|
||||
}
|
||||
|
@ -454,10 +454,10 @@ RenderedTarget.prototype.getSounds = function () {
|
|||
*/
|
||||
RenderedTarget.prototype.updateAllDrawableProperties = function () {
|
||||
if (this.renderer) {
|
||||
var renderedDirectionScale = this._getRenderedDirectionAndScale();
|
||||
var costume = this.sprite.costumes[this.currentCostume];
|
||||
var bitmapResolution = costume.bitmapResolution || 1;
|
||||
var props = {
|
||||
const renderedDirectionScale = this._getRenderedDirectionAndScale();
|
||||
const costume = this.sprite.costumes[this.currentCostume];
|
||||
const bitmapResolution = costume.bitmapResolution || 1;
|
||||
const props = {
|
||||
position: [this.x, this.y],
|
||||
direction: renderedDirectionScale.direction,
|
||||
draggable: this.draggable,
|
||||
|
@ -470,7 +470,7 @@ RenderedTarget.prototype.updateAllDrawableProperties = function () {
|
|||
costume.rotationCenterY / bitmapResolution
|
||||
]
|
||||
};
|
||||
for (var effectName in this.effects) {
|
||||
for (const effectName in this.effects) {
|
||||
if (!this.effects.hasOwnProperty(effectName)) continue;
|
||||
props[effectName] = this.effects[effectName];
|
||||
}
|
||||
|
@ -522,7 +522,7 @@ RenderedTarget.prototype.isTouchingPoint = function (x, y) {
|
|||
// @todo: Update once pick is in Scratch coordinates.
|
||||
// Limits test to this Drawable, so this will return true
|
||||
// even if the clone is obscured by another Drawable.
|
||||
var pickResult = this.runtime.renderer.pick(
|
||||
const pickResult = this.runtime.renderer.pick(
|
||||
x + (this.runtime.constructor.STAGE_WIDTH / 2),
|
||||
-y + (this.runtime.constructor.STAGE_HEIGHT / 2),
|
||||
null, null,
|
||||
|
@ -539,9 +539,9 @@ RenderedTarget.prototype.isTouchingPoint = function (x, y) {
|
|||
*/
|
||||
RenderedTarget.prototype.isTouchingEdge = function () {
|
||||
if (this.renderer) {
|
||||
var stageWidth = this.runtime.constructor.STAGE_WIDTH;
|
||||
var stageHeight = this.runtime.constructor.STAGE_HEIGHT;
|
||||
var bounds = this.getBounds();
|
||||
const stageWidth = this.runtime.constructor.STAGE_WIDTH;
|
||||
const stageHeight = this.runtime.constructor.STAGE_HEIGHT;
|
||||
const bounds = this.getBounds();
|
||||
if (bounds.left < -stageWidth / 2 ||
|
||||
bounds.right > stageWidth / 2 ||
|
||||
bounds.top > stageHeight / 2 ||
|
||||
|
@ -558,13 +558,11 @@ RenderedTarget.prototype.isTouchingEdge = function () {
|
|||
* @return {boolean} True iff touching a clone of the sprite.
|
||||
*/
|
||||
RenderedTarget.prototype.isTouchingSprite = function (spriteName) {
|
||||
var firstClone = this.runtime.getSpriteTargetByName(spriteName);
|
||||
const firstClone = this.runtime.getSpriteTargetByName(spriteName);
|
||||
if (!firstClone || !this.renderer) {
|
||||
return false;
|
||||
}
|
||||
var drawableCandidates = firstClone.sprite.clones.map(function (clone) {
|
||||
return clone.drawableID;
|
||||
});
|
||||
const drawableCandidates = firstClone.sprite.clones.map(clone => clone.drawableID);
|
||||
return this.renderer.isTouchingDrawables(
|
||||
this.drawableID, drawableCandidates);
|
||||
};
|
||||
|
@ -623,7 +621,7 @@ RenderedTarget.prototype.goBackLayers = function (nLayers) {
|
|||
*/
|
||||
RenderedTarget.prototype.goBehindOther = function (other) {
|
||||
if (this.renderer) {
|
||||
var otherLayer = this.renderer.setDrawableOrder(
|
||||
const otherLayer = this.renderer.setDrawableOrder(
|
||||
other.drawableID, 0, true);
|
||||
this.renderer.setDrawableOrder(this.drawableID, otherLayer);
|
||||
}
|
||||
|
@ -637,7 +635,7 @@ RenderedTarget.prototype.goBehindOther = function (other) {
|
|||
* @return {Array.<number>} Fenced X and Y coordinates.
|
||||
*/
|
||||
RenderedTarget.prototype.keepInFence = function (newX, newY, optFence) {
|
||||
var fence = optFence;
|
||||
let fence = optFence;
|
||||
if (!fence) {
|
||||
fence = {
|
||||
left: -this.runtime.constructor.STAGE_WIDTH / 2,
|
||||
|
@ -646,7 +644,7 @@ RenderedTarget.prototype.keepInFence = function (newX, newY, optFence) {
|
|||
bottom: -this.runtime.constructor.STAGE_HEIGHT / 2
|
||||
};
|
||||
}
|
||||
var bounds = this.getBounds();
|
||||
const bounds = this.getBounds();
|
||||
if (!bounds) return;
|
||||
// Adjust the known bounds to the target position.
|
||||
bounds.left += (newX - this.x);
|
||||
|
@ -654,8 +652,8 @@ RenderedTarget.prototype.keepInFence = function (newX, newY, optFence) {
|
|||
bounds.top += (newY - this.y);
|
||||
bounds.bottom += (newY - this.y);
|
||||
// Find how far we need to move the target position.
|
||||
var dx = 0;
|
||||
var dy = 0;
|
||||
let dx = 0;
|
||||
let dy = 0;
|
||||
if (bounds.left < fence.left) {
|
||||
dx += fence.left - bounds.left;
|
||||
}
|
||||
|
@ -681,7 +679,7 @@ RenderedTarget.prototype.makeClone = function () {
|
|||
return null; // Hit max clone limit, or this is the stage.
|
||||
}
|
||||
this.runtime.changeCloneCounter(1);
|
||||
var newClone = this.sprite.createClone();
|
||||
const newClone = this.sprite.createClone();
|
||||
// Copy all properties.
|
||||
newClone.x = this.x;
|
||||
newClone.y = this.y;
|
||||
|
@ -726,7 +724,7 @@ RenderedTarget.prototype.onStopAll = function () {
|
|||
* @param {object} data An object with sprite info data to set.
|
||||
*/
|
||||
RenderedTarget.prototype.postSpriteInfo = function (data) {
|
||||
var force = data.hasOwnProperty('force') ? data.force : null;
|
||||
const force = data.hasOwnProperty('force') ? data.force : null;
|
||||
if (data.hasOwnProperty('x')) {
|
||||
this.setXY(data.x, this.y, force);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var RenderedTarget = require('./rendered-target');
|
||||
var Blocks = require('../engine/blocks');
|
||||
const RenderedTarget = require('./rendered-target');
|
||||
const Blocks = require('../engine/blocks');
|
||||
|
||||
/**
|
||||
* Sprite to be used on the Scratch stage.
|
||||
|
@ -8,7 +8,7 @@ var Blocks = require('../engine/blocks');
|
|||
* @param {Runtime} runtime Reference to the runtime.
|
||||
* @constructor
|
||||
*/
|
||||
var Sprite = function (blocks, runtime) {
|
||||
const Sprite = function (blocks, runtime) {
|
||||
this.runtime = runtime;
|
||||
if (!blocks) {
|
||||
// Shared set of blocks for all clones.
|
||||
|
@ -49,7 +49,7 @@ var Sprite = function (blocks, runtime) {
|
|||
* @returns {!RenderedTarget} Newly created clone.
|
||||
*/
|
||||
Sprite.prototype.createClone = function () {
|
||||
var newClone = new RenderedTarget(this, this.runtime);
|
||||
const newClone = new RenderedTarget(this, this.runtime);
|
||||
newClone.isOriginal = this.clones.length === 0;
|
||||
this.clones.push(newClone);
|
||||
if (newClone.isOriginal) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var Color = require('../util/color');
|
||||
const Color = require('../util/color');
|
||||
|
||||
var Cast = function () {};
|
||||
const Cast = function () {};
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
|
@ -21,7 +21,7 @@ var Cast = function () {};
|
|||
* @return {number} The Scratch-casted number value.
|
||||
*/
|
||||
Cast.toNumber = function (value) {
|
||||
var n = Number(value);
|
||||
const n = Number(value);
|
||||
if (isNaN(n)) {
|
||||
// Scratch treats NaN as 0, when needed as a number.
|
||||
// E.g., 0 + NaN -> 0.
|
||||
|
@ -71,7 +71,7 @@ Cast.toString = function (value) {
|
|||
* @return {Array.<number>} [r,g,b], values between 0-255.
|
||||
*/
|
||||
Cast.toRgbColorList = function (value) {
|
||||
var color = Cast.toRgbColorObject(value);
|
||||
const color = Cast.toRgbColorObject(value);
|
||||
return [color.r, color.g, color.b];
|
||||
};
|
||||
|
||||
|
@ -81,7 +81,7 @@ Cast.toRgbColorList = function (value) {
|
|||
* @return {RGBOject} [r,g,b], values between 0-255.
|
||||
*/
|
||||
Cast.toRgbColorObject = function (value) {
|
||||
var color;
|
||||
let color;
|
||||
if (typeof value === 'string' && value.substring(0, 1) === '#') {
|
||||
color = Color.hexToRgb(value);
|
||||
} else {
|
||||
|
@ -107,8 +107,8 @@ Cast.isWhiteSpace = function (val) {
|
|||
* @returns {number} Negative number if v1 < v2; 0 if equal; positive otherwise.
|
||||
*/
|
||||
Cast.compare = function (v1, v2) {
|
||||
var n1 = Number(v1);
|
||||
var n2 = Number(v2);
|
||||
let n1 = Number(v1);
|
||||
let n2 = Number(v2);
|
||||
if (n1 === 0 && Cast.isWhiteSpace(v1)) {
|
||||
n1 = NaN;
|
||||
} else if (n2 === 0 && Cast.isWhiteSpace(v2)) {
|
||||
|
@ -117,13 +117,13 @@ Cast.compare = function (v1, v2) {
|
|||
if (isNaN(n1) || isNaN(n2)) {
|
||||
// At least one argument can't be converted to a number.
|
||||
// Scratch compares strings as case insensitive.
|
||||
var s1 = String(v1).toLowerCase();
|
||||
var s2 = String(v2).toLowerCase();
|
||||
const s1 = String(v1).toLowerCase();
|
||||
const s2 = String(v2).toLowerCase();
|
||||
return s1.localeCompare(s2);
|
||||
} else {
|
||||
// Compare as numbers.
|
||||
return n1 - n2;
|
||||
}
|
||||
// Compare as numbers.
|
||||
return n1 - n2;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Methods for cloning JavaScript objects.
|
||||
* @type {object}
|
||||
*/
|
||||
var Clone = {};
|
||||
const Clone = {};
|
||||
|
||||
/**
|
||||
* Deep-clone a "simple" object: one which can be fully expressed with JSON.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var Color = function () {};
|
||||
const Color = function () {};
|
||||
|
||||
/**
|
||||
* @typedef {object} RGBObject - An object representing a color in RGB format.
|
||||
|
@ -29,8 +29,8 @@ Color.decimalToHex = function (decimal) {
|
|||
if (decimal < 0) {
|
||||
decimal += 0xFFFFFF + 1;
|
||||
}
|
||||
var hex = Number(decimal).toString(16);
|
||||
hex = '#' + '000000'.substr(0, 6 - hex.length) + hex;
|
||||
let hex = Number(decimal).toString(16);
|
||||
hex = `#${'000000'.substr(0, 6 - hex.length)}${hex}`;
|
||||
return hex;
|
||||
};
|
||||
|
||||
|
@ -40,10 +40,10 @@ Color.decimalToHex = function (decimal) {
|
|||
* @return {RGBObject} rgb - {r: red [0,255], g: green [0,255], b: blue [0,255]}.
|
||||
*/
|
||||
Color.decimalToRgb = function (decimal) {
|
||||
var a = (decimal >> 24) & 0xFF;
|
||||
var r = (decimal >> 16) & 0xFF;
|
||||
var g = (decimal >> 8) & 0xFF;
|
||||
var b = decimal & 0xFF;
|
||||
const a = (decimal >> 24) & 0xFF;
|
||||
const r = (decimal >> 16) & 0xFF;
|
||||
const g = (decimal >> 8) & 0xFF;
|
||||
const b = decimal & 0xFF;
|
||||
return {r: r, g: g, b: b, a: a > 0 ? a : 255};
|
||||
};
|
||||
|
||||
|
@ -55,11 +55,9 @@ Color.decimalToRgb = function (decimal) {
|
|||
* @return {RGBObject} null on failure, or rgb: {r: red [0,255], g: green [0,255], b: blue [0,255]}.
|
||||
*/
|
||||
Color.hexToRgb = function (hex) {
|
||||
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
||||
hex = hex.replace(shorthandRegex, function (m, r, g, b) {
|
||||
return r + r + g + g + b + b;
|
||||
});
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
||||
hex = hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b);
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
|
@ -100,20 +98,20 @@ Color.hexToDecimal = function (hex) {
|
|||
* @return {RGBObject} rgb - {r: red [0,255], g: green [0,255], b: blue [0,255]}.
|
||||
*/
|
||||
Color.hsvToRgb = function (hsv) {
|
||||
var h = hsv.h % 360;
|
||||
let h = hsv.h % 360;
|
||||
if (h < 0) h += 360;
|
||||
var s = Math.max(0, Math.min(hsv.s, 1));
|
||||
var v = Math.max(0, Math.min(hsv.v, 1));
|
||||
const s = Math.max(0, Math.min(hsv.s, 1));
|
||||
const v = Math.max(0, Math.min(hsv.v, 1));
|
||||
|
||||
var i = Math.floor(h / 60);
|
||||
var f = (h / 60) - i;
|
||||
var p = v * (1 - s);
|
||||
var q = v * (1 - (s * f));
|
||||
var t = v * (1 - (s * (1 - f)));
|
||||
const i = Math.floor(h / 60);
|
||||
const f = (h / 60) - i;
|
||||
const p = v * (1 - s);
|
||||
const q = v * (1 - (s * f));
|
||||
const t = v * (1 - (s * (1 - f)));
|
||||
|
||||
var r;
|
||||
var g;
|
||||
var b;
|
||||
let r;
|
||||
let g;
|
||||
let b;
|
||||
|
||||
switch (i) {
|
||||
default:
|
||||
|
@ -162,18 +160,18 @@ Color.hsvToRgb = function (hsv) {
|
|||
* @return {HSVObject} hsv - {h: hue [0,360), s: saturation [0,1], v: value [0,1]}
|
||||
*/
|
||||
Color.rgbToHsv = function (rgb) {
|
||||
var r = rgb.r / 255;
|
||||
var g = rgb.g / 255;
|
||||
var b = rgb.b / 255;
|
||||
var x = Math.min(Math.min(r, g), b);
|
||||
var v = Math.max(Math.max(r, g), b);
|
||||
const r = rgb.r / 255;
|
||||
const g = rgb.g / 255;
|
||||
const b = rgb.b / 255;
|
||||
const x = Math.min(Math.min(r, g), b);
|
||||
const v = Math.max(Math.max(r, g), b);
|
||||
|
||||
// For grays, hue will be arbitrarily reported as zero. Otherwise, calculate
|
||||
var h = 0;
|
||||
var s = 0;
|
||||
let h = 0;
|
||||
let s = 0;
|
||||
if (x !== v) {
|
||||
var f = (r === x) ? g - b : ((g === x) ? b - r : r - g);
|
||||
var i = (r === x) ? 3 : ((g === x) ? 5 : 1);
|
||||
const f = (r === x) ? g - b : ((g === x) ? b - r : r - g);
|
||||
const i = (r === x) ? 3 : ((g === x) ? 5 : 1);
|
||||
h = ((i - (f / (v - x))) * 60) % 360;
|
||||
s = (v - x) / v;
|
||||
}
|
||||
|
@ -191,7 +189,7 @@ Color.rgbToHsv = function (rgb) {
|
|||
Color.mixRgb = function (rgb0, rgb1, fraction1) {
|
||||
if (fraction1 <= 0) return rgb0;
|
||||
if (fraction1 >= 1) return rgb1;
|
||||
var fraction0 = 1 - fraction1;
|
||||
const fraction0 = 1 - fraction1;
|
||||
return {
|
||||
r: (fraction0 * rgb0.r) + (fraction1 * rgb1.r),
|
||||
g: (fraction0 * rgb0.g) + (fraction1 * rgb1.g),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var minilog = require('minilog');
|
||||
const minilog = require('minilog');
|
||||
minilog.enable();
|
||||
|
||||
module.exports = minilog('vm');
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var MathUtil = function () {};
|
||||
const MathUtil = function () {};
|
||||
|
||||
/**
|
||||
* Convert a value from degrees to radians.
|
||||
|
@ -41,7 +41,7 @@ MathUtil.clamp = function (n, min, max) {
|
|||
* @return {!number} Value of n wrapped between min and max.
|
||||
*/
|
||||
MathUtil.wrapClamp = function (n, min, max) {
|
||||
var range = (max - min) + 1;
|
||||
const range = (max - min) + 1;
|
||||
return n - (Math.floor((n - min) / range) * range);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
var StringUtil = function () {};
|
||||
const StringUtil = function () {};
|
||||
|
||||
StringUtil.withoutTrailingDigits = function (s) {
|
||||
var i = s.length - 1;
|
||||
let i = s.length - 1;
|
||||
while ((i >= 0) && ('0123456789'.indexOf(s.charAt(i)) > -1)) i--;
|
||||
return s.slice(0, i + 1);
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ StringUtil.withoutTrailingDigits = function (s) {
|
|||
StringUtil.unusedName = function (name, existingNames) {
|
||||
if (existingNames.indexOf(name) < 0) return name;
|
||||
name = StringUtil.withoutTrailingDigits(name);
|
||||
var i = 2;
|
||||
let i = 2;
|
||||
while (existingNames.indexOf(name + i) >= 0) i++;
|
||||
return name + i;
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
/**
|
||||
* @constructor
|
||||
*/
|
||||
var Timer = function () {};
|
||||
const Timer = function () {};
|
||||
|
||||
/**
|
||||
* Used to store the start time of a timer action.
|
||||
|
@ -28,13 +28,13 @@ Timer.prototype.startTime = 0;
|
|||
* However, instancing it like below (caching the self.performance to a local variable) negates most of the issues.
|
||||
* @type {boolean}
|
||||
*/
|
||||
var USE_PERFORMANCE = false;
|
||||
const USE_PERFORMANCE = false;
|
||||
|
||||
/**
|
||||
* Legacy object to allow for us to call now to get the old style date time (for backwards compatibility)
|
||||
* @deprecated This is only called via the nowObj.now() if no other means is possible...
|
||||
*/
|
||||
var legacyDateCode = {
|
||||
const legacyDateCode = {
|
||||
now: function () {
|
||||
return new Date().getTime();
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ var legacyDateCode = {
|
|||
/**
|
||||
* Use this object to route all time functions through single access points.
|
||||
*/
|
||||
var nowObj = (USE_PERFORMANCE && typeof self !== 'undefined' && self.performance && 'now' in self.performance) ?
|
||||
const nowObj = (USE_PERFORMANCE && typeof self !== 'undefined' && self.performance && 'now' in self.performance) ?
|
||||
self.performance : Date.now ? Date : legacyDateCode;
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Removed $ due to issue 251.
|
||||
* @private
|
||||
*/
|
||||
var soup_ = '!#%()*+,-./:;=?@[]^_`{|}~' +
|
||||
const soup_ = '!#%()*+,-./:;=?@[]^_`{|}~' +
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
/**
|
||||
|
@ -16,11 +16,11 @@ var soup_ = '!#%()*+,-./:;=?@[]^_`{|}~' +
|
|||
* 87 characters ^ 20 length > 128 bits (better than a UUID).
|
||||
* @return {string} A globally unique ID string.
|
||||
*/
|
||||
var uid = function () {
|
||||
var length = 20;
|
||||
var soupLength = soup_.length;
|
||||
var id = [];
|
||||
for (var i = 0; i < length; i++) {
|
||||
const uid = function () {
|
||||
const length = 20;
|
||||
const soupLength = soup_.length;
|
||||
const id = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
id[i] = soup_.charAt(Math.random() * soupLength);
|
||||
}
|
||||
return id.join('');
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* @param {!string} unsafe Unsafe string.
|
||||
* @return {string} XML-escaped string, for use within an XML tag.
|
||||
*/
|
||||
var xmlEscape = function (unsafe) {
|
||||
return unsafe.replace(/[<>&'"]/g, function (c) {
|
||||
const xmlEscape = function (unsafe) {
|
||||
return unsafe.replace(/[<>&'"]/g, c => {
|
||||
switch (c) {
|
||||
case '<': return '<';
|
||||
case '>': return '>';
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
var EventEmitter = require('events');
|
||||
var util = require('util');
|
||||
const EventEmitter = require('events');
|
||||
const util = require('util');
|
||||
|
||||
var log = require('./util/log');
|
||||
var Runtime = require('./engine/runtime');
|
||||
var ScratchStorage = require('scratch-storage');
|
||||
var sb2import = require('./import/sb2import');
|
||||
var StringUtil = require('./util/string-util');
|
||||
const log = require('./util/log');
|
||||
const Runtime = require('./engine/runtime');
|
||||
const ScratchStorage = require('scratch-storage');
|
||||
const sb2import = require('./import/sb2import');
|
||||
const StringUtil = require('./util/string-util');
|
||||
|
||||
var loadCostume = require('./import/load-costume.js');
|
||||
var loadSound = require('./import/load-sound.js');
|
||||
const loadCostume = require('./import/load-costume.js');
|
||||
const loadSound = require('./import/load-sound.js');
|
||||
|
||||
var RESERVED_NAMES = ['_mouse_', '_stage_', '_edge_', '_myself_', '_random_'];
|
||||
const RESERVED_NAMES = ['_mouse_', '_stage_', '_edge_', '_myself_', '_random_'];
|
||||
|
||||
var AssetType = ScratchStorage.AssetType;
|
||||
const AssetType = ScratchStorage.AssetType;
|
||||
|
||||
/**
|
||||
* Handles connections between blocks, stage, and extensions.
|
||||
* @constructor
|
||||
*/
|
||||
var VirtualMachine = function () {
|
||||
var instance = this;
|
||||
const VirtualMachine = function () {
|
||||
const instance = this;
|
||||
// Bind event emitter and runtime to VM instance
|
||||
EventEmitter.call(instance);
|
||||
/**
|
||||
|
@ -34,28 +34,28 @@ var VirtualMachine = function () {
|
|||
*/
|
||||
instance.editingTarget = null;
|
||||
// Runtime emits are passed along as VM emits.
|
||||
instance.runtime.on(Runtime.SCRIPT_GLOW_ON, function (glowData) {
|
||||
instance.runtime.on(Runtime.SCRIPT_GLOW_ON, glowData => {
|
||||
instance.emit(Runtime.SCRIPT_GLOW_ON, glowData);
|
||||
});
|
||||
instance.runtime.on(Runtime.SCRIPT_GLOW_OFF, function (glowData) {
|
||||
instance.runtime.on(Runtime.SCRIPT_GLOW_OFF, glowData => {
|
||||
instance.emit(Runtime.SCRIPT_GLOW_OFF, glowData);
|
||||
});
|
||||
instance.runtime.on(Runtime.BLOCK_GLOW_ON, function (glowData) {
|
||||
instance.runtime.on(Runtime.BLOCK_GLOW_ON, glowData => {
|
||||
instance.emit(Runtime.BLOCK_GLOW_ON, glowData);
|
||||
});
|
||||
instance.runtime.on(Runtime.BLOCK_GLOW_OFF, function (glowData) {
|
||||
instance.runtime.on(Runtime.BLOCK_GLOW_OFF, glowData => {
|
||||
instance.emit(Runtime.BLOCK_GLOW_OFF, glowData);
|
||||
});
|
||||
instance.runtime.on(Runtime.PROJECT_RUN_START, function () {
|
||||
instance.runtime.on(Runtime.PROJECT_RUN_START, () => {
|
||||
instance.emit(Runtime.PROJECT_RUN_START);
|
||||
});
|
||||
instance.runtime.on(Runtime.PROJECT_RUN_STOP, function () {
|
||||
instance.runtime.on(Runtime.PROJECT_RUN_STOP, () => {
|
||||
instance.emit(Runtime.PROJECT_RUN_STOP);
|
||||
});
|
||||
instance.runtime.on(Runtime.VISUAL_REPORT, function (visualReport) {
|
||||
instance.runtime.on(Runtime.VISUAL_REPORT, visualReport => {
|
||||
instance.emit(Runtime.VISUAL_REPORT, visualReport);
|
||||
});
|
||||
instance.runtime.on(Runtime.SPRITE_INFO_REPORT, function (spriteInfo) {
|
||||
instance.runtime.on(Runtime.SPRITE_INFO_REPORT, spriteInfo => {
|
||||
instance.emit(Runtime.SPRITE_INFO_REPORT, spriteInfo);
|
||||
});
|
||||
|
||||
|
@ -120,13 +120,11 @@ VirtualMachine.prototype.clear = function () {
|
|||
* Get data for playground. Data comes back in an emitted event.
|
||||
*/
|
||||
VirtualMachine.prototype.getPlaygroundData = function () {
|
||||
var instance = this;
|
||||
const instance = this;
|
||||
// Only send back thread data for the current editingTarget.
|
||||
var threadData = this.runtime.threads.filter(function (thread) {
|
||||
return thread.target === instance.editingTarget;
|
||||
});
|
||||
const threadData = this.runtime.threads.filter(thread => thread.target === instance.editingTarget);
|
||||
// Remove the target key, since it's a circular reference.
|
||||
var filteredThreadData = JSON.stringify(threadData, function (key, value) {
|
||||
const filteredThreadData = JSON.stringify(threadData, (key, value) => {
|
||||
if (key === 'target') return;
|
||||
return value;
|
||||
}, 2);
|
||||
|
@ -172,9 +170,9 @@ VirtualMachine.prototype.downloadProjectId = function (id) {
|
|||
log.error('No storage module present; cannot load project: ', id);
|
||||
return;
|
||||
}
|
||||
var vm = this;
|
||||
var promise = this.runtime.storage.load(AssetType.Project, id);
|
||||
promise.then(function (projectAsset) {
|
||||
const vm = this;
|
||||
const promise = this.runtime.storage.load(AssetType.Project, id);
|
||||
promise.then(projectAsset => {
|
||||
vm.loadProject(projectAsset.decodeText());
|
||||
});
|
||||
};
|
||||
|
@ -202,12 +200,12 @@ VirtualMachine.prototype.addSprite2 = function (json) {
|
|||
* @property {number} [bitmapResolution] - the resolution scale for a bitmap costume.
|
||||
*/
|
||||
VirtualMachine.prototype.addCostume = function (md5ext, costumeObject) {
|
||||
loadCostume(md5ext, costumeObject, this.runtime).then(function () {
|
||||
loadCostume(md5ext, costumeObject, this.runtime).then(() => {
|
||||
this.editingTarget.sprite.costumes.push(costumeObject);
|
||||
this.editingTarget.setCostume(
|
||||
this.editingTarget.sprite.costumes.length - 1
|
||||
);
|
||||
}.bind(this));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -216,10 +214,10 @@ VirtualMachine.prototype.addCostume = function (md5ext, costumeObject) {
|
|||
* @returns {?Promise} - a promise that resolves when the sound has been decoded and added
|
||||
*/
|
||||
VirtualMachine.prototype.addSound = function (soundObject) {
|
||||
return loadSound(soundObject, this.runtime).then(function () {
|
||||
return loadSound(soundObject, this.runtime).then(() => {
|
||||
this.editingTarget.sprite.sounds.push(soundObject);
|
||||
this.emitTargetsUpdate();
|
||||
}.bind(this));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -232,11 +230,11 @@ VirtualMachine.prototype.addSound = function (soundObject) {
|
|||
* @property {number} [bitmapResolution] - the resolution scale for a bitmap backdrop.
|
||||
*/
|
||||
VirtualMachine.prototype.addBackdrop = function (md5ext, backdropObject) {
|
||||
loadCostume(md5ext, backdropObject, this.runtime).then(function () {
|
||||
var stage = this.runtime.getTargetForStage();
|
||||
loadCostume(md5ext, backdropObject, this.runtime).then(() => {
|
||||
const stage = this.runtime.getTargetForStage();
|
||||
stage.sprite.costumes.push(backdropObject);
|
||||
stage.setCostume(stage.sprite.costumes.length - 1);
|
||||
}.bind(this));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -245,21 +243,17 @@ VirtualMachine.prototype.addBackdrop = function (md5ext, backdropObject) {
|
|||
* @param {string} newName New name of the sprite.
|
||||
*/
|
||||
VirtualMachine.prototype.renameSprite = function (targetId, newName) {
|
||||
var target = this.runtime.getTargetById(targetId);
|
||||
const target = this.runtime.getTargetById(targetId);
|
||||
if (target) {
|
||||
if (!target.isSprite()) {
|
||||
throw new Error('Cannot rename non-sprite targets.');
|
||||
}
|
||||
var sprite = target.sprite;
|
||||
const sprite = target.sprite;
|
||||
if (!sprite) {
|
||||
throw new Error('No sprite associated with this target.');
|
||||
}
|
||||
if (newName && RESERVED_NAMES.indexOf(newName) === -1) {
|
||||
var names = this.runtime.targets.filter(function (runtimeTarget) {
|
||||
return runtimeTarget.isSprite();
|
||||
}).map(function (runtimeTarget) {
|
||||
return runtimeTarget.sprite.name;
|
||||
});
|
||||
const names = this.runtime.targets.filter(runtimeTarget => runtimeTarget.isSprite()).map(runtimeTarget => runtimeTarget.sprite.name);
|
||||
|
||||
sprite.name = StringUtil.unusedName(newName, names);
|
||||
}
|
||||
|
@ -274,18 +268,18 @@ VirtualMachine.prototype.renameSprite = function (targetId, newName) {
|
|||
* @param {string} targetId ID of a target whose sprite to delete.
|
||||
*/
|
||||
VirtualMachine.prototype.deleteSprite = function (targetId) {
|
||||
var target = this.runtime.getTargetById(targetId);
|
||||
const target = this.runtime.getTargetById(targetId);
|
||||
if (target) {
|
||||
if (!target.isSprite()) {
|
||||
throw new Error('Cannot delete non-sprite targets.');
|
||||
}
|
||||
var sprite = target.sprite;
|
||||
const sprite = target.sprite;
|
||||
if (!sprite) {
|
||||
throw new Error('No sprite associated with this target.');
|
||||
}
|
||||
var currentEditingTarget = this.editingTarget;
|
||||
for (var i = 0; i < sprite.clones.length; i++) {
|
||||
var clone = sprite.clones[i];
|
||||
const currentEditingTarget = this.editingTarget;
|
||||
for (let i = 0; i < sprite.clones.length; i++) {
|
||||
const clone = sprite.clones[i];
|
||||
this.runtime.stopForTarget(sprite.clones[i]);
|
||||
this.runtime.disposeTarget(sprite.clones[i]);
|
||||
// Ensure editing target is switched if we are deleting it.
|
||||
|
@ -355,7 +349,7 @@ VirtualMachine.prototype.setEditingTarget = function (targetId) {
|
|||
if (targetId === this.editingTarget.id) {
|
||||
return;
|
||||
}
|
||||
var target = this.runtime.getTargetById(targetId);
|
||||
const target = this.runtime.getTargetById(targetId);
|
||||
if (target) {
|
||||
this.editingTarget = target;
|
||||
// Emit appropriate UI updates.
|
||||
|
@ -373,12 +367,9 @@ VirtualMachine.prototype.setEditingTarget = function (targetId) {
|
|||
VirtualMachine.prototype.emitTargetsUpdate = function () {
|
||||
this.emit('targetsUpdate', {
|
||||
// [[target id, human readable target name], ...].
|
||||
targetList: this.runtime.targets.filter(function (target) {
|
||||
targetList: this.runtime.targets.filter(target =>
|
||||
// Don't report clones.
|
||||
return !target.hasOwnProperty('isOriginal') || target.isOriginal;
|
||||
}).map(function (target) {
|
||||
return target.toJSON();
|
||||
}),
|
||||
!target.hasOwnProperty('isOriginal') || target.isOriginal).map(target => target.toJSON()),
|
||||
// Currently editing target id.
|
||||
editingTarget: this.editingTarget ? this.editingTarget.id : null
|
||||
});
|
||||
|
@ -400,7 +391,7 @@ VirtualMachine.prototype.emitWorkspaceUpdate = function () {
|
|||
* @returns {?string} The target id, if found. Will also be null if the target found is the stage.
|
||||
*/
|
||||
VirtualMachine.prototype.getTargetIdForDrawableId = function (drawableId) {
|
||||
var target = this.runtime.getTargetByDrawableId(drawableId);
|
||||
const target = this.runtime.getTargetByDrawableId(drawableId);
|
||||
if (target && target.hasOwnProperty('id') && target.hasOwnProperty('isStage') && !target.isStage) {
|
||||
return target.id;
|
||||
}
|
||||
|
@ -413,7 +404,7 @@ VirtualMachine.prototype.getTargetIdForDrawableId = function (drawableId) {
|
|||
* @param {string} targetId The id for the target to put into a drag state
|
||||
*/
|
||||
VirtualMachine.prototype.startDrag = function (targetId) {
|
||||
var target = this.runtime.getTargetById(targetId);
|
||||
const target = this.runtime.getTargetById(targetId);
|
||||
if (target) {
|
||||
target.startDrag();
|
||||
this.setEditingTarget(target.id);
|
||||
|
@ -425,7 +416,7 @@ VirtualMachine.prototype.startDrag = function (targetId) {
|
|||
* @param {string} targetId The id for the target to remove from the drag state
|
||||
*/
|
||||
VirtualMachine.prototype.stopDrag = function (targetId) {
|
||||
var target = this.runtime.getTargetById(targetId);
|
||||
const target = this.runtime.getTargetById(targetId);
|
||||
if (target) target.stopDrag();
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue