forked from scratchfoundation/scratch-vm
-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Block versioning extension #5
Open
pmalacho-mit
wants to merge
10
commits into
main
Choose a base branch
from
block-versioning-extension
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
b86bded
feat: versioning
mayarajan3 f984680
docs: commenting and removing prints
mayarajan3 d3d283b
feat: add name and function type
mayarajan3 972deed
feat: combo support
mayarajan3 a5ef7d9
fix: comment
mayarajan3 4c380f5
feat: removing deserialization code
mayarajan3 9090e05
feat: moving to project json
mayarajan3 09d644e
fix: remove unnecessary code
mayarajan3 30a71d4
fix: removing opcode changes from sb3
mayarajan3 4065fe2
fix: small edits
mayarajan3 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -297,16 +297,16 @@ const getExtensionIdForOpcode = function (opcode) { | |
* compressed primitives and the list of all extension IDs present | ||
* in the serialized blocks. | ||
*/ | ||
const serializeBlocks = function (blocks) { | ||
const serializeBlocks = function (blocks, extensionManager) { | ||
const obj = Object.create(null); | ||
const extensionIDs = new Set(); | ||
for (const blockID in blocks) { | ||
if (!Object.prototype.hasOwnProperty.call(blocks, blockID)) continue; | ||
obj[blockID] = serializeBlock(blocks[blockID], blocks); | ||
const extensionID = getExtensionIdForOpcode(blocks[blockID].opcode); | ||
if (extensionID) { | ||
extensionIDs.add(extensionID); | ||
extensionIDs.add(extensionID); | ||
} | ||
obj[blockID] = serializeBlock(blocks[blockID], blocks); | ||
} | ||
// once we have completed a first pass, do a second pass on block inputs | ||
for (const blockID in obj) { | ||
|
@@ -451,7 +451,7 @@ const serializeComments = function (comments) { | |
* @param {Set} extensions A set of extensions to add extension IDs to | ||
* @return {object} A serialized representation of the given target. | ||
*/ | ||
const serializeTarget = function (target, extensions) { | ||
const serializeTarget = function (target, extensions, extensionManager) { | ||
const obj = Object.create(null); | ||
let targetExtensions = []; | ||
obj.isStage = target.isStage; | ||
|
@@ -460,7 +460,7 @@ const serializeTarget = function (target, extensions) { | |
obj.variables = vars.variables; | ||
obj.lists = vars.lists; | ||
obj.broadcasts = vars.broadcasts; | ||
[obj.blocks, targetExtensions] = serializeBlocks(target.blocks); | ||
[obj.blocks, targetExtensions] = serializeBlocks(target.blocks, extensionManager); | ||
obj.comments = serializeComments(target.comments); | ||
|
||
// TODO remove this check/patch when (#1901) is fixed | ||
|
@@ -564,7 +564,7 @@ const serialize = function (runtime, targetId, /* PRG ADDITION BEGIN */ extensio | |
}); | ||
} | ||
|
||
const serializedTargets = flattenedOriginalTargets.map(t => serializeTarget(t, extensions)); | ||
const serializedTargets = flattenedOriginalTargets.map(t => serializeTarget(t, extensions, extensionManager)); | ||
|
||
if (targetId) { | ||
return serializedTargets[0]; | ||
|
@@ -577,6 +577,7 @@ const serialize = function (runtime, targetId, /* PRG ADDITION BEGIN */ extensio | |
/* PRG ADDITION BEGIN */ | ||
extensionManager.getLoadedExtensionIDs().forEach(id => { | ||
const instance = extensionManager.getExtensionInstance(id); | ||
obj.targets = instance["alterOpcodes"]?.(obj.targets); | ||
instance["save"]?.(obj, extensions); | ||
}); | ||
/* PRG ADDITION END */ | ||
|
@@ -839,12 +840,14 @@ const deserializeFields = function (fields) { | |
* @param {object} blocks Serialized SB3 "blocks" property of a target. Will be mutated. | ||
* @return {object} input is modified and returned | ||
*/ | ||
const deserializeBlocks = function (blocks) { | ||
const deserializeBlocks = function (blocks, extensionManager) { | ||
for (const blockId in blocks) { | ||
if (!Object.prototype.hasOwnProperty.call(blocks, blockId)) { | ||
continue; | ||
} | ||
const block = blocks[blockId]; | ||
|
||
|
||
if (Array.isArray(block)) { | ||
// this is one of the primitives | ||
// delete the old entry in object.blocks and replace it w/the | ||
|
@@ -854,8 +857,10 @@ const deserializeBlocks = function (blocks) { | |
continue; | ||
} | ||
block.id = blockId; // add id back to block since it wasn't serialized | ||
|
||
block.inputs = deserializeInputs(block.inputs, blockId, blocks); | ||
block.fields = deserializeFields(block.fields); | ||
|
||
} | ||
return blocks; | ||
}; | ||
|
@@ -957,7 +962,7 @@ const parseScratchAssets = function (object, runtime, zip) { | |
* into costumes and sounds | ||
* @return {!Promise.<Target>} Promise for the target created (stage or sprite), or null for unsupported objects. | ||
*/ | ||
const parseScratchObject = function (object, runtime, extensions, zip, assets) { | ||
const parseScratchObject = function (object, runtime, extensions, zip, assets, extensionManager) { | ||
if (!Object.prototype.hasOwnProperty.call(object, 'name')) { | ||
// Watcher/monitor - skip this object until those are implemented in VM. | ||
// @todo | ||
|
@@ -974,18 +979,18 @@ const parseScratchObject = function (object, runtime, extensions, zip, assets) { | |
sprite.name = object.name; | ||
} | ||
if (Object.prototype.hasOwnProperty.call(object, 'blocks')) { | ||
deserializeBlocks(object.blocks); | ||
deserializeBlocks(object.blocks, extensionManager); | ||
// Take a second pass to create objects and add extensions | ||
for (const blockId in object.blocks) { | ||
if (!Object.prototype.hasOwnProperty.call(object.blocks, blockId)) continue; | ||
const blockJSON = object.blocks[blockId]; | ||
blocks.createBlock(blockJSON); | ||
|
||
// If the block is from an extension, record it. | ||
let blockJSON = object.blocks[blockId]; | ||
const extensionID = getExtensionIdForOpcode(blockJSON.opcode); | ||
blocks.createBlock(blockJSON); | ||
if (extensionID) { | ||
extensions.extensionIDs.add(extensionID); | ||
} | ||
|
||
|
||
} | ||
} | ||
// Costumes from JSON. | ||
|
@@ -1125,6 +1130,7 @@ const deserializeMonitor = function (monitorData, runtime, targets, extensions) | |
// If the serialized monitor has spriteName defined, look up the sprite | ||
// by name in the given list of targets and update the monitor's targetId | ||
// to match the sprite's id. | ||
|
||
if (monitorData.spriteName) { | ||
const filteredTargets = targets.filter(t => t.sprite.name === monitorData.spriteName); | ||
if (filteredTargets && filteredTargets.length > 0) { | ||
|
@@ -1263,16 +1269,23 @@ const replaceUnsafeCharsInVariableIds = function (targets) { | |
* @param {Runtime} runtime - Runtime instance | ||
* @param {JSZip} zip - Sb3 file describing this project (to load assets from) | ||
* @param {boolean} isSingleSprite - If true treat as single sprite, else treat as whole project | ||
* @param {import("../extension-support/extension-manager")} extensionManager Reference to VM's extension manager. | ||
* @returns {Promise.<ImportedProject>} Promise that resolves to the list of targets after the project is deserialized | ||
*/ | ||
const deserialize = function (json, runtime, zip, isSingleSprite) { | ||
const deserialize = function (json, runtime, zip, isSingleSpriteOrExtensionManager) { | ||
const extensions = { | ||
extensionIDs: new Set(), | ||
extensionURLs: new Map() | ||
}; | ||
|
||
/* PRG ADDITION BEGIN */ | ||
json["extensions"]?.forEach(id => extensions.extensionIDs.add(id)); | ||
|
||
var extensionManager = null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mayarajan3 Are these changes still necessary? |
||
var isSingleSprite = false; | ||
if (isSingleSpriteOrExtensionManager && isSingleSpriteOrExtensionManager.runtime == runtime) { | ||
extensionManager = isSingleSpriteOrExtensionManager; | ||
} else if (isSingleSpriteOrExtensionManager == true && isSingleSpriteOrExtensionManager == false) { | ||
isSingleSprite = isSingleSpriteOrExtensionManager; | ||
} | ||
|
||
// Unpack the data for the text model | ||
runtime.modelData = { "textData": {}, "classifierData": {}, "nextLabelNumber": 1 }; | ||
|
@@ -1297,6 +1310,9 @@ const deserialize = function (json, runtime, zip, isSingleSprite) { | |
runtime.origin = null; | ||
} | ||
|
||
console.log("extension manager"); | ||
console.log(extensionManager); | ||
|
||
// First keep track of the current target order in the json, | ||
// then sort by the layer order property before parsing the targets | ||
// so that their corresponding render drawables can be created in | ||
|
@@ -1316,7 +1332,7 @@ const deserialize = function (json, runtime, zip, isSingleSprite) { | |
.then(assets => Promise.resolve(assets)) | ||
.then(assets => Promise.all(targetObjects | ||
.map((target, index) => | ||
parseScratchObject(target, runtime, extensions, zip, assets[index])))) | ||
parseScratchObject(target, runtime, extensions, zip, assets[index], extensionManager)))) | ||
.then(targets => targets // Re-sort targets back into original sprite-pane ordering | ||
.map((t, i) => { | ||
// Add layer order property to deserialized targets. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dead code