mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-27 00:12:57 -05:00
79 lines
2.8 KiB
JavaScript
79 lines
2.8 KiB
JavaScript
|
/**
|
||
|
* @fileoverview
|
||
|
* The BlocksRuntimeCache caches data about the top block of scripts so that
|
||
|
* Runtime can iterate a targeted opcode and iterate the returned set faster.
|
||
|
* Many top blocks need to match fields as well as opcode, since that matching
|
||
|
* compares strings in uppercase we can go ahead and uppercase the cached value
|
||
|
* so we don't need to in the future.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* A set of cached data about the top block of a script.
|
||
|
* @param {Blocks} container - Container holding the block and related data
|
||
|
* @param {string} blockId - Id for whose block data is cached in this instance
|
||
|
*/
|
||
|
class RuntimeScriptCache {
|
||
|
constructor (container, blockId) {
|
||
|
/**
|
||
|
* Container with block data for blockId.
|
||
|
* @type {Blocks}
|
||
|
*/
|
||
|
this.container = container;
|
||
|
|
||
|
/**
|
||
|
* ID for block this instance caches.
|
||
|
* @type {string}
|
||
|
*/
|
||
|
this.blockId = blockId;
|
||
|
|
||
|
const block = container.getBlock(blockId);
|
||
|
const fields = container.getFields(block);
|
||
|
|
||
|
/**
|
||
|
* Formatted fields or fields of input blocks ready for comparison in
|
||
|
* runtime.
|
||
|
*
|
||
|
* This is a clone of parts of the targeted blocks. Changes to these
|
||
|
* clones are limited to copies under RuntimeScriptCache and will not
|
||
|
* appear in the original blocks in their container. This copy is
|
||
|
* modified changing the case of strings to uppercase. These uppercase
|
||
|
* values will be compared later by the VM.
|
||
|
* @type {object}
|
||
|
*/
|
||
|
this.fieldsOfInputs = Object.assign({}, fields);
|
||
|
if (Object.keys(fields).length === 0) {
|
||
|
const inputs = container.getInputs(block);
|
||
|
for (const input in inputs) {
|
||
|
if (!inputs.hasOwnProperty(input)) continue;
|
||
|
const id = inputs[input].block;
|
||
|
const inputBlock = container.getBlock(id);
|
||
|
const inputFields = container.getFields(inputBlock);
|
||
|
Object.assign(this.fieldsOfInputs, inputFields);
|
||
|
}
|
||
|
}
|
||
|
for (const key in this.fieldsOfInputs) {
|
||
|
const field = this.fieldsOfInputs[key] = Object.assign({}, this.fieldsOfInputs[key]);
|
||
|
if (field.value.toUpperCase) {
|
||
|
field.value = field.value.toUpperCase();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get an array of scripts from a block container prefiltered to match opcode.
|
||
|
* @param {Blocks} container - Container of blocks
|
||
|
* @param {string} opcode - Opcode to filter top blocks by
|
||
|
*/
|
||
|
exports.getScripts = function () {
|
||
|
throw new Error('blocks.js has not initialized BlocksRuntimeCache');
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Exposed RuntimeScriptCache class used by integration in blocks.js.
|
||
|
* @private
|
||
|
*/
|
||
|
exports._RuntimeScriptCache = RuntimeScriptCache;
|
||
|
|
||
|
require('./blocks');
|