mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-01-11 10:39:56 -05:00
WIP for demo
This commit is contained in:
parent
aaa7784d39
commit
d43749d675
6 changed files with 78 additions and 13 deletions
|
@ -115,6 +115,12 @@ class SharedDispatch {
|
|||
_remoteTransferCall (provider, service, method, transfer, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const responseId = this._storeCallbacks(resolve, reject);
|
||||
|
||||
/** @TODO: remove this hack! this is just here so we don't try to send `util` to a worker */
|
||||
if ((args.length > 0) && (typeof args[args.length - 1].yield === 'function')) {
|
||||
args.pop();
|
||||
}
|
||||
|
||||
if (transfer) {
|
||||
provider.postMessage({service, method, responseId, args}, transfer);
|
||||
} else {
|
||||
|
|
|
@ -294,6 +294,14 @@ class Runtime extends EventEmitter {
|
|||
return 'MONITORS_UPDATE';
|
||||
}
|
||||
|
||||
/**
|
||||
* Event name for reporting that an extension was added.
|
||||
* @const {string}
|
||||
*/
|
||||
static get EXTENSION_WAS_ADDED () {
|
||||
return 'EXTENSION_WAS_ADDED';
|
||||
}
|
||||
|
||||
/**
|
||||
* How rapidly we try to step threads by default, in ms.
|
||||
*/
|
||||
|
@ -371,10 +379,12 @@ class Runtime extends EventEmitter {
|
|||
|
||||
for (const blockInfo of extensionInfo.blocks) {
|
||||
const convertedBlock = this._convertForScratchBlocks(blockInfo, categoryInfo);
|
||||
const opcode = convertedBlock.json.id;
|
||||
const opcode = convertedBlock.json.type;
|
||||
categoryInfo.blocks.push(convertedBlock);
|
||||
this._primitives[opcode] = convertedBlock.info.func;
|
||||
}
|
||||
|
||||
this.emit(Runtime.EXTENSION_WAS_ADDED, categoryInfo.blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -387,10 +397,8 @@ class Runtime extends EventEmitter {
|
|||
_convertForScratchBlocks (blockInfo, categoryInfo) {
|
||||
const extendedOpcode = `${categoryInfo.id}.${blockInfo.opcode}`;
|
||||
const blockJSON = {
|
||||
id: extendedOpcode,
|
||||
type: extendedOpcode,
|
||||
inputsInline: true,
|
||||
previousStatement: null, // null = available connection; undefined = hat block
|
||||
nextStatement: null, // null = available connection; undefined = terminal
|
||||
category: categoryInfo.name,
|
||||
colour: categoryInfo.color1,
|
||||
colourSecondary: categoryInfo.color2,
|
||||
|
@ -436,6 +444,10 @@ class Runtime extends EventEmitter {
|
|||
switch (blockInfo.blockType) {
|
||||
case BlockType.COMMAND:
|
||||
blockJSON.outputShape = ScratchBlocks.OUTPUT_SHAPE_SQUARE;
|
||||
blockJSON.previousStatement = null; // null = available connection; undefined = hat
|
||||
if (!blockInfo.isTerminal) {
|
||||
blockJSON.nextStatement = null; // null = available connection; undefined = terminal
|
||||
}
|
||||
break;
|
||||
case BlockType.REPORTER:
|
||||
blockJSON.output = 'String'; // TODO: distinguish number & string here?
|
||||
|
@ -447,7 +459,7 @@ class Runtime extends EventEmitter {
|
|||
break;
|
||||
case BlockType.HAT:
|
||||
blockJSON.outputShape = ScratchBlocks.OUTPUT_SHAPE_SQUARE;
|
||||
delete blockJSON.previousStatement;
|
||||
blockJSON.nextStatement = null; // null = available connection; undefined = terminal
|
||||
break;
|
||||
case BlockType.CONDITIONAL:
|
||||
// Statement inputs get names like 'SUBSTACK', 'SUBSTACK2', 'SUBSTACK3', ...
|
||||
|
@ -458,6 +470,8 @@ class Runtime extends EventEmitter {
|
|||
};
|
||||
}
|
||||
blockJSON.outputShape = ScratchBlocks.OUTPUT_SHAPE_SQUARE;
|
||||
blockJSON.previousStatement = null; // null = available connection; undefined = hat
|
||||
blockJSON.nextStatement = null; // null = available connection; undefined = terminal
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -659,7 +673,7 @@ class Runtime extends EventEmitter {
|
|||
if (this.threads[i].topBlock === topBlockId && this.threads[i].status !== Thread.STATUS_DONE) {
|
||||
const blockContainer = opts.target.blocks;
|
||||
const opcode = blockContainer.getOpcode(blockContainer.getBlock(topBlockId));
|
||||
|
||||
|
||||
if (this.getIsEdgeActivatedHat(opcode) && this.threads[i].stackClick !== opts.stackClick) {
|
||||
// Allow edge activated hat thread stack click to coexist with
|
||||
// edge activated hat thread that runs every frame
|
||||
|
|
|
@ -65,10 +65,6 @@ class ExtensionManager {
|
|||
});
|
||||
}
|
||||
|
||||
foo () {
|
||||
return this.loadExtensionURL('extensions/example-extension.js');
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an extension by URL
|
||||
* @param {string} extensionURL - the URL for the extension to load
|
||||
|
@ -77,7 +73,7 @@ class ExtensionManager {
|
|||
loadExtensionURL (extensionURL) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// If we `require` this at the global level it breaks non-webpack targets, including tests
|
||||
const ExtensionWorker = require('worker-loader!./extension-worker');
|
||||
const ExtensionWorker = require('worker-loader?name=extension-worker.js!./extension-worker');
|
||||
|
||||
this.pendingExtensions.push({extensionURL, resolve, reject});
|
||||
dispatch.addWorker(new ExtensionWorker());
|
||||
|
|
|
@ -33,6 +33,28 @@ class ExampleExtension {
|
|||
// Required: the list of blocks implemented by this extension,
|
||||
// in the order intended for display.
|
||||
blocks: [
|
||||
{
|
||||
opcode: 'example-noop',
|
||||
blockType: Scratch.BlockType.COMMAND,
|
||||
blockAllThreads: false,
|
||||
text: 'do nothing',
|
||||
func: 'noop'
|
||||
},
|
||||
{
|
||||
opcode: 'example-conditional',
|
||||
blockType: Scratch.BlockType.CONDITIONAL,
|
||||
branchCount: 4,
|
||||
isTerminal: true,
|
||||
blockAllThreads: false,
|
||||
text: 'choose [BRANCH]',
|
||||
arguments: {
|
||||
BRANCH: {
|
||||
type: Scratch.ArgumentType.NUMBER,
|
||||
defaultValue: 1
|
||||
}
|
||||
},
|
||||
func: 'noop'
|
||||
},
|
||||
{
|
||||
// Required: the machine-readable name of this operation.
|
||||
// This will appear in project JSON. Must not contain a '.' character.
|
||||
|
@ -110,6 +132,18 @@ class ExampleExtension {
|
|||
// ['sprite', 'stage']
|
||||
filter: ['someBlocks.wedo2', 'sprite', 'stage']
|
||||
},
|
||||
{
|
||||
opcode: 'example-Boolean',
|
||||
blockType: Scratch.BlockType.BOOLEAN,
|
||||
text: 'return true',
|
||||
func: 'returnTrue'
|
||||
},
|
||||
{
|
||||
opcode: 'example-hat',
|
||||
blockType: Scratch.BlockType.HAT,
|
||||
text: 'after forever',
|
||||
func: 'returnFalse'
|
||||
},
|
||||
{
|
||||
// Another block...
|
||||
}
|
||||
|
@ -179,6 +213,17 @@ class ExampleExtension {
|
|||
|
||||
return ['Letter ', args.LETTER_NUM, ' of ', args.TEXT, ' is ', result, '.'].join('');
|
||||
}
|
||||
|
||||
noop () {
|
||||
}
|
||||
|
||||
returnTrue () {
|
||||
return true;
|
||||
}
|
||||
|
||||
returnFalse () {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Scratch.extensions.register(new ExampleExtension());
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
const VirtualMachine = require('./virtual-machine');
|
||||
|
||||
const CentralDispatch = require('./dispatch/central-dispatch');
|
||||
const ExtensionManager = require('./extension-support/extension-manager');
|
||||
|
||||
global.Scratch = global.Scratch || {};
|
||||
global.Scratch.dispatch = CentralDispatch;
|
||||
global.Scratch.extensions = new ExtensionManager();
|
||||
|
||||
module.exports = VirtualMachine;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const EventEmitter = require('events');
|
||||
|
||||
const centralDispatch = require('./dispatch/central-dispatch');
|
||||
const ExtensionManager = require('./extension-support/extension-manager');
|
||||
const log = require('./util/log');
|
||||
const Runtime = require('./engine/runtime');
|
||||
const sb2 = require('./serialization/sb2');
|
||||
|
@ -63,6 +64,11 @@ class VirtualMachine extends EventEmitter {
|
|||
this.runtime.on(Runtime.MONITORS_UPDATE, monitorList => {
|
||||
this.emit(Runtime.MONITORS_UPDATE, monitorList);
|
||||
});
|
||||
this.runtime.on(Runtime.EXTENSION_WAS_ADDED, blocksInfo => {
|
||||
this.emit(Runtime.EXTENSION_WAS_ADDED, blocksInfo);
|
||||
});
|
||||
|
||||
this.extensionManager = new ExtensionManager();
|
||||
|
||||
this.blockListener = this.blockListener.bind(this);
|
||||
this.flyoutBlockListener = this.flyoutBlockListener.bind(this);
|
||||
|
|
Loading…
Reference in a new issue