mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-23 14:32:59 -05:00
Track whether a project has cloud data and enforce a cloud data limit on projects being loaded into the runtime.
This commit is contained in:
parent
6ef600dc2c
commit
848deaff30
3 changed files with 93 additions and 3 deletions
|
@ -71,6 +71,47 @@ const ArgumentTypeMap = (() => {
|
||||||
return map;
|
return map;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A pair of functions used to manage the cloud variable limit,
|
||||||
|
* to be used when adding (or attempting to add) or removing a cloud variable.
|
||||||
|
* @typedef {object} CloudDataManager
|
||||||
|
* @property {function} canAddNewCloudVariable A function to call to check that
|
||||||
|
* a cloud variable can be added.
|
||||||
|
* @property {function} removeExistingCloudVariable A function to call when
|
||||||
|
* removing an existing cloud variable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and manages cloud variable limit in a project,
|
||||||
|
* and returns two functions to be used to add a new
|
||||||
|
* cloud variable (while checking that it can be added)
|
||||||
|
* and remove an existing cloud variable.
|
||||||
|
* These are to be called whenever attempting to create or delete
|
||||||
|
* a cloud variable.
|
||||||
|
* @return {CloudDataManager} The functions to be used when adding or removing a
|
||||||
|
* cloud variable.
|
||||||
|
*/
|
||||||
|
const cloudDataManager = () => {
|
||||||
|
let cloudVariableLimit = 8;
|
||||||
|
|
||||||
|
const canAddNewCloudVariable = () => {
|
||||||
|
if (cloudVariableLimit > 0) {
|
||||||
|
cloudVariableLimit--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeExistingCloudVariable = () => {
|
||||||
|
cloudVariableLimit++;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
canAddNewCloudVariable,
|
||||||
|
removeExistingCloudVariable
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Predefined "Converted block info" for a separator between blocks in a block category
|
* Predefined "Converted block info" for a separator between blocks in a block category
|
||||||
* @type {ConvertedBlockInfo}
|
* @type {ConvertedBlockInfo}
|
||||||
|
@ -283,6 +324,30 @@ class Runtime extends EventEmitter {
|
||||||
* @type {Profiler}
|
* @type {Profiler}
|
||||||
*/
|
*/
|
||||||
this.profiler = null;
|
this.profiler = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this runtime uses/interacts with cloud data.
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
this.hasCloudData = false;
|
||||||
|
|
||||||
|
const newCloudDataManager = cloudDataManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function which checks whether a new cloud variable can be added
|
||||||
|
* to the runtime.
|
||||||
|
* @type {function}
|
||||||
|
* @return {boolean} Whether or not a new cloud variable can be added
|
||||||
|
* to the runtime.
|
||||||
|
*/
|
||||||
|
this.canAddNewCloudVariable = newCloudDataManager.canAddNewCloudVariable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function which updates the runtime's cloud variable limit
|
||||||
|
* when removing a cloud variable.
|
||||||
|
* @type {function}
|
||||||
|
*/
|
||||||
|
this.removeExistingCloudVariable = newCloudDataManager.removeExistingCloudVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1394,6 +1459,13 @@ class Runtime extends EventEmitter {
|
||||||
this._monitorState = OrderedMap({});
|
this._monitorState = OrderedMap({});
|
||||||
// @todo clear out extensions? turboMode? etc.
|
// @todo clear out extensions? turboMode? etc.
|
||||||
this.ioDevices.cloud.clear();
|
this.ioDevices.cloud.clear();
|
||||||
|
|
||||||
|
// Reset runtime cloud data info
|
||||||
|
this.hasCloudData = false;
|
||||||
|
const newCloudDataManager = cloudDataManager();
|
||||||
|
this.canAddNewCloudVariable = newCloudDataManager.canAddNewCloudVariable;
|
||||||
|
this.removeExistingCloudVariable = newCloudDataManager.removeExistingCloudVariable;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -470,12 +470,21 @@ const parseScratchObject = function (object, runtime, extensions, topLevel, zip)
|
||||||
if (object.hasOwnProperty('variables')) {
|
if (object.hasOwnProperty('variables')) {
|
||||||
for (let j = 0; j < object.variables.length; j++) {
|
for (let j = 0; j < object.variables.length; j++) {
|
||||||
const variable = object.variables[j];
|
const variable = object.variables[j];
|
||||||
|
// A variable is a cloud variable if:
|
||||||
|
// - the project says it's a cloud variable, and
|
||||||
|
// - it's a stage variable, and
|
||||||
|
// - the runtime can support another cloud variable
|
||||||
|
const isCloud = variable.isPersistent && topLevel &&
|
||||||
|
// It's important that this part of the check goes last
|
||||||
|
// because it will update the cloud variable limit counter.
|
||||||
|
runtime.canAddNewCloudVariable();
|
||||||
const newVariable = new Variable(
|
const newVariable = new Variable(
|
||||||
getVariableId(variable.name, Variable.SCALAR_TYPE),
|
getVariableId(variable.name, Variable.SCALAR_TYPE),
|
||||||
variable.name,
|
variable.name,
|
||||||
Variable.SCALAR_TYPE,
|
Variable.SCALAR_TYPE,
|
||||||
variable.isPersistent
|
isCloud
|
||||||
);
|
);
|
||||||
|
if (isCloud && !runtime.hasCloudData) runtime.hasCloudData = true;
|
||||||
newVariable.value = variable.value;
|
newVariable.value = variable.value;
|
||||||
target.variables[newVariable.id] = newVariable;
|
target.variables[newVariable.id] = newVariable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -393,7 +393,7 @@ const serializeVariables = function (variables) {
|
||||||
// otherwise should be a scalar type
|
// otherwise should be a scalar type
|
||||||
obj.variables[varId] = [v.name, v.value];
|
obj.variables[varId] = [v.name, v.value];
|
||||||
// only scalar vars have the potential to be cloud vars
|
// only scalar vars have the potential to be cloud vars
|
||||||
if (v.isPersistent) obj.variables[varId].push(true);
|
if (v.isCloud) obj.variables[varId].push(true);
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
@ -900,12 +900,21 @@ const parseScratchObject = function (object, runtime, extensions, zip) {
|
||||||
if (object.hasOwnProperty('variables')) {
|
if (object.hasOwnProperty('variables')) {
|
||||||
for (const varId in object.variables) {
|
for (const varId in object.variables) {
|
||||||
const variable = object.variables[varId];
|
const variable = object.variables[varId];
|
||||||
|
// A variable is a cloud variable if:
|
||||||
|
// - the project says it's a cloud variable, and
|
||||||
|
// - it's a stage variable, and
|
||||||
|
// - the runtime can support another cloud variable
|
||||||
|
const isCloud = (variable.length === 3) && variable[2] && object.isStage &&
|
||||||
|
// It's important that this part of the check goes last
|
||||||
|
// because it will update the cloud variable limit counter.
|
||||||
|
runtime.canAddNewCloudVariable();
|
||||||
const newVariable = new Variable(
|
const newVariable = new Variable(
|
||||||
varId, // var id is the index of the variable desc array in the variables obj
|
varId, // var id is the index of the variable desc array in the variables obj
|
||||||
variable[0], // name of the variable
|
variable[0], // name of the variable
|
||||||
Variable.SCALAR_TYPE, // type of the variable
|
Variable.SCALAR_TYPE, // type of the variable
|
||||||
(variable.length === 3) ? variable[2] : false // isPersistent/isCloud
|
isCloud
|
||||||
);
|
);
|
||||||
|
if (isCloud && !runtime.hasCloudData) runtime.hasCloudData = true;
|
||||||
newVariable.value = variable[1];
|
newVariable.value = variable[1];
|
||||||
target.variables[newVariable.id] = newVariable;
|
target.variables[newVariable.id] = newVariable;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue