Skip to content

Commit

Permalink
jme.makeVariables can assign multiple variables at once
Browse files Browse the repository at this point in the history
Keys in te `todo` dictionary can be made from several variable names
separated by commas. The definition must evaluate to a type which can be
cast to a list. The variable names are assigned to the corresponding
items in the list.
  • Loading branch information
christianp committed Aug 19, 2020
1 parent 7669bc9 commit fcf4188
Showing 1 changed file with 40 additions and 3 deletions.
43 changes: 40 additions & 3 deletions runtime/scripts/jme-variables.js
Expand Up @@ -165,6 +165,7 @@ jme.variables = /** @lends Numbas.jme.variables */ {
*/
computeVariable: function(name,todo,scope,path,computeFn)
{
var originalName = todo[name].originalName || name;
if(scope.getVariable(name)!==undefined)
return scope.variables[name];
if(path===undefined)
Expand Down Expand Up @@ -201,13 +202,16 @@ jme.variables = /** @lends Numbas.jme.variables */ {
}
}
if(!v.tree) {
throw(new Numbas.Error('jme.variables.empty definition',{name:name}));
throw(new Numbas.Error('jme.variables.empty definition',{name: originalName}));
}
try {
var value = jme.evaluate(v.tree,scope);
if(v.names) {
value = jme.castToType(value,'list');
}
scope.setVariable(name,value);
} catch(e) {
throw(new Numbas.Error('jme.variables.error evaluating variable',{name:name,message:e.message},e));
throw(new Numbas.Error('jme.variables.error evaluating variable',{name:originalName,message:e.message},e));
}
return value;
},
Expand All @@ -221,6 +225,34 @@ jme.variables = /** @lends Numbas.jme.variables */ {
*/
makeVariables: function(todo,scope,condition,computeFn)
{
var multis = {};
var multi_acc = 0;
var ntodo = {};
Object.keys(todo).forEach(function(name) {
var names = name.split(/\s*,\s*/);
if(names.length>1) {
var mname;
while(true) {
mname = '$multi_'+(multi_acc++);
if(todo[mname]===undefined) {
break;
}
}
multis[mname] = name;
ntodo[mname] = todo[name];
ntodo[mname].names = names;
ntodo[mname].originalName = name;
names.forEach(function(sname,i) {
ntodo[sname] = {
tree: jme.compile(mname+'['+i+']'),
vars: [mname]
}
});
} else {
ntodo[name] = todo[name];
}
});
todo = ntodo;
computeFn = computeFn || jme.variables.computeVariable;
var conditionSatisfied = true;
if(condition) {
Expand All @@ -236,7 +268,12 @@ jme.variables = /** @lends Numbas.jme.variables */ {
computeFn(x,todo,scope,undefined,computeFn);
}
}
return {variables: scope.variables, conditionSatisfied: conditionSatisfied, scope: scope};
var variables = scope.variables;
Object.keys(multis).forEach(function(mname) {
variables[multis[mname]] = variables[mname];
delete variables[mname];
});
return {variables: variables, conditionSatisfied: conditionSatisfied, scope: scope};
},

/** Remake a dictionary of variables, only re-evaluating variables which depend on the changed_variables.
Expand Down

0 comments on commit fcf4188

Please sign in to comment.