Skip to content

Commit

Permalink
Allow to set parameters of included behaviors
Browse files Browse the repository at this point in the history
  • Loading branch information
pschillinger committed Apr 14, 2019
1 parent 49fdd4b commit 77d2b3d
Show file tree
Hide file tree
Showing 13 changed files with 236 additions and 60 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "FlexBE App",
"version": "2.1.5",
"version": "2.2.0",
"main": "src/main.js",
"window": {
"icon": "src/img/icon-128.png",
Expand Down
2 changes: 1 addition & 1 deletion package.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<package>
<name>flexbe_app</name>
<version>2.1.5</version>
<version>2.2.0</version>
<description>
flexbe_app provides a user interface (editor + runtime control) for the FlexBE behavior engine.
</description>
Expand Down
2 changes: 2 additions & 0 deletions src/_helper/checking.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ Checking = new (function() {
var sparams = state.getParameterValues();
for (var i = 0; i < sparams.length; i++) {
if (sparams[i] == "") return "parameter " + state.getParameters()[i] + " of state " + state.getStatePath() + " has empty value";
if (state instanceof BehaviorState && sparams[i] == undefined) continue;
if (!that.isValidExpressionSyntax(sparams[i], false)) return "parameter " + state.getParameters()[i] + " of state " + state.getStatePath() + " has invalid value";
}
}
Expand All @@ -195,6 +196,7 @@ Checking = new (function() {
var imap = state.getInputMapping();
for (var i = 0; i < imap.length; i++) {
if (imap[i] == "") return "input key " + state.getInputKeys()[i] + " of state " + state.getStatePath() + " has empty value";
if (state instanceof BehaviorState && imap[i] == undefined) continue;
if (!imap[i].match(python_varname_pattern)) return "input key " + state.getInputKeys()[i] + " of state " + state.getStatePath() + " has invalid value: " + imap[i];
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/_helper/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Tools = new (function() {
new_state.setInitialState(new_state.getStateByName(s.getInitialState().getStateName()));
}
} else if (s instanceof BehaviorState) {
new_state = new BehaviorState(s.getBehaviorName(), WS.Behaviorlib.getByName(s.getBehaviorName()), s.getDefaultKeys().clone());
new_state = new BehaviorState(s.getBehaviorName(), WS.Behaviorlib.getByName(s.getBehaviorName()));
new_state.setStateName(s.getStateName());
} else if (s instanceof State) {
var state_def = WS.Statelib.getFromLib(s.getStateType());
Expand Down
21 changes: 6 additions & 15 deletions src/_model/behaviorstate.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
BehaviorState = function(be_name, be_definition, be_defkeys) {
BehaviorState = function(be_name, be_definition) {
State.apply(this, [be_name, be_definition]);
var that = this;

var behavior_name = be_definition.getBehaviorName();
var behavior_manifest = be_definition.getBehaviorManifest();
var behavior_statemachine = be_definition.cloneBehaviorStatemachine();
behavior_statemachine.setBehavior(that);
var default_keys = be_defkeys;

this.getBehaviorName = function() {
return behavior_name;
Expand All @@ -20,21 +19,13 @@ BehaviorState = function(be_name, be_definition, be_defkeys) {
return behavior_manifest;
}

this.getDefaultKeys = function() {
return default_keys;
}

this.addDefaultKey = function(new_key) {
if (default_keys.contains(new_key)) return;
default_keys.push(new_key);
}

this.removeDefaultKey = function(key) {
if (!default_keys.contains(key)) return;
default_keys.remove(key);
this.getParameterDefinition = function(param) {
return behavior_manifest.params.findElement(el => {
return el.name == param;
});
}

this.getDefaultValue = function(key) {
this.getDefaultUserdataValue = function(key) {
var element = be_definition.getDefaultUserdata().findElement(function(el) {
return el.key == key;
});
Expand Down
2 changes: 1 addition & 1 deletion src/_model/statemachine.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ Statemachine = function(sm_name, sm_definition) {
var added_keys = []
state.getInputMapping().forEach(function(key, i) {
if (added_keys.contains(key)) return;
if (state instanceof BehaviorState && state.getDefaultKeys().contains(state.getInputKeys()[i])) return;
if (state instanceof BehaviorState && key == undefined) return;
added_keys.push(key);
addDataEdgeForPredecessors(state, state, key, []);
});
Expand Down
36 changes: 24 additions & 12 deletions src/io/io_codegenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,15 +298,24 @@ IO.CodeGenerator = new (function() {

} else if (s instanceof BehaviorState) {
var defkeys_str = "";
var be_defkeys = s.getDefaultKeys();
if (be_defkeys.length > 0) {
var be_defkeys_str = []
for (var j = 0; j < be_defkeys.length; j++) {
be_defkeys_str.push("'"+be_defkeys[j]+"'");
}
defkeys_str = ", default_keys=[" + be_defkeys_str.join(',') + "]";
var be_defkeys_str = [];
for (var j = 0; j < s.getInputKeys().length; j++) {
if (s.getInputMapping()[j] != undefined) continue;
be_defkeys_str.push("'"+s.getInputKeys()[j]+"'");
}
if (be_defkeys_str.length > 0) {
defkeys_str = ",\n"+ws+ws+ws+ws+ws+ws+ws+ws+ws+ws+ws+"default_keys=[" + be_defkeys_str.join(',') + "]";
}
var params_str = "";
var be_params_str = [];
for (var j = 0; j < s.getParameters().length; j++) {
if (s.getParameterValues()[j] == undefined) continue;
be_params_str.push("'"+s.getParameters()[j]+"': "+s.getParameterValues()[j]);
}
code += ws+ws+ws+ws+ws+ws+ws+ws+ws+ws+"self.use_behavior(" + s.getStateClass() + ", '" + s.getStatePath().substr(1) + "'" + defkeys_str + "),\n";
if (be_params_str.length > 0) {
params_str = ",\n"+ws+ws+ws+ws+ws+ws+ws+ws+ws+ws+ws+"parameters={" + be_params_str.join(', ') + "}";
}
code += ws+ws+ws+ws+ws+ws+ws+ws+ws+ws+"self.use_behavior(" + s.getStateClass() + ", '" + s.getStatePath().substr(1) + "'" + defkeys_str + params_str + "),\n";

} else {
var class_key = (!UI.Settings.isExplicitStates() && WS.Statelib.isClassUnique(s.getStateClass()))?
Expand Down Expand Up @@ -352,18 +361,21 @@ IO.CodeGenerator = new (function() {

// remapping
if (s.getInputKeys().length + s.getOutputKeys().length > 0) {
code += ",\n";
code += ws+ws+ws+ws+ws+ws+ws+ws+ws+ws+"remapping={";
var remapping_strings = [];
for (var j=0; j<s.getInputKeys().length; ++j) {
if (s.getInputMapping()[j] == undefined) continue;
remapping_strings.push("'" + s.getInputKeys()[j] + "': '" + s.getInputMapping()[j] + "'");
}
for (var j=0; j<s.getOutputKeys().length; ++j) {
if (s.getInputKeys().contains(s.getOutputKeys()[j])) continue;
remapping_strings.push("'" + s.getOutputKeys()[j] + "': '" + s.getOutputMapping()[j] + "'");
}
code += remapping_strings.join(", ");
code += "}";
if (remapping_strings.length > 0) {
code += ",\n";
code += ws+ws+ws+ws+ws+ws+ws+ws+ws+ws+"remapping={";
code += remapping_strings.join(", ");
code += "}";
}
}

code += ")\n\n";
Expand Down
48 changes: 34 additions & 14 deletions src/io/io_codeparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ IO.CodeParser = new (function() {
var string_quotes_pattern = /^["'](.*)["']/;
// [1] - name of the state class
var state_class_pattern = /^\s*(\w+)\(/;
// [1] - name of the behavior class , [2] - (optional) list of default keys
var state_behavior_pattern = /^\s*self\.use_behavior\((\w+)(?:, ?['"](?:[^'"]*)['"])?(?:, ?default_keys ?= ?\[([^\]]*)\])?\)/;
// [1] - name of the behavior class , [2+2*i,3+2*i] - (optional) list of default keys or parameters
// if [2] is "default_keys", [3] is a list of default keys
// if [2] or [4] is "parameters", [3] or [5] is a dict of behavior parameters
var state_behavior_pattern = /^\s*self\.use_behavior\((\w+)(?:, ?['"](?:[^'"]*)['"])?(?:,\s*(default_keys) ?= ?\[([^\]]*)\])?(?:,\s*(parameters) ?= ?\{([^\}]*)\})?\)/;
// [1] - kind of data (transitions/autonomy/remapping), [2] - comma separated list of values including surrounding braces
var state_interface_pattern = /(transitions|autonomy|remapping)\s*=\s*(\{[^}]*\})/;

Expand Down Expand Up @@ -461,11 +463,14 @@ IO.CodeParser = new (function() {
var parseStateParams = function(params) {
// get name
var state_name = helper_removeQuotes(params[0]);

// get state class and params
var state_class = "";
var state_type = "state";
var parameter_values = [];
var transitions = [];
var autonomy = [];
var remapping = [];

// get state class and params
var class_result = params[1].match(state_class_pattern);
if (class_result != null) {
state_class = class_result[1];
Expand All @@ -487,10 +492,23 @@ IO.CodeParser = new (function() {
if (behavior_use_result != null) {
state_class = behavior_use_result[1];
state_type = "behavior";
if (behavior_use_result[2] != undefined) {
parameter_values = behavior_use_result[2].replace(/["'\s]/g, '').split(',');
} else {
parameter_values = [];
if (behavior_use_result.length > 2 && behavior_use_result[2] == 'default_keys') {
behavior_use_result[3].replace(/["'\s]/g, '').split(',').forEach(key => {
remapping.push({
key: key,
value: undefined
});
});
}
if (behavior_use_result.length > 2 && behavior_use_result[2] == 'parameters'
|| behavior_use_result.length > 4 && behavior_use_result[4] == 'parameters') {
var dict_def = (behavior_use_result.length > 4)? behavior_use_result[5] : behavior_use_result[3];
var dict_split = helper_splitOnTopCommas('{'+dict_def+'}');
dict_split.forEach(element => {
var keyvalue = helper_splitKeyValue(element, ':');
keyvalue.key = helper_removeQuotes(keyvalue.key);
parameter_values.push(keyvalue);
});
}
} else {
state_class = params[1];
Expand All @@ -500,9 +518,6 @@ IO.CodeParser = new (function() {
}

// get further parameters
var transitions = [];
var autonomy = [];
var remapping = [];
for(var i=2; i<params.length; i++) {
var param_result = params[i].match(state_interface_pattern);
if (param_result == null) {
Expand Down Expand Up @@ -544,6 +559,11 @@ IO.CodeParser = new (function() {
var remapping_list = helper_splitOnTopCommas(param_result[2]);
for (var j=0; j<remapping_list.length; j++) {
var remapping_kv = helper_splitKeyValue(remapping_list[j].trim(), ":");
var default_input = remapping.findElement(element => {
return element.key == helper_removeQuotes(remapping_kv.key);
})
if (default_input != undefined)
continue;
if (remapping_kv != undefined) {
remapping.push({
key: helper_removeQuotes(remapping_kv.key),
Expand Down Expand Up @@ -596,11 +616,11 @@ IO.CodeParser = new (function() {
// split into relevant methods
var code_init_split = code_class_split[3].split(init_def_pattern);
if (code_init_split.length == 1) throw "behavior constructor definition could not be found";
var code_init = code_init_split[1].split(/\tdef/)[0];
var code_init = code_init_split[1].split(/\sdef\s/)[0];

var code_create_split = code_class_split[3].split(create_def_pattern);
if (code_create_split.length == 1) throw "behavior state machine creation section could not be found";
var code_create = code_create_split[1].split(/\tdef/)[0];
var code_create = code_create_split[1].split(/\sdef\s/)[0];

// parse init section
var init_result = parseInitSection(code_init);
Expand Down Expand Up @@ -673,7 +693,7 @@ IO.CodeParser = new (function() {

var code_create_split = code_class_split[3].split(create_def_pattern);
if (code_create_split.length == 1) throw "behavior state machine creation section could not be found";
var code_create = code_create_split[1].split(/\tdef/)[0];
var code_create = code_create_split[1].split(/\sdef\s/)[0];

// parse create section
var create_result = parseCreateSection(code_create, true);
Expand Down
3 changes: 2 additions & 1 deletion src/io/io_modelgenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ IO.ModelGenerator = new (function() {
T.logInfo("Please check your workspace settings.");
continue;
}
s = new BehaviorState(s_def.state_name, state_def, s_def.parameter_values);
s = new BehaviorState(s_def.state_name, state_def);
s.setParameterValues(helper_getSortedValueList(s.getParameters(), s.getParameterValues(), s_def.parameter_values));
} else {
var state_def = undefined;
if (s_def.state_class.includes("__")) {
Expand Down
Loading

0 comments on commit 77d2b3d

Please sign in to comment.