From 4e0ce5cf4cb2bf57f3502d732ccc8db7e3a956fa Mon Sep 17 00:00:00 2001 From: Philipp Schillinger Date: Sun, 17 Dec 2017 11:35:20 +0100 Subject: [PATCH] Update states when source code changes (see #10) --- src/_model/state.js | 143 +++++++++++++++++++++++++++++++++++-- src/_model/statemachine.js | 15 ++++ src/events.js | 1 + src/io/io_packageparser.js | 60 +++++++++++----- src/prototype.js | 5 ++ 5 files changed, 200 insertions(+), 24 deletions(-) diff --git a/src/_model/state.js b/src/_model/state.js index 75a612e..560a521 100644 --- a/src/_model/state.js +++ b/src/_model/state.js @@ -130,6 +130,9 @@ State = function(state_name, state_def) { resolved_parameter_output_values_old = resolved_parameter_output_values; } + var noMetaFilter = function(element) { return element[0] != '$'; }; + var metaFilter = function(element) { return element[0] == '$'; }; + var state_name = state_name; var state_class = state_def.getStateClass(); var state_import = state_def.getStatePath(); @@ -139,22 +142,22 @@ State = function(state_name, state_def) { var parameters = state_def.getParameters().clone(); var parameter_values = state_def.getDefaultParameterValues().clone(); - var outcomes = state_def.getOutcomes().filter(function(element) { return element[0] != '$'; }); + var outcomes = state_def.getOutcomes().filter(noMetaFilter); var autonomy = state_def.getDefaultAutonomy().clone(); - var meta_outcomes = state_def.getOutcomes().filter(function(element) { return element[0] == '$'; }); + var meta_outcomes = state_def.getOutcomes().filter(metaFilter); for (var i=0; i { RC.PubSub.shutdown(); ROS.shutdown(); + IO.PackageParser.stopWatching(); }); nw.App.on('open', () => { diff --git a/src/io/io_packageparser.js b/src/io/io_packageparser.js index 2f1b125..e588b53 100644 --- a/src/io/io_packageparser.js +++ b/src/io/io_packageparser.js @@ -38,6 +38,12 @@ IO.PackageParser = new (function() { }); } + this.stopWatching = function() { + for (var state in watched_states) { + watched_states[state].close(); + } + } + var checkForRelevance = function(pkg_path, callback) { var data = fs.readFileSync(path.join(pkg_path, 'package.xml')); var xml = dom_parser.parseFromString(String(data), "text/xml"); @@ -51,24 +57,42 @@ IO.PackageParser = new (function() { var watchStateFolder = function(folder_path, import_path) { if (watched_states[folder_path] != undefined) return; - // watched_states[folder_path] = fs.watch(folder_path, - // {persistent: false}, - // (eventType, filename) => { - // if (eventType == 'change') { - // var entry = path.join(folder_path, filename); - // IO.Filesystem.readFile(entry, (content) => { - // var imports = entry.replace(import_path+"/", "").replace(/.py$/i, "").replace(/[\/]/g, "."); - // var state_def = IO.StateParser.parseState(content, imports); - // if (state_def != undefined) { - // state_def.setFilePath(entry); - // WS.Statelib.updateDef(state_def); - // T.logInfo("Updating changed definition for state: " + state_def.getStateClass()); - // // TODO update defs for existing states and re-draw - // } - // }); - // } - // } - // ); + watched_states[folder_path] = fs.watch(folder_path, + {persistent: false}, + (eventType, filename) => { + if(RC.Controller.isReadonly()) { + T.logWarn("A state definition source file changed while in read-only mode, ignoring the change for now!"); + return; + } + if (eventType == 'change') { + var entry = path.join(folder_path, filename); + IO.Filesystem.readFile(entry, (content) => { + var imports = entry.replace(import_path+"/", "").replace(/.py$/i, "").replace(/[\/]/g, "."); + var state_def = IO.StateParser.parseState(content, imports); + if (state_def != undefined) { + state_def.setFilePath(entry); + WS.Statelib.updateDef(state_def); + T.logInfo("Updating changed definition for state: " + state_def.getStateClass()); + var update_states = Behavior.getStatemachine().traverseStates(function(state) { + return state.getStateClass() == state_def.getStateClass(); + }); + update_states.forEach(function (state) { + state.updateStateDefinition(state_def); + if (state.getContainer() == UI.Statemachine.getDisplayedSM() + && UI.Panels.StateProperties.isCurrentState(state)) { + UI.Panels.StateProperties.hide(); + UI.Panels.StateProperties.displayStateProperties(state); + } + }); + if (UI.Menu.isPageStatemachine()) { + UI.Statemachine.refreshView(); + } + RC.Controller.signalChanged(); + } + }); + } + } + ); } this.parseStateFolder = function(folder, import_path, has_init) { diff --git a/src/prototype.js b/src/prototype.js index 66ff5dd..b88a91f 100644 --- a/src/prototype.js +++ b/src/prototype.js @@ -33,6 +33,11 @@ Array.prototype.contains = function(element) { return this.indexOf(element) != -1; } +Array.prototype.hasSameElements = function(other) { + var diff = this.filter(el => !other.contains(el)); + return 0 == diff.concat(other.filter(el => !this.contains(el))).length; +} + //===================== // String