mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-23 06:23:37 -05:00
Merge branch 'develop' into sensor-error
This commit is contained in:
commit
2856b32dd5
14 changed files with 74 additions and 40 deletions
|
@ -165,7 +165,10 @@ class Scratch3ControlBlocks {
|
|||
// Create clone
|
||||
const newClone = cloneTarget.makeClone();
|
||||
if (newClone) {
|
||||
this.runtime.targets.push(newClone);
|
||||
this.runtime.addTarget(newClone);
|
||||
|
||||
// Place behind the original target.
|
||||
newClone.goBehindOther(cloneTarget);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1560,11 +1560,14 @@ class Runtime extends EventEmitter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a target to the execution order.
|
||||
* @param {Target} executableTarget target to add
|
||||
* Add a target to the runtime. This tracks the sprite pane
|
||||
* ordering of the target. The target still needs to be put
|
||||
* into the correct execution order after calling this function.
|
||||
* @param {Target} target target to add
|
||||
*/
|
||||
addExecutable (executableTarget) {
|
||||
this.executableTargets.push(executableTarget);
|
||||
addTarget (target) {
|
||||
this.targets.push(target);
|
||||
this.executableTargets.push(target);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -69,10 +69,6 @@ class Target extends EventEmitter {
|
|||
* @type {Object.<string, *>}
|
||||
*/
|
||||
this._edgeActivatedHatValues = {};
|
||||
|
||||
if (this.runtime) {
|
||||
this.runtime.addExecutable(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,7 +13,7 @@ const ScratchLinkDeviceAdapter = require('./scratch-link-device-adapter');
|
|||
* @type {string}
|
||||
*/
|
||||
// eslint-disable-next-line max-len
|
||||
const blockIconURI = 'data:image/png;base64,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';
|
||||
const blockIconURI = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoOCAuNSkiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0iTTEyIDM5LjVBMi41IDIuNSAwIDAgMSA5LjUgMzdjMC0uMy4yLS41LjUtLjVzLjUuMi41LjVhMS41IDEuNSAwIDEgMCAzIDB2LS4yYzAtLjQtLjItLjgtLjUtMWwtLjgtLjljLS41LS40LS43LTEtLjctMS43VjMxYzAtLjMuMi0uNS41LS41cy41LjIuNS41djIuMmMwIC40LjEuOC40IDFsLjguOWMuNS40LjggMSAuOCAxLjd2LjJjMCAxLjQtMS4xIDIuNS0yLjUgMi41eiIgZmlsbD0iI0U2RTdFOCIvPjxwYXRoIGQ9Ik0yMy43LjNBMSAxIDAgMCAwIDIzIDBIMWExIDEgMCAwIDAtLjcuM0ExIDEgMCAwIDAgMCAxdjI2YzAgLjMuMS41LjMuNy4yLjIuNC4zLjcuM2gyMmMuMyAwIC41LS4xLjctLjMuMi0uMi4zLS40LjMtLjdWMWExIDEgMCAwIDAtLjMtLjd6TTEyIDRjMiAwIDMuMyAyIDIuNiAzLjhMMTMuMyAxMWExLjQgMS40IDAgMCAxLTIuNyAwTDkuNSA3LjdsLS4yLTFDOS4yIDUuNCAxMC40IDQgMTIgNHoiIHN0cm9rZT0iIzdDODdBNSIgZmlsbD0iIzg1OTJBRiIgZmlsbC1ydWxlPSJub256ZXJvIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48cGF0aCBkPSJNMiAydjI0aDIwVjJIMnptMTAgMmMyIDAgMy4zIDIgMi42IDMuOEwxMy4zIDExYTEuNCAxLjQgMCAwIDEtMi43IDBMOS41IDcuN2wtLjItMUM5LjIgNS40IDEwLjQgNCAxMiA0eiIgc3Ryb2tlPSIjN0M4N0E1IiBmaWxsPSIjNUNCMUQ2IiBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIHN0cm9rZT0iIzdDODdBNSIgZmlsbD0iIzg1OTJBRiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNMjIgMjZIMnYtNmwyMC00eiIvPjxwYXRoIGQ9Ik0uMyAyNy43TDIgMjZNLjMuM0wyIDJNMjIgMkwyMy43LjNNMjMuNyAyNy43TDIyIDI2IiBzdHJva2U9IiM3Qzg3QTUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxjaXJjbGUgZmlsbD0iI0ZGQkYwMCIgY3g9IjEyIiBjeT0iMTQuOCIgcj0iMS4yIi8+PHBhdGggc3Ryb2tlPSIjN0M4N0E1IiBmaWxsPSIjRTZFN0U4IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik0xMCAyOGg0djRoLTR6Ii8+PHBhdGggZD0iTTE1LjUgMjJoLTdhLjUuNSAwIDAgMS0uNS0uNWMwLS4zLjItLjUuNS0uNWg3Yy4zIDAgLjUuMi41LjVzLS4yLjUtLjUuNXpNMTcuNSAyNGgtMTFhLjUuNSAwIDAgMS0uNS0uNWMwLS4zLjItLjUuNS0uNWgxMWMuMyAwIC41LjIuNS41cy0uMi41LS41LjV6IiBmaWxsPSIjRkZCRjAwIi8+PC9nPjwvc3ZnPg==';
|
||||
|
||||
/**
|
||||
* Enum for Vernier godirect protocol.
|
||||
|
@ -76,8 +76,8 @@ class GdxFor {
|
|||
* Called by the runtime when user wants to scan for a peripheral.
|
||||
*/
|
||||
scan () {
|
||||
if (this._device) {
|
||||
this._device.close();
|
||||
if (this._scratchLinkSocket) {
|
||||
this._scratchLinkSocket.disconnect();
|
||||
}
|
||||
|
||||
this._scratchLinkSocket = new BLE(this._runtime, this._extensionId, {
|
||||
|
@ -105,10 +105,9 @@ class GdxFor {
|
|||
* Disconnect from the GDX FOR.
|
||||
*/
|
||||
disconnect () {
|
||||
if (this._device) {
|
||||
this._device.close();
|
||||
this._device = null;
|
||||
this._sensorsEnabled = false;
|
||||
this._sensorsEnabled = false;
|
||||
if (this._scratchLinkSocket) {
|
||||
this._scratchLinkSocket.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,6 @@ class ScratchLinkDeviceAdapter {
|
|||
const response = new DataView(array.buffer);
|
||||
return this._deviceOnResponse(response);
|
||||
}
|
||||
|
||||
close () {
|
||||
return this.scratchLinkSocket.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ScratchLinkDeviceAdapter;
|
||||
|
|
|
@ -781,14 +781,17 @@ const reorderParsedTargets = function (targets) {
|
|||
// Reorder parsed targets based on the temporary targetPaneOrder property
|
||||
// and then delete it.
|
||||
|
||||
targets.sort((a, b) => a.targetPaneOrder - b.targetPaneOrder);
|
||||
const reordered = targets.map((t, index) => {
|
||||
t.layerOrder = index;
|
||||
return t;
|
||||
}).sort((a, b) => a.targetPaneOrder - b.targetPaneOrder);
|
||||
|
||||
// Delete the temporary target pane ordering since we shouldn't need it anymore.
|
||||
targets.forEach(t => {
|
||||
reordered.forEach(t => {
|
||||
delete t.targetPaneOrder;
|
||||
});
|
||||
|
||||
return targets;
|
||||
return reordered;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1157,12 +1157,18 @@ const deserialize = function (json, runtime, zip, isSingleSprite) {
|
|||
parseScratchObject(target, runtime, extensions, zip))
|
||||
)
|
||||
.then(targets => targets // Re-sort targets back into original sprite-pane ordering
|
||||
.map((t, i) => {
|
||||
// Add layer order property to deserialized targets.
|
||||
// This property is used to initialize executable targets in
|
||||
// the correct order and is deleted in VM's installTargets function
|
||||
t.layerOrder = i;
|
||||
return t;
|
||||
})
|
||||
.sort((a, b) => a.targetPaneOrder - b.targetPaneOrder)
|
||||
.map(t => {
|
||||
// Delete the temporary properties used for
|
||||
// sprite pane ordering and stage layer ordering
|
||||
delete t.targetPaneOrder;
|
||||
delete t.layerOrder;
|
||||
return t;
|
||||
}))
|
||||
.then(targets => {
|
||||
|
|
|
@ -1021,8 +1021,6 @@ class RenderedTarget extends Target {
|
|||
newClone._edgeActivatedHatValues = Clone.simple(this._edgeActivatedHatValues);
|
||||
newClone.initDrawable(StageLayering.SPRITE_LAYER);
|
||||
newClone.updateAllDrawableProperties();
|
||||
// Place behind the current target.
|
||||
newClone.goBehindOther(this);
|
||||
return newClone;
|
||||
}
|
||||
|
||||
|
@ -1046,7 +1044,6 @@ class RenderedTarget extends Target {
|
|||
newTarget.effects = JSON.parse(JSON.stringify(this.effects));
|
||||
newTarget.variables = this.duplicateVariables(newTarget.blocks);
|
||||
newTarget.updateAllDrawableProperties();
|
||||
newTarget.goBehindOther(this);
|
||||
return newTarget;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -495,11 +495,18 @@ class VirtualMachine extends EventEmitter {
|
|||
|
||||
return Promise.all(extensionPromises).then(() => {
|
||||
targets.forEach(target => {
|
||||
this.runtime.targets.push(target);
|
||||
this.runtime.addTarget(target);
|
||||
(/** @type RenderedTarget */ target).updateAllDrawableProperties();
|
||||
// Ensure unique sprite name
|
||||
if (target.isSprite()) this.renameSprite(target.id, target.getName());
|
||||
});
|
||||
// Sort the executable targets by layerOrder.
|
||||
// Remove layerOrder property after use.
|
||||
this.runtime.executableTargets.sort((a, b) => a.layerOrder - b.layerOrder);
|
||||
targets.forEach(target => {
|
||||
delete target.layerOrder;
|
||||
});
|
||||
|
||||
// Select the first target for editing, e.g., the first sprite.
|
||||
if (wholeProject && (targets.length > 1)) {
|
||||
this.editingTarget = targets[1];
|
||||
|
@ -1016,7 +1023,8 @@ class VirtualMachine extends EventEmitter {
|
|||
throw new Error('No sprite associated with this target.');
|
||||
}
|
||||
return target.duplicate().then(newTarget => {
|
||||
this.runtime.targets.push(newTarget);
|
||||
this.runtime.addTarget(newTarget);
|
||||
newTarget.goBehindOther(target);
|
||||
this.setEditingTarget(newTarget.id);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -192,7 +192,8 @@ test('edge activated hat should trigger for both sprites when sprite is cloned',
|
|||
val + Object.keys(target._edgeActivatedHatValues).length, 0);
|
||||
t.equal(numTargetEdgeHats, 1);
|
||||
|
||||
vm.runtime.targets.push(vm.runtime.targets[1].makeClone());
|
||||
const cloneTarget = vm.runtime.targets[1].makeClone();
|
||||
vm.runtime.addTarget(cloneTarget);
|
||||
|
||||
vm.runtime._step();
|
||||
// Check that the runtime's _edgeActivatedHatValues object has two separate keys
|
||||
|
|
|
@ -54,7 +54,8 @@ test('#760 - broadcastAndWait', t => {
|
|||
const tgt = new Target(rt, b);
|
||||
tgt.isStage = true;
|
||||
tgt.createVariable('testBroadcastID', 'message', Variable.BROADCAST_MESSAGE_TYPE);
|
||||
rt.targets.push(tgt);
|
||||
|
||||
rt.addTarget(tgt);
|
||||
|
||||
let th = rt._pushThread('broadcastAndWaitBlock', t);
|
||||
const util = new BlockUtility();
|
||||
|
|
|
@ -48,7 +48,7 @@ const testCostume = (costumes, arg, currentCostume = 1, isStage = false) => {
|
|||
|
||||
if (isStage) {
|
||||
target.isStage = true;
|
||||
rt.targets.push(target);
|
||||
rt.addTarget(target);
|
||||
looks.switchBackdrop({BACKDROP: arg}, {target});
|
||||
} else {
|
||||
looks.switchCostume({COSTUME: arg}, {target});
|
||||
|
|
|
@ -188,7 +188,7 @@ test('renameVariable calls cloud io device\'s requestRenameVariable function', t
|
|||
target.isStage = true;
|
||||
const mockCloudVar = new Variable('foo', 'bar', Variable.SCALAR_TYPE, true);
|
||||
target.variables[mockCloudVar.id] = mockCloudVar;
|
||||
runtime.targets.push(target);
|
||||
runtime.addTarget(target);
|
||||
|
||||
target.renameVariable('foo', 'bar2');
|
||||
|
||||
|
@ -215,7 +215,7 @@ test('renameVariable does not call cloud io device\'s requestRenameVariable func
|
|||
const target = new Target(runtime);
|
||||
const mockCloudVar = new Variable('foo', 'bar', Variable.SCALAR_TYPE, true);
|
||||
target.variables[mockCloudVar.id] = mockCloudVar;
|
||||
runtime.targets.push(target);
|
||||
runtime.addTarget(target);
|
||||
|
||||
target.renameVariable('foo', 'bar2');
|
||||
|
||||
|
@ -266,7 +266,7 @@ test('deleteVariable calls cloud io device\'s requestRenameVariable function', t
|
|||
target.isStage = true;
|
||||
const mockCloudVar = new Variable('foo', 'bar', Variable.SCALAR_TYPE, true);
|
||||
target.variables[mockCloudVar.id] = mockCloudVar;
|
||||
runtime.targets.push(target);
|
||||
runtime.addTarget(target);
|
||||
|
||||
target.deleteVariable('foo');
|
||||
|
||||
|
@ -288,7 +288,7 @@ test('deleteVariable calls cloud io device\'s requestRenameVariable function', t
|
|||
const target = new Target(runtime);
|
||||
const mockCloudVar = new Variable('foo', 'bar', Variable.SCALAR_TYPE, true);
|
||||
target.variables[mockCloudVar.id] = mockCloudVar;
|
||||
runtime.targets.push(target);
|
||||
runtime.addTarget(target);
|
||||
|
||||
target.deleteVariable('foo');
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const test = require('tap').test;
|
||||
const path = require('path');
|
||||
const VirtualMachine = require('../../src/index');
|
||||
const Runtime = require('../../src/engine/runtime');
|
||||
const sb3 = require('../../src/serialization/sb3');
|
||||
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
|
||||
const exampleProjectPath = path.resolve(__dirname, '../fixtures/clone-cleanup.sb2');
|
||||
|
@ -147,10 +148,10 @@ test('deserialize sb3 project with comments - no duplicate id serialization', t
|
|||
});
|
||||
});
|
||||
|
||||
test('serialize sb3 preserves sprite layer order', t => {
|
||||
test('serializing and deserializing sb3 preserves sprite layer order', t => {
|
||||
const vm = new VirtualMachine();
|
||||
vm.attachRenderer(new FakeRenderer());
|
||||
vm.loadProject(readFileToBuffer(path.resolve(__dirname, '../fixtures/ordering.sb2')))
|
||||
return vm.loadProject(readFileToBuffer(path.resolve(__dirname, '../fixtures/ordering.sb2')))
|
||||
.then(() => {
|
||||
// Target get layer order needs a renderer,
|
||||
// fake the numbers we would get back from the
|
||||
|
@ -182,8 +183,28 @@ test('serialize sb3 preserves sprite layer order', t => {
|
|||
t.equal(result.targets[2].layerOrder, 1);
|
||||
t.equal(result.targets[3].layerOrder, 3);
|
||||
|
||||
t.end();
|
||||
});
|
||||
return result;
|
||||
})
|
||||
.then(serializedObject =>
|
||||
sb3.deserialize(
|
||||
JSON.parse(JSON.stringify(serializedObject)), new Runtime(), null, false)
|
||||
.then(({targets}) => {
|
||||
// First check that the sprites are ordered correctly (as they would
|
||||
// appear in the target pane)
|
||||
t.equal(targets[0].sprite.name, 'Stage');
|
||||
t.equal(targets[1].sprite.name, 'First');
|
||||
t.equal(targets[2].sprite.name, 'Second');
|
||||
t.equal(targets[3].sprite.name, 'Third');
|
||||
|
||||
// Check that they are in the correct layer order (as they would render
|
||||
// back to front on the stage)
|
||||
t.equal(targets[0].layerOrder, 0);
|
||||
t.equal(targets[1].layerOrder, 2);
|
||||
t.equal(targets[2].layerOrder, 1);
|
||||
t.equal(targets[3].layerOrder, 3);
|
||||
|
||||
t.end();
|
||||
}));
|
||||
});
|
||||
|
||||
test('serializeBlocks', t => {
|
||||
|
|
Loading…
Reference in a new issue