1
0
mirror of https://github.com/DanilaFe/abacus synced 2024-12-23 07:50:09 -08:00

Merge branch 'configuration' into architecture

This commit is contained in:
Danila Fedorin 2017-07-28 21:31:45 -07:00
commit 451931da6c
7 changed files with 179 additions and 9 deletions

View File

@ -14,6 +14,7 @@ repositories {
} }
dependencies { dependencies {
compile 'com.moandjiezana.toml:toml4j:0.7.1'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
} }

View File

@ -0,0 +1,18 @@
package org.nwapw.abacus.config;
/**
* Serializable class that will be used to load TOML
* configurations.
*/
public class Configuration {
/**
* The precision to which the calculator should operator.
*/
public int decimalPrecision;
/**
* The type of number this calculator should use.
*/
public String numberType;
}

View File

@ -0,0 +1,146 @@
package org.nwapw.abacus.config;
import com.moandjiezana.toml.Toml;
import com.moandjiezana.toml.TomlWriter;
import org.nwapw.abacus.number.NaiveNumber;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
/**
* A configuration object, which essentially
* manages saving, loading, and getting values
* from the configuration. While Configuration is
* the data model, this is the interface with it.
*/
public class ConfigurationObject {
/**
* The default implementation to use for instantiating numbers.
*/
private static final Class<? extends NaiveNumber> DEFAULT_IMPLEMENTATION = NaiveNumber.class;
/**
* The writer used to store the configuration.
*/
private static final TomlWriter TOML_WRITER = new TomlWriter();
/**
* The configuration instance being modeled.
*/
private Configuration configuration;
/**
* A map of number names to their implementations, which
* will be provided by plugins.
*/
private Map<String, Class<? extends NaiveNumber>> numberImplementations;
/**
* Sets up the ConfigurationObject.
* different constructors do different things,
* but they all lead here.
* @param configuration the configuration to set up with.
*/
private void setup(Configuration configuration){
this.configuration = configuration;
numberImplementations = new HashMap<>();
}
/**
* Creates a default configuration.
* @return the newly created default configuration.
*/
private Configuration getDefaultConfig(){
configuration = new Configuration();
configuration.decimalPrecision = -1;
configuration.numberType = "naive";
return configuration;
}
/**
* Register a number implementation.
* @param name the name of the number implementation to register the class as.
* @param newClass the class that will be used to instantiate the new number.
* It is required that this class provides a Number(String) constructor.
*/
public void registerImplementation(String name, Class<? extends NaiveNumber> newClass){
numberImplementations.put(name, newClass);
}
/**
* Creates a new number with the configured type, passing
* it the given string.
* @param string the string from which the number should be parsed.
* @return the resulting number, or null if an error occurred.
*/
public NaiveNumber numberFromString(String string) {
Class<? extends NaiveNumber> toLoad =
numberImplementations.getOrDefault(configuration.numberType, DEFAULT_IMPLEMENTATION);
try {
return toLoad.getConstructor(String.class).newInstance(string);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the configured, user-requested precision.
* @return the precision.
*/
public int getPrecision(){
return configuration.decimalPrecision;
}
/**
* Saves the ConfigurationObject to the given file.
* @param toFile the file to save ot.
* @return true if the save succeed, false if otherwise.
*/
public boolean save(File toFile){
if(toFile.getParentFile() != null) toFile.getParentFile().mkdirs();
try {
TOML_WRITER.write(configuration, toFile);
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* Creates a new configuration object with the given config.
* @param config the config to use.
*/
public ConfigurationObject(Configuration config){
setup(config);
}
/**
* Create a configuration object by attempting to
* load a config from the given path, using the
* default configuration otherwise.
* @param path the path to attempt to load.
*/
public ConfigurationObject(File path){
Configuration config;
if(!path.exists()) {
config = getDefaultConfig();
} else {
Toml parse = new Toml();
parse.read(path);
config = parse.to(Configuration.class);
}
setup(config);
}
/**
* Creates a new configuration object with the
* default configuration.
*/
public ConfigurationObject(){
setup(getDefaultConfig());
}
}

View File

@ -10,6 +10,13 @@ public class NaiveNumber implements NumberInterface {
*/ */
private double value; private double value;
/**
* Creates a new NaiveNumber with the given string.
* @param value the value, which will be parsed as a double.
*/
public NaiveNumber(String value) {
this(Double.parseDouble(value));
}
/** /**
* Creates a new NaiveNumber with the given value. * Creates a new NaiveNumber with the given value.
* @param value the value to use. * @param value the value to use.
@ -28,7 +35,7 @@ public class NaiveNumber implements NumberInterface {
public static final NaiveNumber ONE = new NaiveNumber(1); public static final NaiveNumber ONE = new NaiveNumber(1);
@Override @Override
public int precision() { public int getMaxPrecision() {
return 18; return 18;
} }

View File

@ -6,10 +6,10 @@ package org.nwapw.abacus.number;
public interface NumberInterface { public interface NumberInterface {
/** /**
* The precision to which this number operates. * The maximum precision to which this number operates.
* @return the precision. * @return the precision.
*/ */
int precision(); int getMaxPrecision();
/** /**
* Multiplies this number by another, returning * Multiplies this number by another, returning

View File

@ -1,8 +1,6 @@
package org.nwapw.abacus.number; package org.nwapw.abacus.number;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode; import java.math.RoundingMode;
public class PreciseNumber implements NumberInterface{ public class PreciseNumber implements NumberInterface{
@ -43,7 +41,7 @@ public class PreciseNumber implements NumberInterface{
} }
@Override @Override
public int precision() { public int getMaxPrecision() {
return 54; return 54;
} }
@ -54,7 +52,7 @@ public class PreciseNumber implements NumberInterface{
@Override @Override
public NumberInterface divide(NumberInterface divisor) { public NumberInterface divide(NumberInterface divisor) {
return new PreciseNumber(value.divide(((PreciseNumber) divisor).value, this.precision(), RoundingMode.HALF_UP)); return new PreciseNumber(value.divide(((PreciseNumber) divisor).value, this.getMaxPrecision(), RoundingMode.HALF_UP));
} }
@Override @Override
@ -109,7 +107,7 @@ public class PreciseNumber implements NumberInterface{
@Override @Override
public String toString() { public String toString() {
BigDecimal rounded = value.setScale(precision() - 4, RoundingMode.HALF_UP); BigDecimal rounded = value.setScale(getMaxPrecision() - 4, RoundingMode.HALF_UP);
return rounded.stripTrailingZeros().toPlainString(); return rounded.stripTrailingZeros().toPlainString();
} }
} }

View File

@ -292,7 +292,7 @@ public class StandardPlugin extends Plugin {
* @return the maximum error. * @return the maximum error.
*/ */
private NumberInterface getMaxError(NumberInterface number){ private NumberInterface getMaxError(NumberInterface number){
return (new NaiveNumber(10)).promoteTo(number.getClass()).intPow(-number.precision()); return (new NaiveNumber(10)).promoteTo(number.getClass()).intPow(-number.getMaxPrecision());
} }
} }