mirror of
https://github.com/DanilaFe/abacus
synced 2024-12-22 07:20:09 -08:00
Merge branch 'master' into context
This commit is contained in:
commit
1667edc72b
|
@ -1,4 +1,3 @@
|
|||
dependencies {
|
||||
compile 'com.moandjiezana.toml:toml4j:0.7.1'
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
|
|
@ -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 = "<default>";
|
||||
/**
|
||||
* The list of disabled plugins in this Configuration.
|
||||
*/
|
||||
private Set<String> 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<String> 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 = "<default>", disabledPlugins: Array<String> = emptyArray()) {
|
||||
|
||||
/**
|
||||
* The set of disabled plugins that should be ignored by the plugin manager.
|
||||
*/
|
||||
val disabledPlugins = disabledPlugins.toMutableSet()
|
||||
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
{% include head.html %}
|
||||
<style>
|
||||
body {
|
||||
margin: 0px;
|
||||
margin-top: 50px;
|
||||
color: white;
|
||||
text-align: center;
|
||||
|
@ -37,6 +38,58 @@
|
|||
background-color: #06e8a4;
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.fullwidth {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.fullwidth img {
|
||||
max-width: 100%;
|
||||
max-height: 450px;
|
||||
margin: auto;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
display: block;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
div.white {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
div.green {
|
||||
background-color: #06e8a4;
|
||||
color: white;
|
||||
}
|
||||
|
||||
div.fullwidth div.double {
|
||||
height: 100%;
|
||||
text-align: left;
|
||||
width: 50%;
|
||||
box-sizing: border-box;
|
||||
padding: 40px;
|
||||
float: left;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
@media (max-width: 750px) {
|
||||
div.fullwidth div.double {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
}
|
||||
div.fullwidth img {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
div.fullwidth div.double h1, h2, h3, h4, h5, h6 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
<body>
|
||||
<img src="https://raw.githubusercontent.com/DanilaFe/abacus/master/image/logo.png" id="logo">
|
||||
|
@ -49,5 +102,58 @@
|
|||
<a class="button inverted" href="https://github.com/DanilaFe/abacus/wiki">Wiki</a>
|
||||
</div>
|
||||
<img src="http://i.imgur.com/Min70QY.png" title="source: imgur.com" id="image_preview"/>
|
||||
<h2>Features</h2>
|
||||
<div class="fullwidth white">
|
||||
<div class="double">
|
||||
<img src="https://i.imgur.com/gmGJBBK.png">
|
||||
</div>
|
||||
<div class="double">
|
||||
<h2>Precision</h2>
|
||||
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.
|
||||
</div>
|
||||
</div>
|
||||
<div class="fullwidth green">
|
||||
<div class="double">
|
||||
<h2>Configurable and Customizable</h2>
|
||||
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.<br><br>
|
||||
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.
|
||||
</div>
|
||||
<div class="double">
|
||||
<img src="https://i.imgur.com/JzenWPV.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="fullwidth white">
|
||||
<div class="double">
|
||||
<img src="https://i.imgur.com/jY17I3A.png">
|
||||
</div>
|
||||
<div class="double">
|
||||
<h2>Built-in Documentation</h2>
|
||||
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.<br><br>
|
||||
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.
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
apply plugin: 'application'
|
||||
|
||||
dependencies {
|
||||
compile 'com.moandjiezana.toml:toml4j:0.7.1'
|
||||
compile project(':core')
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 = "<default>",
|
||||
disabledPlugins: Array<String> = 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)
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user