From 6bbc47d61aae820fee50246089c0d6c2ddfbf4c9 Mon Sep 17 00:00:00 2001 From: "Blake J. Harnden" Date: Mon, 10 Dec 2018 15:02:13 -0800 Subject: [PATCH] corefx - updated mobility scripts to provide dialogs for each script to control, which can be closed and opened back up, from a mobility node context menu --- corefx/src/main/java/com/core/Controller.java | 49 +++++----- .../main/java/com/core/data/SessionState.java | 5 +- .../java/com/core/graph/EmaneContextMenu.java | 17 ++-- .../java/com/core/graph/WlanContextMenu.java | 17 ++-- .../main/java/com/core/ui/MobilityPlayer.java | 54 ----------- .../com/core/ui/dialogs/MobilityDialog.java | 14 +-- .../core/ui/dialogs/MobilityPlayerDialog.java | 89 +++++++++++++++++++ .../com/core/websocket/CoreWebSocket.java | 21 ++++- corefx/src/main/resources/css/main.css | 21 +++++ .../main/resources/fxml/mobility_player.fxml | 26 ++++-- 10 files changed, 202 insertions(+), 111 deletions(-) delete mode 100644 corefx/src/main/java/com/core/ui/MobilityPlayer.java create mode 100644 corefx/src/main/java/com/core/ui/dialogs/MobilityPlayerDialog.java diff --git a/corefx/src/main/java/com/core/Controller.java b/corefx/src/main/java/com/core/Controller.java index 4023869a..74128e28 100644 --- a/corefx/src/main/java/com/core/Controller.java +++ b/corefx/src/main/java/com/core/Controller.java @@ -49,6 +49,8 @@ public class Controller implements Initializable { @FXML private MenuItem saveXmlMenuItem; @FXML private JFXProgressBar progressBar; + private final Map mobilityScripts = new HashMap<>(); + private final Map mobilityPlayerDialogs = new HashMap<>(); private Application application; private JFXDecorator decorator; private Stage window; @@ -65,7 +67,6 @@ public class Controller implements Initializable { private NodeDetails nodeDetails = new NodeDetails(this); private LinkDetails linkDetails = new LinkDetails(this); private GraphToolbar graphToolbar = new GraphToolbar(this); - private MobilityPlayer mobilityPlayer = new MobilityPlayer(this); // dialogs private SessionsDialog sessionsDialog = new SessionsDialog(this); @@ -135,11 +136,10 @@ public class Controller implements Initializable { networkGraph.reset(); // clear out any previously set information - Platform.runLater(() -> { - bottom.getChildren().remove(mobilityPlayer); - borderPane.setRight(null); - }); + mobilityPlayerDialogs.clear(); + mobilityScripts.clear(); mobilityDialog.setNode(null); + Platform.runLater(() -> borderPane.setRight(null)); // get session to join Session session = coreClient.getSession(sessionId); @@ -182,18 +182,10 @@ public class Controller implements Initializable { // update session default services setCoreDefaultServices(); - // display first mobility script in player, if needed + // retrieve current mobility script configurations and show dialogs Map mobilityConfigMap = coreClient.getMobilityConfigs(); - Optional nodeIdOptional = mobilityConfigMap.keySet().stream().findFirst(); - if (nodeIdOptional.isPresent()) { - Integer nodeId = nodeIdOptional.get(); - MobilityConfig mobilityConfig = mobilityConfigMap.get(nodeId); - CoreNode node = networkGraph.getVertex(nodeId); - if (node != null) { - mobilityPlayer.show(node, mobilityConfig); - Platform.runLater(() -> bottom.getChildren().add(mobilityPlayer)); - } - } + mobilityScripts.putAll(mobilityConfigMap); + showMobilityScriptDialogs(); Platform.runLater(() -> decorator.setTitle(String.format("CORE (Session %s)", sessionId))); } @@ -212,15 +204,7 @@ public class Controller implements Initializable { boolean result = coreClient.start(nodes, links, hooks); progressBar.setVisible(false); if (result) { - // configure and add mobility player - CoreNode node = mobilityDialog.getNode(); - if (node != null) { - MobilityConfig mobilityConfig = mobilityDialog.getMobilityScripts().get(node.getId()); - if (mobilityConfig != null) { - mobilityPlayer.show(node, mobilityConfig); - Platform.runLater(() -> bottom.getChildren().add(mobilityPlayer)); - } - } + showMobilityScriptDialogs(); saveXmlMenuItem.setDisable(false); } return result; @@ -239,7 +223,6 @@ public class Controller implements Initializable { boolean result = coreClient.stop(); progressBar.setVisible(false); if (result) { - Platform.runLater(() -> bottom.getChildren().remove(mobilityPlayer)); saveXmlMenuItem.setDisable(true); } return result; @@ -289,6 +272,20 @@ public class Controller implements Initializable { nodeTypeCreateDialog.setOwner(window); } + private void showMobilityScriptDialogs() { + for (Map.Entry entry : mobilityScripts.entrySet()) { + Integer nodeId = entry.getKey(); + CoreNode node = networkGraph.getVertex(nodeId); + MobilityConfig mobilityConfig = entry.getValue(); + Platform.runLater(() -> { + MobilityPlayerDialog mobilityPlayerDialog = new MobilityPlayerDialog(this, node); + mobilityPlayerDialog.setOwner(window); + mobilityPlayerDialogs.put(nodeId, mobilityPlayerDialog); + mobilityPlayerDialog.showDialog(mobilityConfig); + }); + } + } + @FXML private void onCoreMenuConnect(ActionEvent event) { logger.info("showing connect!"); diff --git a/corefx/src/main/java/com/core/data/SessionState.java b/corefx/src/main/java/com/core/data/SessionState.java index 71bca0e5..c9e92904 100644 --- a/corefx/src/main/java/com/core/data/SessionState.java +++ b/corefx/src/main/java/com/core/data/SessionState.java @@ -9,7 +9,10 @@ public enum SessionState { INSTANTIATION(3), RUNTIME(4), DATA_COLLECT(5), - SHUTDOWN(6); + SHUTDOWN(6), + START(7), + STOP(8), + PAUSE(9); private static final Map LOOKUP = new HashMap<>(); diff --git a/corefx/src/main/java/com/core/graph/EmaneContextMenu.java b/corefx/src/main/java/com/core/graph/EmaneContextMenu.java index be567d0c..848bbfb3 100644 --- a/corefx/src/main/java/com/core/graph/EmaneContextMenu.java +++ b/corefx/src/main/java/com/core/graph/EmaneContextMenu.java @@ -2,6 +2,7 @@ package com.core.graph; import com.core.Controller; import com.core.data.CoreNode; +import com.core.ui.dialogs.MobilityPlayerDialog; class EmaneContextMenu extends AbstractNodeContextMenu { EmaneContextMenu(Controller controller, CoreNode coreNode) { @@ -10,13 +11,15 @@ class EmaneContextMenu extends AbstractNodeContextMenu { } private void setup() { - addMenuItem("EMANE Settings", - event -> controller.getNodeEmaneDialog().showDialog(coreNode)); - if (!controller.getCoreClient().isRunning()) { - addMenuItem("Mobility", - event -> controller.getMobilityDialog().showDialog(coreNode)); - addMenuItem("Link MDRs", - event -> controller.getNetworkGraph().linkMdrs(coreNode)); + addMenuItem("EMANE Settings", event -> controller.getNodeEmaneDialog().showDialog(coreNode)); + if (controller.getCoreClient().isRunning()) { + MobilityPlayerDialog mobilityPlayerDialog = controller.getMobilityPlayerDialogs().get(coreNode.getId()); + if (mobilityPlayerDialog != null && !mobilityPlayerDialog.getStage().isShowing()) { + addMenuItem("Mobility Script", event -> mobilityPlayerDialog.show()); + } + } else { + addMenuItem("Mobility", event -> controller.getMobilityDialog().showDialog(coreNode)); + addMenuItem("Link MDRs", event -> controller.getNetworkGraph().linkMdrs(coreNode)); addMenuItem("Delete Node", event -> controller.deleteNode(coreNode)); } } diff --git a/corefx/src/main/java/com/core/graph/WlanContextMenu.java b/corefx/src/main/java/com/core/graph/WlanContextMenu.java index 6fe29132..937eef15 100644 --- a/corefx/src/main/java/com/core/graph/WlanContextMenu.java +++ b/corefx/src/main/java/com/core/graph/WlanContextMenu.java @@ -2,6 +2,7 @@ package com.core.graph; import com.core.Controller; import com.core.data.CoreNode; +import com.core.ui.dialogs.MobilityPlayerDialog; class WlanContextMenu extends AbstractNodeContextMenu { WlanContextMenu(Controller controller, CoreNode coreNode) { @@ -10,13 +11,15 @@ class WlanContextMenu extends AbstractNodeContextMenu { } private void setup() { - addMenuItem("WLAN Settings", - event -> controller.getNodeWlanDialog().showDialog(coreNode)); - if (!controller.getCoreClient().isRunning()) { - addMenuItem("Mobility", - event -> controller.getMobilityDialog().showDialog(coreNode)); - addMenuItem("Link MDRs", - event -> controller.getNetworkGraph().linkMdrs(coreNode)); + addMenuItem("WLAN Settings", event -> controller.getNodeWlanDialog().showDialog(coreNode)); + if (controller.getCoreClient().isRunning()) { + MobilityPlayerDialog mobilityPlayerDialog = controller.getMobilityPlayerDialogs().get(coreNode.getId()); + if (mobilityPlayerDialog != null && !mobilityPlayerDialog.getStage().isShowing()) { + addMenuItem("Mobility Script", event -> mobilityPlayerDialog.show()); + } + } else { + addMenuItem("Mobility", event -> controller.getMobilityDialog().showDialog(coreNode)); + addMenuItem("Link MDRs", event -> controller.getNetworkGraph().linkMdrs(coreNode)); addMenuItem("Delete Node", event -> controller.deleteNode(coreNode)); } } diff --git a/corefx/src/main/java/com/core/ui/MobilityPlayer.java b/corefx/src/main/java/com/core/ui/MobilityPlayer.java deleted file mode 100644 index 20181fc6..00000000 --- a/corefx/src/main/java/com/core/ui/MobilityPlayer.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.core.ui; - -import com.core.Controller; -import com.core.data.CoreNode; -import com.core.data.MobilityConfig; -import com.core.utils.FxmlUtils; -import com.core.utils.IconUtils; -import com.jfoenix.controls.JFXButton; -import javafx.fxml.FXML; -import javafx.scene.control.Label; -import javafx.scene.layout.HBox; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; - -public class MobilityPlayer extends HBox { - private static final Logger logger = LogManager.getLogger(); - private static final int ICON_SIZE = 20; - private static final String ICON_FILL = "white"; - @FXML private Label label; - @FXML private JFXButton playButton; - @FXML private JFXButton pauseButton; - @FXML private JFXButton stopButton; - private Controller controller; - private CoreNode node; - private MobilityConfig mobilityConfig; - - public MobilityPlayer(Controller controller) { - this.controller = controller; - FxmlUtils.loadRootController(this, "/fxml/mobility_player.fxml"); - - playButton.setGraphic(IconUtils.get("play_arrow", ICON_SIZE, ICON_FILL)); - playButton.setOnAction(event -> action("start")); - pauseButton.setGraphic(IconUtils.get("pause", ICON_SIZE, ICON_FILL)); - pauseButton.setOnAction(event -> action("pause")); - stopButton.setGraphic(IconUtils.get("stop", ICON_SIZE, ICON_FILL)); - stopButton.setOnAction(event -> action("stop")); - } - - private void action(String action) { - try { - controller.getCoreClient().mobilityAction(node, action); - } catch (IOException ex) { - Toast.error(String.format("mobility error: %s", action), ex); - } - } - - public void show(CoreNode node, MobilityConfig mobilityConfig) { - this.node = node; - this.mobilityConfig = mobilityConfig; - label.setText(String.format("%s - %s", node.getName(), mobilityConfig.getFile())); - } -} diff --git a/corefx/src/main/java/com/core/ui/dialogs/MobilityDialog.java b/corefx/src/main/java/com/core/ui/dialogs/MobilityDialog.java index 8e8c8388..ff0766cb 100644 --- a/corefx/src/main/java/com/core/ui/dialogs/MobilityDialog.java +++ b/corefx/src/main/java/com/core/ui/dialogs/MobilityDialog.java @@ -17,8 +17,6 @@ import org.apache.logging.log4j.Logger; import java.io.File; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; @Data public class MobilityDialog extends StageDialog { @@ -31,7 +29,6 @@ public class MobilityDialog extends StageDialog { @FXML private JFXTextField startTextField; @FXML private JFXTextField pauseTextField; @FXML private JFXTextField stopTextField; - private Map mobilityScripts = new HashMap<>(); private CoreNode node; public MobilityDialog(Controller controller) { @@ -53,8 +50,13 @@ public class MobilityDialog extends StageDialog { mobilityConfig.setStopScript(stopTextField.getText()); try { - controller.getCoreClient().setMobilityConfig(node, mobilityConfig); - mobilityScripts.put(node.getId(), mobilityConfig); + boolean result = controller.getCoreClient().setMobilityConfig(node, mobilityConfig); + if (result) { + getController().getMobilityScripts().put(node.getId(), mobilityConfig); + Toast.info(String.format("Set mobility configuration for %s", node.getName())); + } else { + Toast.error(String.format("Error setting mobility configuration for %s", node.getName())); + } } catch (IOException ex) { Toast.error("error setting mobility configuration", ex); } @@ -75,7 +77,7 @@ public class MobilityDialog extends StageDialog { String mobilityPath = getController().getConfiguration().getMobilityPath(); fileChooser.setInitialDirectory(new File(mobilityPath)); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Mobility", - "*.mobility")); + "*.scen")); try { File file = fileChooser.showOpenDialog(getController().getWindow()); if (file != null) { diff --git a/corefx/src/main/java/com/core/ui/dialogs/MobilityPlayerDialog.java b/corefx/src/main/java/com/core/ui/dialogs/MobilityPlayerDialog.java new file mode 100644 index 00000000..baf8574d --- /dev/null +++ b/corefx/src/main/java/com/core/ui/dialogs/MobilityPlayerDialog.java @@ -0,0 +1,89 @@ +package com.core.ui.dialogs; + +import com.core.Controller; +import com.core.data.CoreNode; +import com.core.data.MobilityConfig; +import com.core.data.SessionState; +import com.core.ui.Toast; +import com.core.utils.IconUtils; +import com.jfoenix.controls.JFXButton; +import com.jfoenix.controls.JFXProgressBar; +import javafx.animation.KeyFrame; +import javafx.animation.KeyValue; +import javafx.animation.Timeline; +import javafx.application.Platform; +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.stage.Modality; +import javafx.util.Duration; +import lombok.Data; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; + +@Data +public class MobilityPlayerDialog extends StageDialog { + private static final Logger logger = LogManager.getLogger(); + private static final int ICON_SIZE = 20; + private static final String ICON_FILL = "white"; + @FXML private Label label; + @FXML private JFXButton playButton; + @FXML private JFXButton pauseButton; + @FXML private JFXButton stopButton; + @FXML private JFXProgressBar progressBar; + private final CoreNode node; + private MobilityConfig mobilityConfig; + + public MobilityPlayerDialog(Controller controller, CoreNode node) { + super(controller, "/fxml/mobility_player.fxml", Modality.NONE); + this.node = node; + + playButton.setGraphic(IconUtils.get("play_arrow", ICON_SIZE, ICON_FILL)); + playButton.setOnAction(event -> action("start")); + pauseButton.setGraphic(IconUtils.get("pause", ICON_SIZE, ICON_FILL)); + pauseButton.setOnAction(event -> action("pause")); + stopButton.setGraphic(IconUtils.get("stop", ICON_SIZE, ICON_FILL)); + stopButton.setOnAction(event -> action("stop")); + + addCancelButton(); + setTitle(String.format("%s Mobility Script", node.getName())); + getStage().sizeToScene(); + } + + public void event(SessionState state, Integer start, Integer end) { + Platform.runLater(() -> { + playButton.setDisable(false); + stopButton.setDisable(false); + + switch (state) { + case START: + playButton.setDisable(true); + progressBar.setProgress(0); + Timeline timeline = new Timeline(); + KeyValue keyValue = new KeyValue(progressBar.progressProperty(), 1.0); + KeyFrame keyFrame = new KeyFrame(new Duration(end * 1000), keyValue); + timeline.getKeyFrames().add(keyFrame); + timeline.play(); + break; + case STOP: + stopButton.setDisable(true); + break; + } + }); + } + + private void action(String action) { + try { + getCoreClient().mobilityAction(node, action); + } catch (IOException ex) { + Toast.error(String.format("mobility error: %s", action), ex); + } + } + + public void showDialog(MobilityConfig mobilityConfig) { + this.label.setText(mobilityConfig.getFile()); + this.mobilityConfig = mobilityConfig; + show(); + } +} diff --git a/corefx/src/main/java/com/core/websocket/CoreWebSocket.java b/corefx/src/main/java/com/core/websocket/CoreWebSocket.java index 451f8416..6b497f4a 100644 --- a/corefx/src/main/java/com/core/websocket/CoreWebSocket.java +++ b/corefx/src/main/java/com/core/websocket/CoreWebSocket.java @@ -2,6 +2,8 @@ package com.core.websocket; import com.core.Controller; import com.core.data.*; +import com.core.ui.dialogs.MobilityDialog; +import com.core.ui.dialogs.MobilityPlayerDialog; import com.core.utils.JsonUtils; import io.socket.client.IO; import io.socket.client.Socket; @@ -61,9 +63,26 @@ public class CoreWebSocket { CoreEvent event = JsonUtils.read(arg.toString(), CoreEvent.class); logger.info("handling broadcast event: {}", event); SessionState state = SessionState.get(event.getEventType().getValue()); - if (state != null) { + if (state == null) { + logger.warn("unknown event type: {}", event.getEventType().getValue()); + return; + } + + // session state event + if (state.getValue() <= 6) { logger.info("event updating session state: {}", state); controller.getCoreClient().updateState(state); + // mobility script event + } else if (state.getValue() <= 9) { + Integer nodeId = event.getNode(); + String[] values = event.getData().split("\\s+"); + Integer start = Integer.parseInt(values[0].split("=")[1]); + Integer end = Integer.parseInt(values[1].split("=")[1]); + logger.info(String.format("node(%s) mobility event (%s) - start(%s) stop(%s)", + nodeId, state, start, end)); + logger.info("all dialogs: {}", controller.getMobilityPlayerDialogs().keySet()); + MobilityPlayerDialog mobilityPlayerDialog = controller.getMobilityPlayerDialogs().get(nodeId); + mobilityPlayerDialog.event(state, start, end); } } catch (IOException ex) { logger.error("error getting core event", ex); diff --git a/corefx/src/main/resources/css/main.css b/corefx/src/main/resources/css/main.css index 252c1254..5654da59 100644 --- a/corefx/src/main/resources/css/main.css +++ b/corefx/src/main/resources/css/main.css @@ -67,6 +67,27 @@ -fx-text-fill: black; } +.mobility-start { + -fx-background-color: green; + -fx-text-fill: white; + -fx-pref-width: 100px; + -jfx-button-type: RAISED; +} + +.mobility-pause { + -fx-background-color: yellow; + -fx-text-fill: white; + -fx-pref-width: 100px; + -jfx-button-type: RAISED; +} + +.mobility-stop { + -fx-background-color: red; + -fx-text-fill: white; + -fx-pref-width: 100px; + -jfx-button-type: RAISED; +} + .core-button { -fx-background-color: olivedrab; -fx-text-fill: white; diff --git a/corefx/src/main/resources/fxml/mobility_player.fxml b/corefx/src/main/resources/fxml/mobility_player.fxml index 391d8f68..3efea18c 100644 --- a/corefx/src/main/resources/fxml/mobility_player.fxml +++ b/corefx/src/main/resources/fxml/mobility_player.fxml @@ -1,18 +1,26 @@ + + - + + - - - - - +