mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-25 16:15:19 +00:00
Compare commits
11 Commits
stoppable-
...
plugin-lis
| Author | SHA1 | Date | |
|---|---|---|---|
| 4056013d1f | |||
| be28e26607 | |||
| 2f1ed5f0d1 | |||
| 2615273d28 | |||
| 6e1d2ce629 | |||
| 44b8efd9bc | |||
| 2502c90837 | |||
| e49f28a850 | |||
| 88e4a87d81 | |||
| cda09518c3 | |||
| 56510d97de |
@@ -5,10 +5,10 @@ Summer project for NWAPW.
|
|||||||
Created by Arthur Drobot, Danila Fedorin and Riley Jones.
|
Created by Arthur Drobot, Danila Fedorin and Riley Jones.
|
||||||
|
|
||||||
## Project Description
|
## Project Description
|
||||||
Abacus is a calculator built with extensibility and usability in mind. It provides a plugin interface, via Java, as Lua proves too difficult to link up to the Java core. The description of the internals of the project can be found on the wiki page.
|
Abacus is a calculator built with extensibility and usability in mind. It provides a plugin interface, via Java, as Lua provides too difficult to link up to the Java core. The description of the internals of the project can be found on the wiki page.
|
||||||
|
|
||||||
## Current State
|
## Current State
|
||||||
Abacus is being built for the Northwest Advanced Programming Workshop, a 3 week program in which students work in teams to complete a single project, following principles of agile development. Because of its short timeframe, Abacus is not even close to completed state. Below is a list of the current features and problems.
|
Abacus is being built for the Northwest Advanced Programming Workshop, a 3 week program in which students work in treams to complete a single project, following principles of agile development. Because of its short timeframe, Abacus is not even close to completed state. Below is a list of the current features and problems.
|
||||||
- [x] Basic number class
|
- [x] Basic number class
|
||||||
- [x] Implementation of basic functions
|
- [x] Implementation of basic functions
|
||||||
- [x] Implementation of `exp`, `ln`, `sqrt` using the basic functions and Taylor Series
|
- [x] Implementation of `exp`, `ln`, `sqrt` using the basic functions and Taylor Series
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class Abacus {
|
|||||||
* Creates a new instance of the Abacus calculator.
|
* Creates a new instance of the Abacus calculator.
|
||||||
*/
|
*/
|
||||||
public Abacus() {
|
public Abacus() {
|
||||||
pluginManager = new PluginManager();
|
pluginManager = new PluginManager(this);
|
||||||
numberReducer = new NumberReducer(this);
|
numberReducer = new NumberReducer(this);
|
||||||
configuration = new Configuration(CONFIG_FILE);
|
configuration = new Configuration(CONFIG_FILE);
|
||||||
configuration.saveTo(CONFIG_FILE);
|
configuration.saveTo(CONFIG_FILE);
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import com.moandjiezana.toml.TomlWriter;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The configuration object that stores
|
* The configuration object that stores
|
||||||
@@ -12,26 +15,38 @@ import java.io.IOException;
|
|||||||
*/
|
*/
|
||||||
public class Configuration {
|
public class Configuration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The defaults TOML string.
|
||||||
|
*/
|
||||||
|
private static final String DEFAULT_CONFIG =
|
||||||
|
"numberImplementation = \"naive\"\n" +
|
||||||
|
"disabledPlugins = []";
|
||||||
|
/**
|
||||||
|
* The defaults TOML object, parsed from the string.
|
||||||
|
*/
|
||||||
|
private static final Toml DEFAULT_TOML = new Toml().read(DEFAULT_CONFIG);
|
||||||
/**
|
/**
|
||||||
* The TOML writer used to write this configuration to a file.
|
* The TOML writer used to write this configuration to a file.
|
||||||
*/
|
*/
|
||||||
private static final TomlWriter TOML_WRITER = new TomlWriter();
|
private static final TomlWriter TOML_WRITER = new TomlWriter();
|
||||||
/**
|
|
||||||
* The TOML reader used to load this config from a file.
|
|
||||||
*/
|
|
||||||
private static final Toml TOML_READER = new Toml();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The implementation of the number that should be used.
|
* The implementation of the number that should be used.
|
||||||
*/
|
*/
|
||||||
private String numberImplementation = "naive";
|
private String numberImplementation = "<default>";
|
||||||
|
/**
|
||||||
|
* The list of disabled plugins in this Configuration.
|
||||||
|
*/
|
||||||
|
private Set<String> disabledPlugins = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new configuration with the given values.
|
* Creates a new configuration with the given values.
|
||||||
* @param numberImplementation the number implementation, like "naive" or "precise"
|
* @param numberImplementation the number implementation, like "naive" or "precise"
|
||||||
|
* @param disabledPlugins the list of disabled plugins.
|
||||||
*/
|
*/
|
||||||
public Configuration(String numberImplementation){
|
public Configuration(String numberImplementation, String[] disabledPlugins){
|
||||||
this.numberImplementation = numberImplementation;
|
this.numberImplementation = numberImplementation;
|
||||||
|
this.disabledPlugins.addAll(Arrays.asList(disabledPlugins));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +55,7 @@ public class Configuration {
|
|||||||
*/
|
*/
|
||||||
public Configuration(File fromFile){
|
public Configuration(File fromFile){
|
||||||
if(!fromFile.exists()) return;
|
if(!fromFile.exists()) return;
|
||||||
copyFrom(TOML_READER.read(fromFile).to(Configuration.class));
|
copyFrom(new Toml(DEFAULT_TOML).read(fromFile).to(Configuration.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,6 +64,7 @@ public class Configuration {
|
|||||||
*/
|
*/
|
||||||
public void copyFrom(Configuration otherConfiguration){
|
public void copyFrom(Configuration otherConfiguration){
|
||||||
this.numberImplementation = otherConfiguration.numberImplementation;
|
this.numberImplementation = otherConfiguration.numberImplementation;
|
||||||
|
this.disabledPlugins.addAll(otherConfiguration.disabledPlugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,4 +96,13 @@ public class Configuration {
|
|||||||
public void setNumberImplementation(String numberImplementation) {
|
public void setNumberImplementation(String numberImplementation) {
|
||||||
this.numberImplementation = numberImplementation;
|
this.numberImplementation = numberImplementation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of disabled plugins.
|
||||||
|
* @return the list of disabled plugins.
|
||||||
|
*/
|
||||||
|
public Set<String> getDisabledPlugins() {
|
||||||
|
return disabledPlugins;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,28 @@
|
|||||||
package org.nwapw.abacus.fx;
|
package org.nwapw.abacus.fx;
|
||||||
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.control.cell.CheckBoxListCell;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
|
import javafx.util.StringConverter;
|
||||||
import org.nwapw.abacus.Abacus;
|
import org.nwapw.abacus.Abacus;
|
||||||
|
import org.nwapw.abacus.config.Configuration;
|
||||||
import org.nwapw.abacus.number.NumberInterface;
|
import org.nwapw.abacus.number.NumberInterface;
|
||||||
|
import org.nwapw.abacus.plugin.PluginListener;
|
||||||
|
import org.nwapw.abacus.plugin.PluginManager;
|
||||||
import org.nwapw.abacus.tree.TreeNode;
|
import org.nwapw.abacus.tree.TreeNode;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The controller for the abacus FX UI, responsible
|
* The controller for the abacus FX UI, responsible
|
||||||
* for all the user interaction.
|
* for all the user interaction.
|
||||||
*/
|
*/
|
||||||
public class AbacusController {
|
public class AbacusController implements PluginListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constant string that is displayed if the text could not be lexed or parsed.
|
* Constant string that is displayed if the text could not be lexed or parsed.
|
||||||
@@ -26,10 +32,7 @@ public class AbacusController {
|
|||||||
* Constant string that is displayed if the tree could not be reduced.
|
* Constant string that is displayed if the tree could not be reduced.
|
||||||
*/
|
*/
|
||||||
private static final String ERR_EVAL = "Evaluation Error";
|
private static final String ERR_EVAL = "Evaluation Error";
|
||||||
/**
|
|
||||||
* Constant string that is displayed if the calculations are stopped before they are done.
|
|
||||||
*/
|
|
||||||
private static final String ERR_STOP = "Stopped";
|
|
||||||
@FXML
|
@FXML
|
||||||
private TableView<HistoryModel> historyTable;
|
private TableView<HistoryModel> historyTable;
|
||||||
@FXML
|
@FXML
|
||||||
@@ -46,6 +49,8 @@ public class AbacusController {
|
|||||||
private Button inputButton;
|
private Button inputButton;
|
||||||
@FXML
|
@FXML
|
||||||
private ComboBox<String> numberImplementationBox;
|
private ComboBox<String> numberImplementationBox;
|
||||||
|
@FXML
|
||||||
|
private ListView<ToggleablePlugin> enabledPluginView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of history entries, created by the users.
|
* The list of history entries, created by the users.
|
||||||
@@ -59,36 +64,38 @@ public class AbacusController {
|
|||||||
private ObservableList<String> numberImplementationOptions;
|
private ObservableList<String> numberImplementationOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread used for calculating.
|
* The list of plugin objects that can be toggled on and off,
|
||||||
|
* and, when reloaded, get added to the plugin manager's black list.
|
||||||
*/
|
*/
|
||||||
private Thread calcThread;
|
private ObservableList<ToggleablePlugin> enabledPlugins;
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the calculator is calculating.
|
|
||||||
*/
|
|
||||||
private boolean calculating;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Seconds delayed for timer;
|
|
||||||
*/
|
|
||||||
private double delay = 0;
|
|
||||||
private Abacus abacus;
|
private Abacus abacus;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void initialize(){
|
public void initialize(){
|
||||||
Callback<TableColumn<HistoryModel, String>, TableCell<HistoryModel, String>> cellFactory =
|
Callback<TableColumn<HistoryModel, String>, TableCell<HistoryModel, String>> cellFactory =
|
||||||
param -> new CopyableCell<>();
|
param -> new CopyableCell<>();
|
||||||
|
Callback<ListView<ToggleablePlugin>, ListCell<ToggleablePlugin>> pluginCellFactory =
|
||||||
|
param -> new CheckBoxListCell<>(ToggleablePlugin::enabledProperty, new StringConverter<ToggleablePlugin>() {
|
||||||
|
@Override
|
||||||
|
public String toString(ToggleablePlugin object) {
|
||||||
|
return object.getClassName().substring(object.getClassName().lastIndexOf('.') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ToggleablePlugin fromString(String string) {
|
||||||
|
return new ToggleablePlugin(true, string);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
historyData = FXCollections.observableArrayList();
|
historyData = FXCollections.observableArrayList();
|
||||||
historyTable.setItems(historyData);
|
historyTable.setItems(historyData);
|
||||||
numberImplementationOptions = FXCollections.observableArrayList();
|
numberImplementationOptions = FXCollections.observableArrayList();
|
||||||
numberImplementationBox.setItems(numberImplementationOptions);
|
numberImplementationBox.setItems(numberImplementationOptions);
|
||||||
numberImplementationBox.valueProperty().addListener((observable, oldValue, newValue)
|
|
||||||
-> {
|
|
||||||
abacus.getConfiguration().setNumberImplementation(newValue);
|
|
||||||
abacus.getConfiguration().saveTo(Abacus.CONFIG_FILE);
|
|
||||||
});
|
|
||||||
historyTable.getSelectionModel().setCellSelectionEnabled(true);
|
historyTable.getSelectionModel().setCellSelectionEnabled(true);
|
||||||
|
enabledPlugins = FXCollections.observableArrayList();
|
||||||
|
enabledPluginView.setItems(enabledPlugins);
|
||||||
|
enabledPluginView.setCellFactory(pluginCellFactory);
|
||||||
inputColumn.setCellFactory(cellFactory);
|
inputColumn.setCellFactory(cellFactory);
|
||||||
inputColumn.setCellValueFactory(cell -> cell.getValue().inputProperty());
|
inputColumn.setCellValueFactory(cell -> cell.getValue().inputProperty());
|
||||||
parsedColumn.setCellFactory(cellFactory);
|
parsedColumn.setCellFactory(cellFactory);
|
||||||
@@ -97,71 +104,67 @@ public class AbacusController {
|
|||||||
outputColumn.setCellValueFactory(cell -> cell.getValue().outputProperty());
|
outputColumn.setCellValueFactory(cell -> cell.getValue().outputProperty());
|
||||||
|
|
||||||
abacus = new Abacus();
|
abacus = new Abacus();
|
||||||
numberImplementationOptions.addAll(abacus.getPluginManager().getAllNumbers());
|
abacus.getPluginManager().addListener(this);
|
||||||
String actualImplementation = abacus.getConfiguration().getNumberImplementation();
|
abacus.getPluginManager().reload();
|
||||||
String toSelect = (numberImplementationOptions.contains(actualImplementation)) ? actualImplementation : "naive";
|
|
||||||
numberImplementationBox.getSelectionModel().select(toSelect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void performCalculation(){
|
private void performCalculation(){
|
||||||
Runnable calculator = new Runnable(){
|
inputButton.setDisable(true);
|
||||||
public void run() {
|
TreeNode constructedTree = abacus.parseString(inputField.getText());
|
||||||
if(delay>0) {
|
if(constructedTree == null){
|
||||||
Runnable timer = new Runnable() {
|
outputText.setText(ERR_SYNTAX);
|
||||||
public void run() {
|
inputButton.setDisable(false);
|
||||||
long gap = (long) (delay * 1000);
|
return;
|
||||||
long startTime = System.currentTimeMillis();
|
}
|
||||||
while (System.currentTimeMillis() - startTime <= gap) {
|
NumberInterface evaluatedNumber = abacus.evaluateTree(constructedTree);
|
||||||
}
|
if(evaluatedNumber == null){
|
||||||
stopCalculation();
|
outputText.setText(ERR_EVAL);
|
||||||
}
|
inputButton.setDisable(false);
|
||||||
};
|
return;
|
||||||
Thread maxTime = new Thread(timer);
|
}
|
||||||
maxTime.setName("maxTime");
|
outputText.setText(evaluatedNumber.toString());
|
||||||
maxTime.start();
|
historyData.add(new HistoryModel(inputField.getText(), constructedTree.toString(), evaluatedNumber.toString()));
|
||||||
}
|
|
||||||
calculating = true;
|
|
||||||
Platform.runLater(() -> inputButton.setDisable(true));
|
|
||||||
TreeNode constructedTree = abacus.parseString(inputField.getText());
|
|
||||||
if (constructedTree == null) {
|
|
||||||
Platform.runLater(() ->outputText.setText(ERR_SYNTAX));
|
|
||||||
Platform.runLater(() -> inputButton.setDisable(false));
|
|
||||||
//return;
|
|
||||||
}else {
|
|
||||||
NumberInterface evaluatedNumber = abacus.evaluateTree(constructedTree);
|
|
||||||
if (evaluatedNumber == null) {
|
|
||||||
if(Thread.currentThread().isInterrupted()){
|
|
||||||
Platform.runLater(() -> outputText.setText(ERR_STOP));
|
|
||||||
Platform.runLater(() -> inputButton.setDisable(false));
|
|
||||||
}else {
|
|
||||||
Platform.runLater(() -> outputText.setText(ERR_EVAL));
|
|
||||||
Platform.runLater(() -> inputButton.setDisable(false));
|
|
||||||
//return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Platform.runLater(() -> outputText.setText(evaluatedNumber.toString()));
|
|
||||||
|
|
||||||
historyData.add(new HistoryModel(inputField.getText(), constructedTree.toString(), evaluatedNumber.toString()));
|
inputButton.setDisable(false);
|
||||||
|
inputField.setText("");
|
||||||
|
}
|
||||||
|
|
||||||
Platform.runLater(() -> inputButton.setDisable(false));
|
@FXML
|
||||||
Platform.runLater(() -> inputField.setText(""));
|
private void performReload(){
|
||||||
}
|
Configuration configuration = abacus.getConfiguration();
|
||||||
}
|
Set<String> disabledPlugins = configuration.getDisabledPlugins();
|
||||||
calculating = false;
|
disabledPlugins.clear();
|
||||||
}
|
for(ToggleablePlugin pluginEntry : enabledPlugins){
|
||||||
};
|
if(!pluginEntry.isEnabled()) disabledPlugins.add(pluginEntry.getClassName());
|
||||||
if(!calculating) {
|
}
|
||||||
calcThread = new Thread(calculator);
|
abacus.getPluginManager().reload();
|
||||||
calcThread.setName("calcThread");
|
}
|
||||||
calcThread.start();
|
|
||||||
|
@FXML
|
||||||
|
private void performSave(){
|
||||||
|
Configuration configuration = abacus.getConfiguration();
|
||||||
|
configuration.setNumberImplementation(numberImplementationBox.getSelectionModel().getSelectedItem());
|
||||||
|
configuration.saveTo(Abacus.CONFIG_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad(PluginManager manager) {
|
||||||
|
Configuration configuration = abacus.getConfiguration();
|
||||||
|
Set<String> disabledPlugins = configuration.getDisabledPlugins();
|
||||||
|
numberImplementationOptions.addAll(abacus.getPluginManager().getAllNumbers());
|
||||||
|
String actualImplementation = configuration.getNumberImplementation();
|
||||||
|
String toSelect = (numberImplementationOptions.contains(actualImplementation)) ? actualImplementation : "<default>";
|
||||||
|
numberImplementationBox.getSelectionModel().select(toSelect);
|
||||||
|
for(Class<?> pluginClass : abacus.getPluginManager().getLoadedPluginClasses()){
|
||||||
|
String fullName = pluginClass.getName();
|
||||||
|
enabledPlugins.add(new ToggleablePlugin(!disabledPlugins.contains(fullName), fullName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@FXML
|
|
||||||
private void stopCalculation(){
|
|
||||||
calcThread.interrupt();
|
|
||||||
calculating = false;
|
|
||||||
//Platform.runLater(() ->inputButton.setDisable(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUnload(PluginManager manager) {
|
||||||
|
enabledPlugins.clear();
|
||||||
|
numberImplementationOptions.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
src/main/java/org/nwapw/abacus/fx/ToggleablePlugin.java
Normal file
29
src/main/java/org/nwapw/abacus/fx/ToggleablePlugin.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package org.nwapw.abacus.fx;
|
||||||
|
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
|
||||||
|
public class ToggleablePlugin {
|
||||||
|
|
||||||
|
private final BooleanProperty enabled;
|
||||||
|
private final String className;
|
||||||
|
|
||||||
|
public ToggleablePlugin(boolean enabled, String className){
|
||||||
|
this.enabled = new SimpleBooleanProperty();
|
||||||
|
this.enabled.setValue(enabled);
|
||||||
|
this.className = className;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty enabledProperty() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClassName() {
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.nwapw.abacus.plugin;
|
package org.nwapw.abacus.plugin;
|
||||||
|
|
||||||
|
import org.nwapw.abacus.Abacus;
|
||||||
import org.nwapw.abacus.function.Function;
|
import org.nwapw.abacus.function.Function;
|
||||||
import org.nwapw.abacus.function.Operator;
|
import org.nwapw.abacus.function.Operator;
|
||||||
import org.nwapw.abacus.number.NumberInterface;
|
import org.nwapw.abacus.number.NumberInterface;
|
||||||
@@ -52,11 +53,17 @@ public class PluginManager {
|
|||||||
* The list of plugin listeners attached to this instance.
|
* The list of plugin listeners attached to this instance.
|
||||||
*/
|
*/
|
||||||
private Set<PluginListener> listeners;
|
private Set<PluginListener> listeners;
|
||||||
|
/**
|
||||||
|
* The abacus instance used to access other
|
||||||
|
* components of the application.
|
||||||
|
*/
|
||||||
|
private Abacus abacus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new plugin manager.
|
* Creates a new plugin manager.
|
||||||
*/
|
*/
|
||||||
public PluginManager() {
|
public PluginManager(Abacus abacus) {
|
||||||
|
this.abacus = abacus;
|
||||||
loadedPluginClasses = new HashSet<>();
|
loadedPluginClasses = new HashSet<>();
|
||||||
plugins = new HashSet<>();
|
plugins = new HashSet<>();
|
||||||
cachedFunctions = new HashMap<>();
|
cachedFunctions = new HashMap<>();
|
||||||
@@ -160,8 +167,13 @@ public class PluginManager {
|
|||||||
* Loads all the plugins in the PluginManager.
|
* Loads all the plugins in the PluginManager.
|
||||||
*/
|
*/
|
||||||
public void load() {
|
public void load() {
|
||||||
for (Plugin plugin : plugins) plugin.enable();
|
Set<String> disabledPlugins = abacus.getConfiguration().getDisabledPlugins();
|
||||||
for (Plugin plugin : plugins) {
|
for (Plugin plugin : plugins) {
|
||||||
|
if(disabledPlugins.contains(plugin.getClass().getName())) continue;
|
||||||
|
plugin.enable();
|
||||||
|
}
|
||||||
|
for (Plugin plugin : plugins) {
|
||||||
|
if(disabledPlugins.contains(plugin.getClass().getName())) continue;
|
||||||
allFunctions.addAll(plugin.providedFunctions());
|
allFunctions.addAll(plugin.providedFunctions());
|
||||||
allOperators.addAll(plugin.providedOperators());
|
allOperators.addAll(plugin.providedOperators());
|
||||||
allNumbers.addAll(plugin.providedNumbers());
|
allNumbers.addAll(plugin.providedNumbers());
|
||||||
@@ -173,11 +185,18 @@ public class PluginManager {
|
|||||||
* Unloads all the plugins in the PluginManager.
|
* Unloads all the plugins in the PluginManager.
|
||||||
*/
|
*/
|
||||||
public void unload() {
|
public void unload() {
|
||||||
for (Plugin plugin : plugins) plugin.disable();
|
listeners.forEach(e -> e.onUnload(this));
|
||||||
|
Set<String> disabledPlugins = abacus.getConfiguration().getDisabledPlugins();
|
||||||
|
for (Plugin plugin : plugins) {
|
||||||
|
if(disabledPlugins.contains(plugin.getClass().getName())) continue;
|
||||||
|
plugin.disable();
|
||||||
|
}
|
||||||
|
cachedFunctions.clear();
|
||||||
|
cachedOperators.clear();
|
||||||
|
cachedNumbers.clear();
|
||||||
allFunctions.clear();
|
allFunctions.clear();
|
||||||
allOperators.clear();
|
allOperators.clear();
|
||||||
allNumbers.clear();
|
allNumbers.clear();
|
||||||
listeners.forEach(e -> e.onUnload(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -185,7 +204,7 @@ public class PluginManager {
|
|||||||
*/
|
*/
|
||||||
public void reload() {
|
public void reload() {
|
||||||
unload();
|
unload();
|
||||||
reload();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -233,4 +252,12 @@ public class PluginManager {
|
|||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of all the plugin class files that have been
|
||||||
|
* added to the plugin manager.
|
||||||
|
* @return the list of all the added plugin classes.
|
||||||
|
*/
|
||||||
|
public Set<Class<?>> getLoadedPluginClasses() {
|
||||||
|
return loadedPluginClasses;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,13 +31,9 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
NumberInterface sum = params[0];
|
NumberInterface sum = params[0];
|
||||||
for (int i = 1; i < params.length; i++) {
|
for (int i = 1; i < params.length; i++) {
|
||||||
sum = sum.add(params[i]);
|
sum = sum.add(params[i]);
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
@@ -53,10 +49,7 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return params[0].subtract(params[1]);
|
return params[0].subtract(params[1]);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/**
|
/**
|
||||||
@@ -70,8 +63,6 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return params[0].negate();
|
return params[0].negate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -86,13 +77,9 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
NumberInterface product = params[0];
|
NumberInterface product = params[0];
|
||||||
for (int i = 1; i < params.length; i++) {
|
for (int i = 1; i < params.length; i++) {
|
||||||
product = product.multiply(params[i]);
|
product = product.multiply(params[i]);
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
@@ -108,8 +95,6 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return params[0].divide(params[1]);
|
return params[0].divide(params[1]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -125,19 +110,15 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
if (params[0].signum() == 0) {
|
if (params[0].signum() == 0) {
|
||||||
return (new NaiveNumber(1)).promoteTo(params[0].getClass());
|
return (new NaiveNumber(1)).promoteTo(params[0].getClass());
|
||||||
}
|
}
|
||||||
NumberInterface factorial = params[0];
|
NumberInterface factorial = params[0];
|
||||||
NumberInterface multiplier = params[0];
|
NumberInterface multiplier = params[0];
|
||||||
//It is necessary to later prevent calls of factorial on anything but non-negative integers.
|
//It is necessary to later prevent calls of factorial on anything but non-negative integers.
|
||||||
while (!Thread.currentThread().isInterrupted()&&(multiplier = multiplier.subtract(NaiveNumber.ONE.promoteTo(multiplier.getClass())))!=null&&multiplier.signum() == 1) {
|
while ((multiplier = multiplier.subtract(NaiveNumber.ONE.promoteTo(multiplier.getClass()))).signum() == 1) {
|
||||||
factorial = factorial.multiply(multiplier);
|
factorial = factorial.multiply(multiplier);
|
||||||
}
|
}
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return factorial;
|
return factorial;
|
||||||
/*if(!storedList.containsKey(params[0].getClass())){
|
/*if(!storedList.containsKey(params[0].getClass())){
|
||||||
storedList.put(params[0].getClass(), new ArrayList<NumberInterface>());
|
storedList.put(params[0].getClass(), new ArrayList<NumberInterface>());
|
||||||
@@ -157,12 +138,7 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
return FUNCTION_EXP.apply(FUNCTION_LN.apply(params[0]).multiply(params[1]));
|
||||||
return null;
|
|
||||||
NumberInterface check;
|
|
||||||
if((check = FUNCTION_EXP.apply(FUNCTION_LN.apply(params[0])))!=null&&(check = check.multiply(params[1]))!=null)
|
|
||||||
return check;
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/**
|
/**
|
||||||
@@ -176,8 +152,6 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return params[0].multiply((new NaiveNumber(params[0].signum())).promoteTo(params[0].getClass()));
|
return params[0].multiply((new NaiveNumber(params[0].signum())).promoteTo(params[0].getClass()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -192,17 +166,14 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
NumberInterface maxError = getMaxError(params[0]);
|
NumberInterface maxError = getMaxError(params[0]);
|
||||||
int n = 0;
|
int n = 0;
|
||||||
if(params[0].signum() <= 0){
|
if(params[0].signum() <= 0){
|
||||||
NumberInterface currentTerm = NaiveNumber.ONE.promoteTo(params[0].getClass()), sum = currentTerm;
|
NumberInterface currentTerm = NaiveNumber.ONE.promoteTo(params[0].getClass()), sum = currentTerm;
|
||||||
NumberInterface check;
|
while(FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0){
|
||||||
while((check = FUNCTION_ABS.apply(currentTerm))!=null && (check.compareTo(maxError) > 0)){
|
|
||||||
n++;
|
n++;
|
||||||
if(Thread.currentThread().isInterrupted()||(currentTerm = currentTerm.multiply(params[0]))==null||(currentTerm = currentTerm.divide((new NaiveNumber(n)).promoteTo(params[0].getClass())))==null||(sum = (sum.add(currentTerm)))==null)
|
currentTerm = currentTerm.multiply(params[0]).divide((new NaiveNumber(n)).promoteTo(params[0].getClass()));
|
||||||
return null;
|
sum = sum.add(currentTerm);
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
@@ -211,28 +182,18 @@ public class StandardPlugin extends Plugin {
|
|||||||
//right and left refer to lhs and rhs in the above inequality.
|
//right and left refer to lhs and rhs in the above inequality.
|
||||||
NumberInterface sum = NaiveNumber.ONE.promoteTo(params[0].getClass());
|
NumberInterface sum = NaiveNumber.ONE.promoteTo(params[0].getClass());
|
||||||
NumberInterface nextNumerator = params[0];
|
NumberInterface nextNumerator = params[0];
|
||||||
//NumberInterface left = params[0].multiply((new NaiveNumber(3)).promoteTo(params[0].getClass()).intPow(params[0].ceiling())), right = maxError;
|
NumberInterface left = params[0].multiply((new NaiveNumber(3)).promoteTo(params[0].getClass()).intPow(params[0].ceiling())), right = maxError;
|
||||||
NumberInterface check;
|
|
||||||
if((check =intPow(new NaiveNumber(3).promoteTo(params[0].getClass()),params[0].getClass(),(new NaiveNumber(params[0].ceiling())).promoteTo(params[0].getClass())))==null)
|
|
||||||
return null;
|
|
||||||
NumberInterface left = params[0].multiply(check), right = maxError;
|
|
||||||
do{
|
do{
|
||||||
if((check = factorial(params[0].getClass(),n+1))==null||(check = nextNumerator.divide(check))==null||(sum = sum.add(check))==null)
|
sum = sum.add(nextNumerator.divide(factorial(params[0].getClass(), n+1)));
|
||||||
return null;
|
|
||||||
n++;
|
n++;
|
||||||
if((nextNumerator = nextNumerator.multiply(params[0]))==null)
|
nextNumerator = nextNumerator.multiply(params[0]);
|
||||||
return null;
|
left = left.multiply(params[0]);
|
||||||
if((left = left.multiply(params[0]))==null)
|
|
||||||
return null;
|
|
||||||
NumberInterface nextN = (new NaiveNumber(n+1)).promoteTo(params[0].getClass());
|
NumberInterface nextN = (new NaiveNumber(n+1)).promoteTo(params[0].getClass());
|
||||||
if((right = right.multiply(nextN))==null)
|
right = right.multiply(nextN);
|
||||||
return null;
|
|
||||||
//System.out.println(left + ", " + right);
|
//System.out.println(left + ", " + right);
|
||||||
}
|
}
|
||||||
while(!Thread.currentThread().isInterrupted()&&left.compareTo(right) > 0);
|
while(left.compareTo(right) > 0);
|
||||||
//System.out.println(n+1);
|
//System.out.println(n+1);
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,32 +209,26 @@ public class StandardPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
NumberInterface param = params[0];
|
NumberInterface param = params[0];
|
||||||
int powersOf2 = 0;
|
int powersOf2 = 0;
|
||||||
NumberInterface check;
|
while (FUNCTION_ABS.apply(param.subtract(NaiveNumber.ONE.promoteTo(param.getClass()))).compareTo((new NaiveNumber(0.1)).promoteTo(param.getClass())) >= 0) {
|
||||||
while (!Thread.currentThread().isInterrupted()&&(check = FUNCTION_ABS.apply(param.subtract(NaiveNumber.ONE.promoteTo(param.getClass()))))!=null&&(check.compareTo((new NaiveNumber(0.1)).promoteTo(param.getClass()))) >= 0) {
|
if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() == 1) {
|
||||||
if ((check = param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())))!=null&&check.signum() == 1) {
|
|
||||||
param = param.divide(new NaiveNumber(2).promoteTo(param.getClass()));
|
param = param.divide(new NaiveNumber(2).promoteTo(param.getClass()));
|
||||||
powersOf2++;
|
powersOf2++;
|
||||||
if ((check = param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())))==null||check.signum() != 1) {
|
if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() != 1) {
|
||||||
break;
|
break;
|
||||||
//No infinite loop for you.
|
//No infinite loop for you.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
param = param.multiply(new NaiveNumber(2).promoteTo(param.getClass()));
|
param = param.multiply(new NaiveNumber(2).promoteTo(param.getClass()));
|
||||||
powersOf2--;
|
powersOf2--;
|
||||||
if ((check = param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())))==null||check.signum() != 1) {
|
if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() != 1) {
|
||||||
break;
|
break;
|
||||||
//No infinite loop for you.
|
//No infinite loop for you.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumberInterface check2;
|
return getLog2(param).multiply((new NaiveNumber(powersOf2)).promoteTo(param.getClass())).add(getLogPartialSum(param));
|
||||||
if(!Thread.currentThread().isInterrupted()&&(check = getLog2(param))!=null&&(check = check.multiply((new NaiveNumber(powersOf2).promoteTo(param.getClass()))))!=null&&(check2 = getLogPartialSum(param))!=null&&(check = check.add(check2))!=null)
|
|
||||||
return check;
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -283,23 +238,16 @@ public class StandardPlugin extends Plugin {
|
|||||||
* @return the partial sum.
|
* @return the partial sum.
|
||||||
*/
|
*/
|
||||||
private NumberInterface getLogPartialSum(NumberInterface x) {
|
private NumberInterface getLogPartialSum(NumberInterface x) {
|
||||||
|
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
NumberInterface maxError = getMaxError(x);
|
NumberInterface maxError = getMaxError(x);
|
||||||
x = x.subtract(NaiveNumber.ONE.promoteTo(x.getClass())); //Terms used are for log(x+1).
|
x = x.subtract(NaiveNumber.ONE.promoteTo(x.getClass())); //Terms used are for log(x+1).
|
||||||
NumberInterface currentNumerator = x, currentTerm = x, sum = x;
|
NumberInterface currentNumerator = x, currentTerm = x, sum = x;
|
||||||
int n = 1;
|
int n = 1;
|
||||||
NumberInterface check;
|
while (FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0) {
|
||||||
while (!Thread.currentThread().isInterrupted()&&(check = FUNCTION_ABS.apply(currentTerm))!=null&&check.compareTo(maxError) > 0) {
|
|
||||||
n++;
|
n++;
|
||||||
if((currentNumerator = currentNumerator.multiply(x))==null||(currentNumerator = currentNumerator.negate())==null)
|
currentNumerator = currentNumerator.multiply(x).negate();
|
||||||
return null;
|
|
||||||
currentTerm = currentNumerator.divide(new NaiveNumber(n).promoteTo(x.getClass()));
|
currentTerm = currentNumerator.divide(new NaiveNumber(n).promoteTo(x.getClass()));
|
||||||
sum = sum.add(currentTerm);
|
sum = sum.add(currentTerm);
|
||||||
}
|
}
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,8 +257,6 @@ public class StandardPlugin extends Plugin {
|
|||||||
* @return the value of log(2) with the appropriate precision.
|
* @return the value of log(2) with the appropriate precision.
|
||||||
*/
|
*/
|
||||||
private NumberInterface getLog2(NumberInterface number) {
|
private NumberInterface getLog2(NumberInterface number) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
NumberInterface maxError = getMaxError(number);
|
NumberInterface maxError = getMaxError(number);
|
||||||
//NumberInterface errorBound = (new NaiveNumber(1)).promoteTo(number.getClass());
|
//NumberInterface errorBound = (new NaiveNumber(1)).promoteTo(number.getClass());
|
||||||
//We'll use the series \sigma_{n >= 1) ((1/3^n + 1/4^n) * 1/n)
|
//We'll use the series \sigma_{n >= 1) ((1/3^n + 1/4^n) * 1/n)
|
||||||
@@ -319,17 +265,13 @@ public class StandardPlugin extends Plugin {
|
|||||||
NumberInterface a = (new NaiveNumber(1)).promoteTo(number.getClass()), b = a, c = a;
|
NumberInterface a = (new NaiveNumber(1)).promoteTo(number.getClass()), b = a, c = a;
|
||||||
NumberInterface sum = NaiveNumber.ZERO.promoteTo(number.getClass());
|
NumberInterface sum = NaiveNumber.ZERO.promoteTo(number.getClass());
|
||||||
int n = 0;
|
int n = 0;
|
||||||
while (!Thread.currentThread().isInterrupted()&&a.compareTo(maxError) >= 1) {
|
while (a.compareTo(maxError) >= 1) {
|
||||||
n++;
|
n++;
|
||||||
a = a.divide((new NaiveNumber(3)).promoteTo(number.getClass()));
|
a = a.divide((new NaiveNumber(3)).promoteTo(number.getClass()));
|
||||||
b = b.divide((new NaiveNumber(4)).promoteTo(number.getClass()));
|
b = b.divide((new NaiveNumber(4)).promoteTo(number.getClass()));
|
||||||
c = NaiveNumber.ONE.promoteTo(number.getClass()).divide((new NaiveNumber(n)).promoteTo(number.getClass()));
|
c = NaiveNumber.ONE.promoteTo(number.getClass()).divide((new NaiveNumber(n)).promoteTo(number.getClass()));
|
||||||
NumberInterface check;
|
sum = sum.add(a.add(b).multiply(c));
|
||||||
if(a==null||(check = a.add(b))==null||(check = check.multiply(c))==null||(sum = sum.add(check))==null)
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -403,8 +345,6 @@ public class StandardPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static NumberInterface factorial(Class<? extends NumberInterface> numberClass, int n){
|
public static NumberInterface factorial(Class<? extends NumberInterface> numberClass, int n){
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
if(!factorialLists.containsKey(numberClass)){
|
if(!factorialLists.containsKey(numberClass)){
|
||||||
factorialLists.put(numberClass, new ArrayList<>());
|
factorialLists.put(numberClass, new ArrayList<>());
|
||||||
factorialLists.get(numberClass).add(NaiveNumber.ONE.promoteTo(numberClass));
|
factorialLists.get(numberClass).add(NaiveNumber.ONE.promoteTo(numberClass));
|
||||||
@@ -412,34 +352,11 @@ public class StandardPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
ArrayList<NumberInterface> list = factorialLists.get(numberClass);
|
ArrayList<NumberInterface> list = factorialLists.get(numberClass);
|
||||||
if(n >= list.size()){
|
if(n >= list.size()){
|
||||||
while(!Thread.currentThread().isInterrupted()&&list.size() < n + 16){
|
while(list.size() < n + 16){
|
||||||
list.add(list.get(list.size()-1).multiply(new NaiveNumber(list.size()).promoteTo(numberClass)));
|
list.add(list.get(list.size()-1).multiply(new NaiveNumber(list.size()).promoteTo(numberClass)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return list.get(n);
|
return list.get(n);
|
||||||
}
|
}
|
||||||
public static NumberInterface intPow(NumberInterface number, Class<? extends NumberInterface> numberClass,NumberInterface exponent) {
|
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
if (exponent.compareTo((new NaiveNumber(0)).promoteTo(numberClass))==0) {
|
|
||||||
return (new NaiveNumber(1)).promoteTo(numberClass);
|
|
||||||
}
|
|
||||||
boolean takeReciprocal = exponent.compareTo((new NaiveNumber(0)).promoteTo(numberClass))<0;
|
|
||||||
exponent = FUNCTION_ABS.apply(exponent);
|
|
||||||
NumberInterface power = number;
|
|
||||||
for(NumberInterface currentExponent =(new NaiveNumber(1)).promoteTo(numberClass);currentExponent.compareTo(exponent)<0;currentExponent = currentExponent.add((new NaiveNumber(1)).promoteTo(numberClass))){
|
|
||||||
power = power.multiply(number);
|
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (takeReciprocal) {
|
|
||||||
power = (new NaiveNumber(1)).promoteTo(numberClass).divide(power);
|
|
||||||
}
|
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return power;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,15 +92,10 @@ public class BinaryNode extends TreeNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T reduce(Reducer<T> reducer) {
|
public <T> T reduce(Reducer<T> reducer) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
T leftReduce = left.reduce(reducer);
|
T leftReduce = left.reduce(reducer);
|
||||||
T rightReduce = right.reduce(reducer);
|
T rightReduce = right.reduce(reducer);
|
||||||
if (leftReduce == null || rightReduce == null) return null;
|
if (leftReduce == null || rightReduce == null) return null;
|
||||||
T a = reducer.reduceNode(this, leftReduce, rightReduce);
|
return reducer.reduceNode(this, leftReduce, rightReduce);
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -62,17 +62,12 @@ public class FunctionNode extends TreeNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T reduce(Reducer<T> reducer) {
|
public <T> T reduce(Reducer<T> reducer) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
Object[] reducedChildren = new Object[children.size()];
|
Object[] reducedChildren = new Object[children.size()];
|
||||||
for (int i = 0; i < reducedChildren.length; i++) {
|
for (int i = 0; i < reducedChildren.length; i++) {
|
||||||
reducedChildren[i] = children.get(i).reduce(reducer);
|
reducedChildren[i] = children.get(i).reduce(reducer);
|
||||||
if (Thread.currentThread().isInterrupted()||reducedChildren[i] == null) return null;
|
if (reducedChildren[i] == null) return null;
|
||||||
}
|
}
|
||||||
T a = reducer.reduceNode(this, reducedChildren);
|
return reducer.reduceNode(this, reducedChildren);
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -33,14 +33,9 @@ public class UnaryNode extends TreeNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T reduce(Reducer<T> reducer) {
|
public <T> T reduce(Reducer<T> reducer) {
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
Object reducedChild = applyTo.reduce(reducer);
|
Object reducedChild = applyTo.reduce(reducer);
|
||||||
if (reducedChild == null) return null;
|
if (reducedChild == null) return null;
|
||||||
T a = reducer.reduceNode(this, reducedChild);
|
return reducer.reduceNode(this, reducedChild);
|
||||||
if(Thread.currentThread().isInterrupted())
|
|
||||||
return null;
|
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -37,8 +37,6 @@
|
|||||||
<TextField fx:id="inputField" onAction="#performCalculation"/>
|
<TextField fx:id="inputField" onAction="#performCalculation"/>
|
||||||
<Button fx:id="inputButton" text="Calculate" maxWidth="Infinity"
|
<Button fx:id="inputButton" text="Calculate" maxWidth="Infinity"
|
||||||
onAction="#performCalculation"/>
|
onAction="#performCalculation"/>
|
||||||
<Button fx:id="stopButton" text="Stop" maxWidth="Infinity"
|
|
||||||
onAction="#stopCalculation"/>
|
|
||||||
</VBox>
|
</VBox>
|
||||||
</bottom>
|
</bottom>
|
||||||
</BorderPane>
|
</BorderPane>
|
||||||
@@ -48,6 +46,13 @@
|
|||||||
<padding><Insets left="10" right="10" top="10" bottom="10"/></padding>
|
<padding><Insets left="10" right="10" top="10" bottom="10"/></padding>
|
||||||
<Label text="Number Implementation" GridPane.columnIndex="0" GridPane.rowIndex="0"/>
|
<Label text="Number Implementation" GridPane.columnIndex="0" GridPane.rowIndex="0"/>
|
||||||
<ComboBox fx:id="numberImplementationBox" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
|
<ComboBox fx:id="numberImplementationBox" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
|
||||||
|
<ListView fx:id="enabledPluginView"
|
||||||
|
GridPane.rowIndex="1" GridPane.columnIndex="0"
|
||||||
|
GridPane.columnSpan="2" maxHeight="100"/>
|
||||||
|
<HBox GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="2" spacing="10">
|
||||||
|
<Button text="Apply" onAction="#performSave"/>
|
||||||
|
<Button text="Reload" onAction="#performReload"/>
|
||||||
|
</HBox>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</Tab>
|
</Tab>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
|||||||
Reference in New Issue
Block a user