diff --git a/core/build.gradle b/core/build.gradle index 5aff72f..18889df 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,4 +1,3 @@ dependencies { - compile 'com.moandjiezana.toml:toml4j:0.7.1' testCompile 'junit:junit:4.12' } diff --git a/core/src/main/java/org/nwapw/abacus/config/Configuration.java b/core/src/main/java/org/nwapw/abacus/config/Configuration.java deleted file mode 100644 index 284e80d..0000000 --- a/core/src/main/java/org/nwapw/abacus/config/Configuration.java +++ /dev/null @@ -1,159 +0,0 @@ -package org.nwapw.abacus.config; - -import com.moandjiezana.toml.Toml; -import com.moandjiezana.toml.TomlWriter; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * The configuration object that stores - * options that the user can change. - */ -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. - */ - 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. - */ - private String numberImplementation = ""; - /** - * The list of disabled plugins in this Configuration. - */ - private Set disabledPlugins = new HashSet<>(); - - /** - * Creates a new configuration form the given configuration. - * - * @param copyFrom the configuration to copy. - */ - public Configuration(Configuration copyFrom) { - copyFrom(copyFrom); - } - - /** - * 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(double computationDelay, String numberImplementation, String[] disabledPlugins) { - this.computationDelay = computationDelay; - this.numberImplementation = numberImplementation; - this.disabledPlugins.addAll(Arrays.asList(disabledPlugins)); - } - - /** - * Loads a configuration from a given file, keeping non-specified fields default. - * - * @param fromFile the file to load from. - */ - public Configuration(File fromFile) { - if (!fromFile.exists()) return; - copyFrom(new Toml(DEFAULT_TOML).read(fromFile).to(Configuration.class)); - } - - /** - * Copies the values from the given configuration into this one. - * - * @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); - } - - /** - * Saves this configuration to the given file, creating - * any directories that do not exist. - * - * @param file the file to save to. - */ - public void saveTo(File file) { - if (file.getParentFile() != null) file.getParentFile().mkdirs(); - try { - TOML_WRITER.write(this, file); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Gets the value of this configuration as a string. - * - * @return the string that represents this configuration. - */ - public String asTomlString() { - return TOML_WRITER.write(this); - } - - /** - * Gets the number implementation from this configuration. - * - * @return the number implementation. - */ - public String getNumberImplementation() { - return numberImplementation; - } - - /** - * Sets the number implementation for the configuration - * - * @param numberImplementation the number implementation. - */ - public void setNumberImplementation(String numberImplementation) { - this.numberImplementation = numberImplementation; - } - - /** - * Gets the list of disabled plugins. - * - * @return the list of disabled plugins. - */ - public Set getDisabledPlugins() { - 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/core/src/main/kotlin/org/nwapw/abacus/config/Configuration.kt b/core/src/main/kotlin/org/nwapw/abacus/config/Configuration.kt new file mode 100644 index 0000000..e622910 --- /dev/null +++ b/core/src/main/kotlin/org/nwapw/abacus/config/Configuration.kt @@ -0,0 +1,20 @@ +package org.nwapw.abacus.config + +/** + * A class that holds information that tells Abacus how to behave. + * + * Configuration stores information about how Abacus should behave, for + * instance, what number implementation it should use and what + * plugins should be ignored during loading. + * + * @property numberImplementation the number implementation Abacus should use for loading. + * @param disabledPlugins the plugins that should be disabled and not loaded by the plugin manager. + */ +open class Configuration(var numberImplementation: String = "", disabledPlugins: Array = emptyArray()) { + + /** + * The set of disabled plugins that should be ignored by the plugin manager. + */ + val disabledPlugins = disabledPlugins.toMutableSet() + +} \ No newline at end of file diff --git a/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java b/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java index 0a00289..af85be6 100755 --- a/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java +++ b/core/src/test/java/org/nwapw/abacus/tests/CalculationTests.java @@ -12,7 +12,7 @@ import org.nwapw.abacus.tree.TreeNode; public class CalculationTests { - private static Abacus abacus = new Abacus(new Configuration(0, "precise", new String[]{})); + private static Abacus abacus = new Abacus(new Configuration( "precise", new String[]{})); @BeforeClass public static void prepareTests() { diff --git a/core/src/test/java/org/nwapw/abacus/tests/TokenizerTests.java b/core/src/test/java/org/nwapw/abacus/tests/TokenizerTests.java index d22f94d..8293bd4 100644 --- a/core/src/test/java/org/nwapw/abacus/tests/TokenizerTests.java +++ b/core/src/test/java/org/nwapw/abacus/tests/TokenizerTests.java @@ -17,7 +17,7 @@ import java.util.List; public class TokenizerTests { - private static Abacus abacus = new Abacus(new Configuration(0, "precise", new String[]{})); + private static Abacus abacus = new Abacus(new Configuration("precise", new String[]{})); private static LexerTokenizer lexerTokenizer = new LexerTokenizer(); private static NumberFunction subtractFunction = new NumberFunction() { @Override diff --git a/docs/_layouts/home.html b/docs/_layouts/home.html index bb7cb68..4d2c482 100644 --- a/docs/_layouts/home.html +++ b/docs/_layouts/home.html @@ -3,6 +3,7 @@ {% include head.html %} @@ -49,5 +102,58 @@ Wiki +

Features

+
+
+ +
+
+

Precision

+ Abacus uses a mathematical tool called Taylor Series to determine values + as accurate as the user desires. Of course, this comes with some + performance issues with larger numbers. However, Abacus has been + tested to generate the value of e correctly to a thousand digits. +
+
+
+
+

Configurable and Customizable

+ The very first idea for Abacus was inspired by how difficult it was + to program a TI-84 calculator. Only two languages were available, TI-BASIC + and Assembly, the latter having virtually no documentation. Determined + to be better than a TI-84, Abacus implemented a plugin system that allows + users to easily create and add plugins written in the same programming + language as Abacus itself - Java. These plugins can access the full + power of the language, and implement their own ways of handling numbers, + as well as their own functions and even operators.

+ Besides the ability to add plugins, Abacus also adds some general + options that can be used to make the user's experience more pleasant. + For instance, it allows for a computation limit to be set in order + to prevent excessively long evaluation: 8!!! is, for example, an expression + that even Wolfram Alpha doesn't compute accurately, and will never finish + on Abacus (it's simply too large). The computation limit will allow Abacus + to kill a computation if it takes too long. Support for user-definable + precision is also planned. +
+
+ +
+
+
+
+ +
+
+

Built-in Documentation

+ Abacus plugins are given a mechanism to register documentation for + the functions that they provide. The Abacus GUI displays these + functions in a searchable list, allowing the user to read the parameters + that have to be supplied to each function, as well as learn about + its return value.

+ The search finds functions not only by their names, but also by relevant + terms mentioned in the function's description, thus allowing related + functions to be displayed together. +
+
diff --git a/docs/assets/css/main.scss b/docs/assets/css/main.scss index f7c9664..0d1398d 100644 --- a/docs/assets/css/main.scss +++ b/docs/assets/css/main.scss @@ -7,7 +7,7 @@ $code-color: #efefef; $accent-color: #00AFE8; $clear-color: white; $title-font: "Open Sans"; -$text-font: Helvetica; +$text-font: "Raleway"; $code-font: "Source Code Pro"; $max-width: 850px; diff --git a/fx/build.gradle b/fx/build.gradle index d72592b..2380c71 100644 --- a/fx/build.gradle +++ b/fx/build.gradle @@ -1,6 +1,7 @@ apply plugin: 'application' dependencies { + compile 'com.moandjiezana.toml:toml4j:0.7.1' compile project(':core') } diff --git a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java index 435da06..5f23a9a 100644 --- a/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/fx/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -200,7 +200,7 @@ public class AbacusController implements PluginListener { */ private final Runnable TIMER_RUNNABLE = () -> { try { - Configuration abacusConfig = abacus.getConfiguration(); + ExtendedConfiguration abacusConfig = (ExtendedConfiguration) abacus.getConfiguration(); if (abacusConfig.getComputationDelay() == 0) return; Thread.sleep((long) (abacusConfig.getComputationDelay() * 1000)); performStop(); @@ -260,12 +260,12 @@ public class AbacusController implements PluginListener { if (oldValue.equals(settingsTab)) alertIfApplyNeeded(true); }); - abacus = new Abacus(new Configuration(CONFIG_FILE)); + abacus = new Abacus(new ExtendedConfiguration(CONFIG_FILE)); PluginManager abacusPluginManager = abacus.getPluginManager(); abacusPluginManager.addListener(this); performScan(); - computationLimitField.setText(Double.toString(abacus.getConfiguration().getComputationDelay())); + computationLimitField.setText(Double.toString(((ExtendedConfiguration) abacus.getConfiguration()).getComputationDelay())); computationLimitField.textProperty().addListener((observable, oldValue, newValue) -> { if (!newValue.matches("(\\d+(\\.\\d*)?)?")) { computationLimitField.setText(oldValue); @@ -342,8 +342,8 @@ public class AbacusController implements PluginListener { if (!pluginEntry.isEnabled()) disabledPlugins.add(pluginEntry.getClassName()); } if (computationLimitField.getText().matches("\\d*(\\.\\d+)?") && computationLimitField.getText().length() != 0) - configuration.setComputationDelay(Double.parseDouble(computationLimitField.getText())); - configuration.saveTo(CONFIG_FILE); + ((ExtendedConfiguration) configuration).setComputationDelay(Double.parseDouble(computationLimitField.getText())); + ((ExtendedConfiguration) configuration).saveTo(CONFIG_FILE); changesMade = false; reloadAlertShown = false; } diff --git a/fx/src/main/kotlin/org/nwapw/abacus/fx/ExtendedConfiguration.kt b/fx/src/main/kotlin/org/nwapw/abacus/fx/ExtendedConfiguration.kt new file mode 100644 index 0000000..9c0b152 --- /dev/null +++ b/fx/src/main/kotlin/org/nwapw/abacus/fx/ExtendedConfiguration.kt @@ -0,0 +1,70 @@ +package org.nwapw.abacus.fx + +import com.moandjiezana.toml.Toml +import com.moandjiezana.toml.TomlWriter +import org.nwapw.abacus.config.Configuration +import java.io.File + +/** + * Additional settings for user interface. + * + * ExtendedConfiguration is used to add other settings + * that aren't built into Abacus core, but are necessary + * for the fx module. + * + * @property computationDelay the delay before which the computation stops. + * @param implementation the number implementation, same as [Configuration.numberImplementation] + * @param disabledPlugins the list of plugins that should be disabled, same as [Configuration.disabledPlugins] + */ +class ExtendedConfiguration(var computationDelay: Double = 0.0, + implementation: String = "", + disabledPlugins: Array = emptyArray()) + : Configuration(implementation, disabledPlugins) { + + companion object { + /** + * The default TOML. + */ + val DEFAULT_TOML_STRING = """ + computationDelay=0.0 + implementation="naive" + disabledPlugins=[] + """ + /** + * A reader with the default TOML data. + */ + val DEFAULT_TOML_READER = Toml().read(DEFAULT_TOML_STRING) + /** + * A writer used to writing the configuration to disk. + */ + val DEFAULT_TOML_WRITER = TomlWriter() + } + + /** + * Constructs a new configuration from a file on disk. + * @param tomlFile the file from disk to load. + */ + constructor(tomlFile: File) : this() { + copyFrom(Toml(DEFAULT_TOML_READER).read(tomlFile).to(ExtendedConfiguration::class.java)) + } + + /** + * Copies data from another configuration into this one. + * @param config the configuration to copy from. + */ + fun copyFrom(config: ExtendedConfiguration) { + computationDelay = config.computationDelay + numberImplementation = config.numberImplementation + disabledPlugins.clear() + disabledPlugins.addAll(config.disabledPlugins) + } + + /** + * Saves this configuration to a file. + * @param file the file to save to. + */ + fun saveTo(file: File) { + DEFAULT_TOML_WRITER.write(this, file) + } + +} \ No newline at end of file