@@ -9,24 +9,21 @@ import android.app.Application;
import android.content.Context ;
import android.content.SharedPreferences ;
import android.preference.PreferenceManager ;
import jscl.* ;
import jscl.math.Generic ;
import jscl.AngleUnit ;
import jscl.JsclMathEngine ;
import jscl.MathEngine ;
import jscl.NumeralBase ;
import jscl.math.function.Function ;
import jscl.math.function.IConstant ;
import jscl.math.operator.Operator ;
import jscl.text.ParseInterruptedException ;
import org.jetbrains.annotations.NotNull ;
import org.jetbrains.annotations.Nullabl e ;
import org.solovyev.android.calculator.* ;
import org.solovyev.android.calculator.jscl.JsclOperation ;
import org.solovyev.android.calculator.text.TextProcessor ;
import org.solovyev.android.msg.AndroidMessage ;
import org.solovyev.android.calculator.CalculatorEngin e ;
import org.solovyev.android.calculator.CalculatorEngineImpl ;
import org.solovyev.android.calculator.CalculatorMathEngine ;
import org.solovyev.android.calculator.CalculatorMathRegistry ;
import org.solovyev.android.prefs.BooleanPreference ;
import org.solovyev.android.prefs.Preference ;
import org.solovyev.android.prefs.StringPreference ;
import org.solovyev.common.MutableObject ;
import org.solovyev.common.msg.MessageRegistry ;
import org.solovyev.common.msg.MessageType ;
import org.solovyev.common.text.EnumMapper ;
import org.solovyev.common.text.NumberMapper ;
import org.solovyev.common.text.StringUtils ;
@@ -35,8 +32,6 @@ import java.text.DecimalFormatSymbols;
import java.util.ArrayList ;
import java.util.Collections ;
import java.util.List ;
import java.util.concurrent.CountDownLatch ;
import java.util.concurrent.TimeUnit ;
/**
* User: serso
@@ -46,270 +41,199 @@ import java.util.concurrent.TimeUnit;
public class AndroidCalculatorEngine implements CalculatorEngine {
private static final String GROUPING_SEPARATOR_P_KEY = " org.solovyev.android.calculator.CalculatorActivity_calc_grouping_separator " ;
private static final String GROUPING_SEPARATOR_P_KEY = " org.solovyev.android.calculator.CalculatorActivity_calc_grouping_separator " ;
private static final String MULTIPLICATION_SIGN_P_KEY = " org.solovyev.android.calculator.CalculatorActivity_calc_multiplication_sign " ;
private static final String MULTIPLICATION_SIGN_DEFAULT = " × " ;
private static final String MULTIPLICATION_SIGN_P_KEY = " org.solovyev.android.calculator.CalculatorActivity_calc_multiplication_sign " ;
private static final String MULTIPLICATION_SIGN_DEFAULT = " × " ;
private static final String MAX_CALCULATION_TIME_P_KEY = " calculation.max_calculation_time " ;
private static final String MAX_CALCULATION_TIME_DEFAULT = " 5 " ;
private static final String MAX_CALCULATION_TIME_P_KEY = " calculation.max_calculation_time " ;
private static final String MAX_CALCULATION_TIME_DEFAULT = " 5 " ;
private static final String SCIENCE_NOTATION_P_KEY = " calculation.output.science_notation " ;
private static final boolean SCIENCE_NOTATION_DEFAULT = false ;
private static final String SCIENCE_NOTATION_P_KEY = " calculation.output.science_notation " ;
private static final boolean SCIENCE_NOTATION_DEFAULT = false ;
private static final String ROUND_RESULT_P_KEY = " org.solovyev.android.calculator.CalculatorModel_round_result " ;
private static final boolean ROUND_RESULT_DEFAULT = true ;
private static final String ROUND_RESULT_P_KEY = " org.solovyev.android.calculator.CalculatorModel_round_result " ;
private static final boolean ROUND_RESULT_DEFAULT = true ;
private static final String RESULT_PRECISION_P_KEY = " org.solovyev.android.calculator.CalculatorModel_result_precision " ;
private static final String RESULT_PRECISION_DEFAULT = " 5 " ;
private static final String RESULT_PRECISION_P_KEY = " org.solovyev.android.calculator.CalculatorModel_result_precision " ;
private static final String RESULT_PRECISION_DEFAULT = " 5 " ;
private static final String NUMERAL_BASES_P_KEY = " org.solovyev.android.calculator.CalculatorActivity_numeral_bases " ;
private static final String NUMERAL_BASES_DEFAULT = " dec " ;
private static final String NUMERAL_BASES_P_KEY = " org.solovyev.android.calculator.CalculatorActivity_numeral_bases " ;
private static final String NUMERAL_BASES_DEFAULT = " dec " ;
private static final String ANGLE_UNITS_P_KEY = " org.solovyev.android.calculator.CalculatorActivity_angle_units " ;
private static final String ANGLE_UNITS_DEFAULT = " deg " ;
private static final String ANGLE_UNITS_P_KEY = " org.solovyev.android.calculator.CalculatorActivity_angle_units " ;
private static final String ANGLE_UNITS_DEFAULT = " deg " ;
public static class Preferences {
public static final Preference < String > groupingSeparator = StringPreference . newInstance ( GROUPING_SEPARATOR_P_KEY , JsclMathEngine . GROUPING_SEPARATOR_DEFAULT ) ;
public static final Preference < String > multiplicationSign = StringPreference . newInstance ( MULTIPLICATION_SIGN_P_KEY , MULTIPLICATION_SIGN_DEFAULT ) ;
public static final Preference < Integer > precision = StringPreference . newInstance ( RESULT_PRECISION_P_KEY , RESULT_PRECISION_DEFAULT , new NumberMapper < Integer > ( Integer . class ) ) ;
public static final Preference < Boolean > roundResult = new BooleanPreference ( ROUND_RESULT_P_KEY , ROUND_RESULT_DEFAULT ) ;
public static final Preference < NumeralBase > numeralBase = StringPreference . newInstance ( NUMERAL_BASES_P_KEY , NUMERAL_BASES_DEFAULT , EnumMapper . newInstance ( NumeralBase . class ) ) ;
public static final Preference < AngleUnit > angleUnit = StringPreference . newInstance ( ANGLE_UNITS_P_KEY , ANGLE_UNITS_DEFAULT , EnumMapper . newInstance ( AngleUnit . class ) ) ;
public static final Preference < Boolean > scienceNotation = new BooleanPreference ( SCIENCE_NOTATION_P_KEY , SCIENCE_NOTATION_DEFAULT ) ;
public static final Preference < Integer > maxCalculationTime = StringPreference . newInstance ( MAX_CALCULATION_TIME_P_KEY , MAX_CALCULATION_TIME_DEFAULT , new NumberMapper < Integer > ( Integer . class ) ) ;
public static class Preferences {
public static final Preference < String > groupingSeparator = StringPreference . newInstance ( GROUPING_SEPARATOR_P_KEY , JsclMathEngine . GROUPING_SEPARATOR_DEFAULT ) ;
public static final Preference < String > multiplicationSign = StringPreference . newInstance ( MULTIPLICATION_SIGN_P_KEY , MULTIPLICATION_SIGN_DEFAULT ) ;
public static final Preference < Integer > precision = StringPreference . newInstance ( RESULT_PRECISION_P_KEY , RESULT_PRECISION_DEFAULT , new NumberMapper < Integer > ( Integer . class ) ) ;
public static final Preference < Boolean > roundResult = new BooleanPreference ( ROUND_RESULT_P_KEY , ROUND_RESULT_DEFAULT ) ;
public static final Preference < NumeralBase > numeralBase = StringPreference . newInstance ( NUMERAL_BASES_P_KEY , NUMERAL_BASES_DEFAULT , EnumMapper . newInstance ( NumeralBase . class ) ) ;
public static final Preference < AngleUnit > angleUnit = StringPreference . newInstance ( ANGLE_UNITS_P_KEY , ANGLE_UNITS_DEFAULT , EnumMapper . newInstance ( AngleUnit . class ) ) ;
public static final Preference < Boolean > scienceNotation = new BooleanPreference ( SCIENCE_NOTATION_P_KEY , SCIENCE_NOTATION_DEFAULT ) ;
public static final Preference < Integer > maxCalculationTime = StringPreference . newInstance ( MAX_CALCULATION_TIME_P_KEY , MAX_CALCULATION_TIME_DEFAULT , new NumberMapper < Integer > ( Integer . class ) ) ;
private static final List < String > preferenceKeys = new ArrayList < String > ( ) ;
private static final List < String > preferenceKeys = new ArrayList < String > ( ) ;
static {
preferenceKeys . add ( groupingSeparator . getKey ( ) ) ;
preferenceKeys . add ( multiplicationSign . getKey ( ) ) ;
preferenceKeys . add ( precision . getKey ( ) ) ;
preferenceKeys . add ( roundResult . getKey ( ) ) ;
preferenceKeys . add ( numeralBase . getKey ( ) ) ;
preferenceKeys . add ( angleUnit . getKey ( ) ) ;
preferenceKeys . add ( scienceNotation . getKey ( ) ) ;
preferenceKeys . add ( maxCalculationTime . getKey ( ) ) ;
}
static {
preferenceKeys . add ( groupingSeparator . getKey ( ) ) ;
preferenceKeys . add ( multiplicationSign . getKey ( ) ) ;
preferenceKeys . add ( precision . getKey ( ) ) ;
preferenceKeys . add ( roundResult . getKey ( ) ) ;
preferenceKeys . add ( numeralBase . getKey ( ) ) ;
preferenceKeys . add ( angleUnit . getKey ( ) ) ;
preferenceKeys . add ( scienceNotation . getKey ( ) ) ;
preferenceKeys . add ( maxCalculationTime . getKey ( ) ) ;
}
@NotNull
public static List < String > getPreferenceKeys ( ) {
return Collections . unmodifiableList ( preferenceKeys ) ;
}
}
@NotNull
private final Object lock = new Object ( ) ;
@NotNull
private MathEngine engine = JsclMathEngine . instance ;
@NotNull
public final TextProcessor < PreparedExpression , String > preprocessor = ToJsclTextProcessor . getInstance ( ) ;
@NotNull
private final CalculatorMathRegistry < IConstant > varsRegistry ;
@NotNull
private final CalculatorMathRegistry < Function > functionsRegistry ;
@NotNull
private final CalculatorMathRegistry < Operator > operatorsRegistry ;
private final CalculatorMathRegistry < Operator > postfixFunctionsRegistry ;
@Nullable
private ThreadKiller threadKiller = new AndroidThreadKiller ( ) ;
// calculation thread timeout in seconds, after timeout thread would be interrupted
private int timeout = Integer . valueOf ( MAX_CALCULATION_TIME_DEFAULT ) ;
@NotNull
private String multiplicationSign = MULTIPLICATION_SIGN_DEFAULT ;
@NotNull
public static List < String > getPreferenceKeys ( ) {
return Collections . unmodifiableList ( preferenceKeys ) ;
}
}
@NotNull
private final Context context ;
public AndroidCalculatorEngine ( @NotNull Application application ) {
@NotNull
private final CalculatorEngine calculatorEngine ;
@NotNull
private final Object lock ;
public AndroidCalculatorEngine ( @NotNull Application application ) {
this . context = application ;
this . lock = new Object ( ) ;
this . engine . setRoundResult ( true ) ;
this . engine . setUseGroupingSeparator ( true ) ;
this . varsRegistry = new AndroidVars RegistryImpl ( engine . getConstant sRegistry ( ) , application ) ;
this . functionsRegistry = new AndroidFunction sMathRegistry ( engine . getFunction sRegistry ( ) , application ) ;
this . operatorsRegistry = new AndroidOperatorsMath Registry ( engine . getOperator sRegistry ( ) , application ) ;
this . postfixFunctionsRegistry = new AndroidPostfixFunctionsRegistry ( engine . getPostfixFunctionsRegistry ( ) , application ) ;
final JsclMathEngine engine = JsclMathEngine . instance ;
this . calculatorEngine = new CalculatorEngineImpl ( engine ,
new AndroidVarsRegistryImpl ( engine . getConstantsRegistry ( ) , application ) ,
new AndroidFunctionsMath Registry ( engine . getFunction sRegistry ( ) , application ) ,
new AndroidOperator sMathRegistry ( engine . getOperator sRegistry ( ) , application ) ,
new AndroidPostfixFunctions Registry ( engine . getPostfixFunction sRegistry ( ) , application ) ,
this . lock ) ;
}
@Override
@Override
@NotNull
public String getMultiplicationSign ( ) {
return multiplicationSign ;
}
public CalculatorMathRegistry < IConstant > getVarsRegistry ( ) {
return calculatorEngine . getVarsRegistry ( ) ;
}
public void setMultiplicationSign ( @NotNull String multiplicationSign ) {
this . multiplicationSign = multiplicationSign ;
}
@Override
@NotNull
public CalculatorMathRegistry < Function > getFunctionsRegistry ( ) {
return calculatorEngine . getFunctionsRegistry ( ) ;
}
public CalculatorOutput evaluate ( @NotNull JsclOperation operation ,
@NotNull String expression ) throws CalculatorParseException , CalculatorEvalException {
return evaluate ( o peration , expression , null ) ;
}
@Override
@NotNull
public CalculatorMathRegistry < O perator > getOperatorsRegistry ( ) {
return calculatorEngine . getOperatorsRegistry ( ) ;
}
public CalculatorOutput evaluate ( @NotNull final JsclOperation operation ,
@NotNull String expression ,
@Nullable MessageRegistry mr ) throws CalculatorParseException , CalculatorEvalException {
synchronized ( lock ) {
final StringBuilder sb = new StringBuilder ( ) ;
@Override
@NotNull
public CalculatorMathRegistry < Operator > getPostfixFunctionsRegistry ( ) {
return calculatorEngine . getPostfixFunctionsRegistry ( ) ;
}
final PreparedExpression preparedExpression = preprocessor . process ( expression ) ;
sb . append ( preparedExpression ) ;
@Override
@NotNull
public CalculatorMathEngine getMathEngine ( ) {
return calculatorEngine . getMathEngine ( ) ;
}
//Log.d(CalculatorEngine.class.getName(), "Preprocessed expression: " + preparedExpression);
/*if (operation == JsclOperation.numeric && preparedExpression.isExistsUndefinedVar()) {
operation = JsclOperation.simplify;
@NotNull
@Override
public MathEngine getMathEngine0 ( ) {
return calculatorEngine . getMathEngine0 ( ) ;
}
if (mr != null) {
final String undefinedVars = CollectionsUtils.formatValue(preparedExpression.getUndefinedVars(), ", ", new Formatter<Var>() {
@Override
public String formatValue(@Nullable Var var) throws IllegalArgumentException {
return var != null ? var.getName() : "";
}
});
@NotNull
@Override
public NumeralBase getNumeralBase ( ) {
return calculatorEngine . getNumeralBase ( ) ;
}
mr.addMessage(new AndroidMessage(R.string.c_simplify_instead_of_numeric, MessageType.info, undefinedVars));
}
}*/
final String jsclExpression = sb . toString ( ) ;
final MutableObject < Generic > calculationResult = new MutableObject < Generic > ( null ) ;
final MutableObject < CalculatorParseException > parseException = new MutableObject < CalculatorParseException > ( null ) ;
final MutableObject < CalculatorEvalException > evalException = new MutableObject < CalculatorEvalException > ( null ) ;
final MutableObject < Thread > calculationThread = new MutableObject < Thread > ( null ) ;
final CountDownLatch latch = new CountDownLatch ( 1 ) ;
new Thread ( new Runnable ( ) {
@Override
public void run ( ) {
final Thread thread = Thread . currentThread ( ) ;
try {
//Log.d(CalculatorEngine.class.getName(), "Calculation thread started work: " + thread.getName());
//System.out.println(jsclExpression);
calculationThread . setObject ( thread ) ;
final Generic genericResult = operation . evaluateGeneric ( jsclExpression ) ;
// NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!)
genericResult . toString ( ) ;
calculationResult . setObject ( genericResult ) ;
} catch ( AbstractJsclArithmeticException e ) {
evalException . setObject ( new CalculatorEvalException ( e , e , jsclExpression ) ) ;
} catch ( ArithmeticException e ) {
//System.out.println(e.getMessage());
final AndroidMessage androidMessage = new AndroidMessage ( R . string . msg_1 , MessageType . error , CalculatorApplication . getInstance ( ) , e . getMessage ( ) ) ;
parseException . setObject ( new CalculatorParseException ( jsclExpression , androidMessage ) ) ;
} catch ( StackOverflowError e ) {
//System.out.println(StringUtils.fromStackTrace(e.getStackTrace()));
final AndroidMessage androidMessage = new AndroidMessage ( R . string . msg_2 , MessageType . error , CalculatorApplication . getInstance ( ) ) ;
parseException . setObject ( new CalculatorParseException ( jsclExpression , androidMessage ) ) ;
} catch ( jscl . text . ParseException e ) {
//System.out.println(e.getMessage());
parseException . setObject ( new CalculatorParseException ( e ) ) ;
} catch ( ParseInterruptedException e ) {
//System.out.println(e.getMessage());
// do nothing - we ourselves interrupt the calculations
} finally {
//Log.d(CalculatorEngine.class.getName(), "Calculation thread ended work: " + thread.getName());
calculationThread . setObject ( null ) ;
latch . countDown ( ) ;
}
}
} ) . start ( ) ;
try {
//Log.d(CalculatorEngine.class.getName(), "Main thread is waiting: " + Thread.currentThread().getName());
latch . await ( timeout , TimeUnit . SECONDS ) ;
//Log.d(CalculatorEngine.class.getName(), "Main thread got up: " + Thread.currentThread().getName());
final CalculatorParseException parseExceptionObject = parseException . getObject ( ) ;
final CalculatorEvalException evalExceptionObject = evalException . getObject ( ) ;
final Object calculationResultLocal = calculationResult . getObject ( ) ;
final Thread calculationThreadLocal = calculationThread . getObject ( ) ;
if ( calculationThreadLocal ! = null ) {
if ( threadKiller ! = null ) {
threadKiller . killThread ( calculationThreadLocal ) ;
}
//calculationThreadLocal.stop();
}
if ( parseExceptionObject ! = null | | evalExceptionObject ! = null ) {
if ( operation = = JsclOperation . numeric & &
( preparedExpression . isExistsUndefinedVar ( ) | | ( evalExceptionObject ! = null & & evalExceptionObject . getCause ( ) instanceof NumeralBaseException ) ) ) {
return evaluate ( JsclOperation . simplify , expression , mr ) ;
}
if ( parseExceptionObject ! = null ) {
throw parseExceptionObject ;
} else {
throw evalExceptionObject ;
}
}
if ( calculationResultLocal = = null ) {
final AndroidMessage androidMessage = new AndroidMessage ( R . string . msg_3 , MessageType . error , CalculatorApplication . getInstance ( ) ) ;
throw new CalculatorParseException ( jsclExpression , androidMessage ) ;
}
} catch ( InterruptedException e ) {
final AndroidMessage androidMessage = new AndroidMessage ( R . string . msg_4 , MessageType . error , CalculatorApplication . getInstance ( ) ) ;
throw new CalculatorParseException ( jsclExpression , androidMessage ) ;
}
final Generic genericResult = calculationResult . getObject ( ) ;
return new CalculatorOutputImpl ( operation . getFromProcessor ( ) . process ( genericResult ) , operation , genericResult ) ;
}
}
public void setPrecision ( int precision ) {
this . getEngine ( ) . setPrecision ( precision ) ;
}
public void setRoundResult ( boolean roundResult ) {
this . getEngine ( ) . setRoundResult ( roundResult ) ;
}
@Override
@Override
public void init ( ) {
synchronized ( lock ) {
rese t( ) ;
}
}
synchronized ( lock ) {
calculatorEngine . ini t( ) ;
}
}
@Override
@Override
public void reset ( ) {
synchronized ( lock ) {
synchronized ( lock ) {
final SharedPreferences preferences = PreferenceManager . getDefaultSharedPreferences ( context ) ;
softReset ( preferences ) ;
softReset ( preferences ) ;
varsRegistry . load ( ) ;
functionsRegistry . load ( ) ;
operatorsRegistry . load ( ) ;
postfixFunctionsRegistry . load ( ) ;
}
}
calculatorEngine . reset ( ) ;
}
}
@Override
@Override
public void softReset ( ) {
synchronized ( lock ) {
synchronized ( lock ) {
softReset ( PreferenceManager . getDefaultSharedPreferences ( context ) ) ;
}
}
calculatorEngine . softReset ( ) ;
}
}
@Override
public void setUseGroupingSeparator ( boolean useGroupingSeparator ) {
calculatorEngine . setUseGroupingSeparator ( useGroupingSeparator ) ;
}
@Override
public void setGroupingSeparator ( char groupingSeparator ) {
calculatorEngine . setGroupingSeparator ( groupingSeparator ) ;
}
@Override
public void setPrecision ( @NotNull Integer precision ) {
calculatorEngine . setPrecision ( precision ) ;
}
@Override
public void setRoundResult ( @NotNull Boolean round ) {
calculatorEngine . setRoundResult ( round ) ;
}
@NotNull
@Override
public AngleUnit getAngleUnits ( ) {
return calculatorEngine . getAngleUnits ( ) ;
}
@Override
public void setAngleUnits ( @NotNull AngleUnit angleUnits ) {
calculatorEngine . setAngleUnits ( angleUnits ) ;
}
@Override
public void setNumeralBase ( @NotNull NumeralBase numeralBase ) {
calculatorEngine . setNumeralBase ( numeralBase ) ;
}
@Override
public void setMultiplicationSign ( @NotNull String multiplicationSign ) {
calculatorEngine . setMultiplicationSign ( multiplicationSign ) ;
}
@Override
public void setScienceNotation ( @NotNull Boolean scienceNotation ) {
calculatorEngine . setScienceNotation ( scienceNotation ) ;
}
@Override
public void setTimeout ( @NotNull Integer timeout ) {
calculatorEngine . setTimeout ( timeout ) ;
}
private void softReset ( @NotNull SharedPreferences preferences ) {
this . setPrecision ( Preferences . precision . getPreference ( preferences ) ) ;
@@ -322,100 +246,32 @@ public class AndroidCalculatorEngine implements CalculatorEngine {
final String groupingSeparator = Preferences . groupingSeparator . getPreference ( preferences ) ;
if ( StringUtils . isEmpty ( groupingSeparator ) ) {
this . getEngine ( ) . setUseGroupingSeparator( false ) ;
this . setUseGroupingSeparator ( false ) ;
} else {
this . getEngine ( ) . setUseGroupingSeparator( true ) ;
this . getEngine ( ) . setGroupingSeparator( groupingSeparator . charAt ( 0 ) ) ;
this . setUseGroupingSeparator ( true ) ;
setGroupingSeparator( groupingSeparator . charAt ( 0 ) ) ;
}
}
@NotNull
public NumeralBase getNumeralBaseFromPrefs ( @NotNull SharedPreferences preferences ) {
return Preferences . numeralBase . getPreference ( preferences ) ;
}
@NotNull
public NumeralBase getNumeralBase FromPrefs( @NotNull SharedPreferences preferences ) {
return Preferences . numeralBase . getPreference ( preferences ) ;
}
public AngleUnit getAngleUnits FromPrefs( @NotNull SharedPreferences preferences ) {
return Preferences . angleUnit . getPreference ( preferences ) ;
}
@NotNull
public AngleUnit g etAngleUnitsFromPref s( @NotNull SharedPreferences preference s) {
return Preferences . angleUnit . g etPreference ( preference s) ;
}
//for tests only
public void s etDecimalGroupSymbol s( @NotNull DecimalFormatSymbols decimalGroupSymbol s) {
this . calculatorEngine . s etDecimalGroupSymbols ( decimalGroupSymbol s) ;
}
//for tests only
void setDecimalGroupSymbols ( @NotNull DecimalFormatSymbols decimalGroupSymbols ) {
synchronized ( lock ) {
this . getEngine ( ) . setDecimalGroupSymbols ( decimalGroupSymbols ) ;
}
}
@Override
@Override
@NotNull
public CalculatorMathRegistry < IConstant > getVarsRegistry ( ) {
return varsRegistry ;
}
public String getMultiplicationSign ( ) {
return calculatorEngine . getMultiplicationSign ( ) ;
}
@Override
@NotNull
public CalculatorMathRegistry < Function > getFunctionsRegistry ( ) {
return functionsRegistry ;
}
@Override
@NotNull
public CalculatorMathRegistry < Operator > getOperatorsRegistry ( ) {
return operatorsRegistry ;
}
@Override
@NotNull
public CalculatorMathRegistry < Operator > getPostfixFunctionsRegistry ( ) {
return postfixFunctionsRegistry ;
}
@Override
@NotNull
public MathEngine getEngine ( ) {
return engine ;
}
// package protected for tests
void setTimeout ( int timeout ) {
this . timeout = timeout ;
}
public void setAngleUnits ( @NotNull AngleUnit angleUnits ) {
getEngine ( ) . setAngleUnits ( angleUnits ) ;
}
public void setScienceNotation ( boolean scienceNotation ) {
getEngine ( ) . setScienceNotation ( scienceNotation ) ;
}
public void setNumeralBase ( @NotNull NumeralBase numeralBase ) {
getEngine ( ) . setNumeralBase ( numeralBase ) ;
}
// for tests only
void setThreadKiller ( @Nullable ThreadKiller threadKiller ) {
this . threadKiller = threadKiller ;
}
private static interface ThreadKiller {
void killThread ( @NotNull Thread thread ) ;
}
private static class AndroidThreadKiller implements ThreadKiller {
@Override
public void killThread ( @NotNull Thread thread ) {
thread . setPriority ( Thread . MIN_PRIORITY ) ;
thread . interrupt ( ) ;
}
}
public static class ThreadKillerImpl implements ThreadKiller {
@Override
public void killThread ( @NotNull Thread thread ) {
thread . setPriority ( Thread . MIN_PRIORITY ) ;
thread . stop ( ) ;
}
}
}