Merge pull request #1255 from technoboy10/feature/extension-serialization

Serialize extensions used in a project
This commit is contained in:
Connor Hudson 2018-06-26 09:49:19 -04:00 committed by GitHub
commit 326c41875e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -272,14 +272,21 @@ const compressInputTree = function (block, blocks) {
* Serialize the given blocks object (representing all the blocks for the target * Serialize the given blocks object (representing all the blocks for the target
* currently being serialized.) * currently being serialized.)
* @param {object} blocks The blocks to be serialized * @param {object} blocks The blocks to be serialized
* @return {object} The serialized blocks with compressed inputs and compressed * @return {Array} An array of the serialized blocks with compressed inputs and
* primitives. * compressed primitives and the list of all extension IDs present
* in the serialized blocks.
*/ */
const serializeBlocks = function (blocks) { const serializeBlocks = function (blocks) {
const obj = Object.create(null); const obj = Object.create(null);
const extensionIDs = new Set();
for (const blockID in blocks) { for (const blockID in blocks) {
if (!blocks.hasOwnProperty(blockID)) continue; if (!blocks.hasOwnProperty(blockID)) continue;
obj[blockID] = serializeBlock(blocks[blockID], blocks); obj[blockID] = serializeBlock(blocks[blockID], blocks);
const index = blocks[blockID].opcode.indexOf('_');
const prefix = blocks[blockID].opcode.substring(0, index);
if (CORE_EXTENSIONS.indexOf(prefix) === -1) {
if (prefix !== '') extensionIDs.add(prefix);
}
} }
// once we have completed a first pass, do a second pass on block inputs // once we have completed a first pass, do a second pass on block inputs
for (const blockID in obj) { for (const blockID in obj) {
@ -308,7 +315,7 @@ const serializeBlocks = function (blocks) {
delete obj[blockID]; delete obj[blockID];
} }
} }
return obj; return [obj, Array.from(extensionIDs)];
}; };
/** /**
@ -412,17 +419,19 @@ const serializeComments = function (comments) {
* Serialize the given target. Only serialize properties that are necessary * Serialize the given target. Only serialize properties that are necessary
* for saving and loading this target. * for saving and loading this target.
* @param {object} target The target to be serialized. * @param {object} target The target to be serialized.
* @param {Set} extensions A set of extensions to add extension IDs to
* @return {object} A serialized representation of the given target. * @return {object} A serialized representation of the given target.
*/ */
const serializeTarget = function (target) { const serializeTarget = function (target, extensions) {
const obj = Object.create(null); const obj = Object.create(null);
let targetExtensions = [];
obj.isStage = target.isStage; obj.isStage = target.isStage;
obj.name = obj.isStage ? 'Stage' : target.name; obj.name = obj.isStage ? 'Stage' : target.name;
const vars = serializeVariables(target.variables); const vars = serializeVariables(target.variables);
obj.variables = vars.variables; obj.variables = vars.variables;
obj.lists = vars.lists; obj.lists = vars.lists;
obj.broadcasts = vars.broadcasts; obj.broadcasts = vars.broadcasts;
obj.blocks = serializeBlocks(target.blocks); [obj.blocks, targetExtensions] = serializeBlocks(target.blocks);
obj.comments = serializeComments(target.comments); obj.comments = serializeComments(target.comments);
obj.currentCostume = target.currentCostume; obj.currentCostume = target.currentCostume;
obj.costumes = target.costumes.map(serializeCostume); obj.costumes = target.costumes.map(serializeCostume);
@ -441,6 +450,11 @@ const serializeTarget = function (target) {
obj.draggable = target.draggable; obj.draggable = target.draggable;
obj.rotationStyle = target.rotationStyle; obj.rotationStyle = target.rotationStyle;
} }
// Add found extensions to the extensions object
targetExtensions.forEach(extensionId => {
extensions.add(extensionId);
});
return obj; return obj;
}; };
@ -453,11 +467,13 @@ const serializeTarget = function (target) {
const serialize = function (runtime, targetId) { const serialize = function (runtime, targetId) {
// Fetch targets // Fetch targets
const obj = Object.create(null); const obj = Object.create(null);
// Create extension set to hold extension ids found while serializing targets
const extensions = new Set();
const flattenedOriginalTargets = JSON.parse(JSON.stringify(targetId ? const flattenedOriginalTargets = JSON.parse(JSON.stringify(targetId ?
[runtime.getTargetById(targetId)] : [runtime.getTargetById(targetId)] :
runtime.targets.filter(target => target.isOriginal))); runtime.targets.filter(target => target.isOriginal)));
const serializedTargets = flattenedOriginalTargets.map(t => serializeTarget(t, runtime)); const serializedTargets = flattenedOriginalTargets.map(t => serializeTarget(t, extensions));
if (targetId) { if (targetId) {
return serializedTargets[0]; return serializedTargets[0];
@ -468,6 +484,9 @@ const serialize = function (runtime, targetId) {
// TODO Serialize monitors // TODO Serialize monitors
// Assemble extension list
obj.extensions = Array.from(extensions);
// Assemble metadata // Assemble metadata
const meta = Object.create(null); const meta = Object.create(null);
meta.semver = '3.0.0'; meta.semver = '3.0.0';