mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-01-11 10:39:56 -05:00
Add API to generically validate and add sprite based on validation results.
This commit is contained in:
parent
1fcbbc261f
commit
adf7571851
1 changed files with 60 additions and 31 deletions
|
@ -212,7 +212,7 @@ class VirtualMachine extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
const validationPromise = new Promise((resolve, reject) => {
|
const validationPromise = new Promise((resolve, reject) => {
|
||||||
validate(input, (error, res) => {
|
validate(input, false /* this is not a single sprite */, (error, res) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
|
@ -379,23 +379,64 @@ class VirtualMachine extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a single sprite from the "Sprite2" (i.e., SB2 sprite) format.
|
* Add a sprite, this could be .sprite2 or .sprite3. Unpack and validate
|
||||||
* @param {string} json JSON string representing the sprite.
|
* such a file first.
|
||||||
* @returns {Promise} Promise that resolves after the sprite is added
|
* @param {string | object} input A json string, object, or ArrayBuffer representing the project to load.
|
||||||
|
* @return {!Promise} Promise that resolves after targets are installed.
|
||||||
*/
|
*/
|
||||||
addSprite2 (json) {
|
addSprite (input) {
|
||||||
// Validate & parse
|
if (typeof input === 'object' && !(input instanceof ArrayBuffer) &&
|
||||||
if (typeof json !== 'string') {
|
!ArrayBuffer.isView(input)) {
|
||||||
log.error('Failed to parse sprite. Non-string supplied to addSprite2.');
|
// If the input is an object and not any ArrayBuffer
|
||||||
return;
|
// or an ArrayBuffer view (this includes all typed arrays and DataViews)
|
||||||
}
|
// turn the object into a JSON string, because we suspect
|
||||||
json = JSON.parse(json);
|
// this is a project.json as an object
|
||||||
if (typeof json !== 'object') {
|
// validate expects a string or buffer as input
|
||||||
log.error('Failed to parse sprite. JSON supplied to addSprite2 is not an object.');
|
// TODO not sure if we need to check that it also isn't a data view
|
||||||
return;
|
input = JSON.stringify(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb2.deserialize(json, this.runtime, true)
|
const validationPromise = new Promise((resolve, reject) => {
|
||||||
|
validate(input, true /* single sprite */, (error, res) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
if (res) {
|
||||||
|
resolve(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return validationPromise
|
||||||
|
.then(validatedInput => {
|
||||||
|
const projectVersion = validatedInput[0].projectVersion;
|
||||||
|
if (projectVersion === 2) {
|
||||||
|
return this.addSprite2(validatedInput[0], validatedInput[1]);
|
||||||
|
}
|
||||||
|
if (projectVersion === 3) {
|
||||||
|
return this.addSprite3(validatedInput[0], validatedInput[1]);
|
||||||
|
}
|
||||||
|
return Promise.reject('Unable to verify sprite version.');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// Intentionally rejecting here (want errors to be handled by caller)
|
||||||
|
if (error.hasOwnProperty('validationError')) {
|
||||||
|
return Promise.reject(JSON.stringify(error));
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a single sprite from the "Sprite2" (i.e., SB2 sprite) format.
|
||||||
|
* @param {string} json JSON string representing the sprite.
|
||||||
|
* @param {?ArrayBuffer} zip Optional zip of assets being referenced by json
|
||||||
|
* @returns {Promise} Promise that resolves after the sprite is added
|
||||||
|
*/
|
||||||
|
addSprite2 (json, zip) {
|
||||||
|
// Validate & parse
|
||||||
|
|
||||||
|
return sb2.deserialize(json, this.runtime, true, zip)
|
||||||
.then(({targets, extensions}) =>
|
.then(({targets, extensions}) =>
|
||||||
this.installTargets(targets, extensions, false));
|
this.installTargets(targets, extensions, false));
|
||||||
}
|
}
|
||||||
|
@ -403,26 +444,14 @@ class VirtualMachine extends EventEmitter {
|
||||||
/**
|
/**
|
||||||
* Add a single sb3 sprite.
|
* Add a single sb3 sprite.
|
||||||
* @param {string} target JSON string representing the sprite/target.
|
* @param {string} target JSON string representing the sprite/target.
|
||||||
|
* @param {?ArrayBuffer} zip Optional zip of assets being referenced by target json
|
||||||
* @returns {Promise} Promise that resolves after the sprite is added
|
* @returns {Promise} Promise that resolves after the sprite is added
|
||||||
*/
|
*/
|
||||||
addSprite3 (target) {
|
addSprite3 (target, zip) {
|
||||||
// Validate & parse
|
// Validate & parse
|
||||||
if (typeof target !== 'string') {
|
|
||||||
log.error('Failed to parse sprite. Non-string supplied to addSprite3.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
target = JSON.parse(target);
|
|
||||||
if (typeof target !== 'object') {
|
|
||||||
log.error('Failed to parse sprite. JSON supplied to addSprite3 is not an object.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const jsonFormatted = {
|
|
||||||
targets: [target]
|
|
||||||
};
|
|
||||||
|
|
||||||
return sb3
|
return sb3
|
||||||
.deserialize(jsonFormatted, this.runtime, null)
|
.deserialize(target, this.runtime, zip)
|
||||||
.then(({targets, extensions}) => this.installTargets(targets, extensions, false));
|
.then(({targets, extensions}) => this.installTargets(targets, extensions, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,7 +643,7 @@ class VirtualMachine extends EventEmitter {
|
||||||
canvas.height = bitmap.height;
|
canvas.height = bitmap.height;
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext('2d');
|
||||||
context.putImageData(bitmap, 0, 0);
|
context.putImageData(bitmap, 0, 0);
|
||||||
|
|
||||||
// Divide by resolution because the renderer's definition of the rotation center
|
// Divide by resolution because the renderer's definition of the rotation center
|
||||||
// is the rotation center divided by the bitmap resolution
|
// is the rotation center divided by the bitmap resolution
|
||||||
this.runtime.renderer.updateBitmapSkin(
|
this.runtime.renderer.updateBitmapSkin(
|
||||||
|
|
Loading…
Reference in a new issue