From 40bdbd1948237a62b5c2841d8a0efe686ade3335 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 7 Aug 2017 08:58:47 -0700 Subject: [PATCH 1/6] Add a timer to the computation thread to stop it from running. --- .../java/org/nwapw/abacus/fx/AbacusController.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/src/main/java/org/nwapw/abacus/fx/AbacusController.java index 06b10ac..96d5ad3 100644 --- a/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -124,6 +124,17 @@ public class AbacusController implements PluginListener { * The alert shown when a press to "apply" is needed. */ private Alert reloadAlert; + /** + * The runnable that takes care of killing computations that take too long. + */ + private final Runnable TIMER_RUNNABLE = () -> { + try { + Thread.sleep(30 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + performStop(); + }; /** * The runnable used to perform the calculation. */ @@ -239,6 +250,7 @@ public class AbacusController implements PluginListener { stopButton.setDisable(false); calculationThread = new Thread(CALCULATION_RUNNABLE); calculationThread.start(); + new Thread(TIMER_RUNNABLE).start(); } @FXML From b8f8c4486a953a7c58eb3b823e2655d5e3d48167 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 7 Aug 2017 09:22:11 -0700 Subject: [PATCH 2/6] Add a setting to the timeout delay. --- .../nwapw/abacus/config/Configuration.java | 28 ++++++++++++++++++- .../org/nwapw/abacus/fx/AbacusController.java | 4 ++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/nwapw/abacus/config/Configuration.java b/src/main/java/org/nwapw/abacus/config/Configuration.java index 2b68236..1bc7aa2 100644 --- a/src/main/java/org/nwapw/abacus/config/Configuration.java +++ b/src/main/java/org/nwapw/abacus/config/Configuration.java @@ -30,6 +30,10 @@ public class Configuration { */ private static final TomlWriter TOML_WRITER = new TomlWriter(); + /** + * The computation delay for which the thread can run without interruption. + */ + private double computationDelay = 0; /** * The implementation of the number that should be used. */ @@ -51,10 +55,12 @@ public class Configuration { /** * Creates a new configuration with the given values. * + * @param computationDelay the delay before the computation gets killed. * @param numberImplementation the number implementation, like "naive" or "precise" * @param disabledPlugins the list of disabled plugins. */ - public Configuration(String numberImplementation, String[] disabledPlugins) { + public Configuration(double computationDelay, String numberImplementation, String[] disabledPlugins) { + this.computationDelay = computationDelay; this.numberImplementation = numberImplementation; this.disabledPlugins.addAll(Arrays.asList(disabledPlugins)); } @@ -75,6 +81,7 @@ public class Configuration { * @param otherConfiguration the configuration to copy from. */ public void copyFrom(Configuration otherConfiguration) { + this.computationDelay = otherConfiguration.computationDelay; this.numberImplementation = otherConfiguration.numberImplementation; this.disabledPlugins.addAll(otherConfiguration.disabledPlugins); } @@ -130,4 +137,23 @@ public class Configuration { return disabledPlugins; } + + /** + * Gets the computation delay specified in the configuration. + * + * @return the computaton delay. + */ + public double getComputationDelay() { + return computationDelay; + } + + /** + * Sets the computation delay. + * + * @param computationDelay the new computation delay. + */ + public void setComputationDelay(double computationDelay) { + this.computationDelay = computationDelay; + } + } diff --git a/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/src/main/java/org/nwapw/abacus/fx/AbacusController.java index 96d5ad3..6b5aae3 100644 --- a/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -129,7 +129,9 @@ public class AbacusController implements PluginListener { */ private final Runnable TIMER_RUNNABLE = () -> { try { - Thread.sleep(30 * 1000); + Configuration abacusConfig = abacus.getConfiguration(); + if(abacusConfig.getComputationDelay() != 0) + Thread.sleep((long) (abacusConfig.getComputationDelay() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } From b2fad93ce4487db62f46c4cd3af01b83a26de331 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 7 Aug 2017 09:55:06 -0700 Subject: [PATCH 3/6] Fix tests to work with the configuration. --- src/test/java/org/nwapw/abacus/tests/CalculationTests.java | 2 +- src/test/java/org/nwapw/abacus/tests/TokenizerTests.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/nwapw/abacus/tests/CalculationTests.java b/src/test/java/org/nwapw/abacus/tests/CalculationTests.java index 106daa8..e451732 100644 --- a/src/test/java/org/nwapw/abacus/tests/CalculationTests.java +++ b/src/test/java/org/nwapw/abacus/tests/CalculationTests.java @@ -11,7 +11,7 @@ import org.nwapw.abacus.tree.TreeNode; public class CalculationTests { - private static Abacus abacus = new Abacus(new Configuration("precise", new String[]{})); + private static Abacus abacus = new Abacus(new Configuration(0, "precise", new String[]{})); @BeforeClass public static void prepareTests(){ diff --git a/src/test/java/org/nwapw/abacus/tests/TokenizerTests.java b/src/test/java/org/nwapw/abacus/tests/TokenizerTests.java index 6ba223c..56515e3 100644 --- a/src/test/java/org/nwapw/abacus/tests/TokenizerTests.java +++ b/src/test/java/org/nwapw/abacus/tests/TokenizerTests.java @@ -19,7 +19,7 @@ import java.util.List; public class TokenizerTests { - private static Abacus abacus = new Abacus(new Configuration("precise", new String[]{})); + private static Abacus abacus = new Abacus(new Configuration(0, "precise", new String[]{})); private static LexerTokenizer lexerTokenizer = new LexerTokenizer(); private static Function subtractFunction = new Function() { @Override From ed7d60800b674bae90db1a930b3ce12ef5bff36d Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Mon, 7 Aug 2017 10:30:37 -0700 Subject: [PATCH 4/6] Read delay input from input field, and kill delay thread. --- .../org/nwapw/abacus/fx/AbacusController.java | 37 +++++++++++++++---- src/main/resources/abacus.fxml | 4 +- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/src/main/java/org/nwapw/abacus/fx/AbacusController.java index 6b5aae3..f3f2acc 100644 --- a/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -1,6 +1,8 @@ package org.nwapw.abacus.fx; import javafx.application.Platform; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; @@ -89,6 +91,8 @@ public class AbacusController implements PluginListener { private ComboBox numberImplementationBox; @FXML private ListView enabledPluginView; + @FXML + private TextField computationLimitField; /** * The list of history entries, created by the users. @@ -130,12 +134,10 @@ public class AbacusController implements PluginListener { private final Runnable TIMER_RUNNABLE = () -> { try { Configuration abacusConfig = abacus.getConfiguration(); - if(abacusConfig.getComputationDelay() != 0) + if(abacusConfig.getComputationDelay() == 0) return; Thread.sleep((long) (abacusConfig.getComputationDelay() * 1000)); - } catch (InterruptedException e) { - e.printStackTrace(); - } - performStop(); + performStop(); + } catch (InterruptedException e) { } }; /** * The runnable used to perform the calculation. @@ -174,6 +176,7 @@ public class AbacusController implements PluginListener { }); } }; + private Thread computationLimitThread; /** * The thread in which the computation runs. */ @@ -237,6 +240,15 @@ public class AbacusController implements PluginListener { } abacusPluginManager.reload(); + computationLimitField.setText(Double.toString(abacus.getConfiguration().getComputationDelay())); + computationLimitField.textProperty().addListener((observable, oldValue, newValue) -> { + if(!newValue.matches("(\\d+(\\.\\d*)?)?")) { + computationLimitField.setText(oldValue); + } else { + changesMade = true; + } + }); + changesMade = false; reloadAlertShown = false; @@ -252,13 +264,20 @@ public class AbacusController implements PluginListener { stopButton.setDisable(false); calculationThread = new Thread(CALCULATION_RUNNABLE); calculationThread.start(); - new Thread(TIMER_RUNNABLE).start(); + computationLimitThread = new Thread(TIMER_RUNNABLE); + computationLimitThread.start(); } @FXML private void performStop(){ - if(calculationThread != null) + if(calculationThread != null) { calculationThread.interrupt(); + calculationThread = null; + } + if(computationLimitThread != null){ + computationLimitThread.interrupt(); + computationLimitThread = null; + } } @FXML @@ -284,6 +303,9 @@ public class AbacusController implements PluginListener { for (ToggleablePlugin pluginEntry : enabledPlugins) { if (!pluginEntry.isEnabled()) disabledPlugins.add(pluginEntry.getClassName()); } + if(computationLimitField.getText().matches("\\d*(\\.\\d+)?") && computationLimitField.getText().length() != 0) + configuration.setComputationDelay(Double.parseDouble(computationLimitField.getText())); + System.out.println(configuration.getComputationDelay()); configuration.saveTo(CONFIG_FILE); changesMade = false; reloadAlertShown = false; @@ -310,4 +332,5 @@ public class AbacusController implements PluginListener { enabledPlugins.clear(); numberImplementationOptions.clear(); } + } diff --git a/src/main/resources/abacus.fxml b/src/main/resources/abacus.fxml index 495c654..495187c 100644 --- a/src/main/resources/abacus.fxml +++ b/src/main/resources/abacus.fxml @@ -50,7 +50,9 @@ - + +