changes
This commit is contained in:
parent
94282706fe
commit
c1a1e23e3c
@ -8,8 +8,10 @@
|
|||||||
|
|
||||||
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||||
a:id="@+id/divisionButton" a:text="/"
|
a:id="@+id/divisionButton"
|
||||||
calc:textUp="√"
|
calc:textUp="%"
|
||||||
|
a:text="/"
|
||||||
|
calc:textDown="√"
|
||||||
calc:directionTextScale="0.5"
|
calc:directionTextScale="0.5"
|
||||||
style="?digitButtonStyle"
|
style="?digitButtonStyle"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
@ -7,6 +7,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||||
a:id="@+id/functionsButton"
|
a:id="@+id/functionsButton"
|
||||||
a:text="ƒ(x)"
|
a:text="ƒ(x)"
|
||||||
a:textStyle="italic"
|
a:textStyle="italic"
|
||||||
|
@ -8,6 +8,6 @@
|
|||||||
|
|
||||||
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
a:id="@+id/functionsButton"
|
a:id="@+id/functionsButton"
|
||||||
a:text="∂,∫"
|
a:text="∂,…"
|
||||||
a:onClick="operatorsButtonClickHandler"
|
a:onClick="operatorsButtonClickHandler"
|
||||||
style="?controlButtonStyle"/>
|
style="?controlButtonStyle"/>
|
@ -8,7 +8,7 @@
|
|||||||
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
<org.solovyev.android.view.widgets.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
xmlns:calc="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
|
||||||
a:id="@+id/subtractionButton"
|
a:id="@+id/subtractionButton"
|
||||||
calc:textUp="%"
|
calc:textDown="∂,…"
|
||||||
a:text="-"
|
a:text="-"
|
||||||
calc:directionTextScale="0.5"
|
calc:directionTextScale="0.5"
|
||||||
style="?digitButtonStyle"
|
style="?digitButtonStyle"
|
||||||
|
@ -147,4 +147,11 @@
|
|||||||
<string name="c_not_valid_result">Результат не допустим!</string>
|
<string name="c_not_valid_result">Результат не допустим!</string>
|
||||||
<string name="c_operators">Операторы</string>
|
<string name="c_operators">Операторы</string>
|
||||||
|
|
||||||
|
<string name="c_op_description_mod">Возвращает остаток от деления \'x\' на \'y\'.</string>
|
||||||
|
<string name="c_op_description_sum">Суммирует функции \'f(i)\', пробегая по переменной \'i\' от \'from\' до \'to\'.</string>
|
||||||
|
<string name="c_op_description_product">Возвращает произведение функций \'f(i)\', пробегая по переменной \'i\' от \'from\' до \'to\'.</string>
|
||||||
|
<string name="c_op_description_derivative">Возвращает производную порядка \'order\' функции \'f(x)\' по переменной \'x\' и вычисляет её в точке \'x_point\'.</string>
|
||||||
|
<string name="c_op_description_integral">Возвращает интеграл функции \'f(x)\' по переменно \'x\'.</string>
|
||||||
|
<string name="c_op_description_integral_ab">Интегрирует функцию \'f(x)\' по переменной \'x\' от \'a\' до \'b\'.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -140,12 +140,20 @@
|
|||||||
<string name="c_fun_description_ne">Not-equals function - gives 1 if two arguments are not equals, 0 otherwise.</string>
|
<string name="c_fun_description_ne">Not-equals function - gives 1 if two arguments are not equals, 0 otherwise.</string>
|
||||||
<string name="c_fun_description_lt">Lesser function - gives 1 if first argument is less than second, 0 otherwise.</string>
|
<string name="c_fun_description_lt">Lesser function - gives 1 if first argument is less than second, 0 otherwise.</string>
|
||||||
<string name="c_fun_description_gt">Greater function - gives 1 if first argument is greater than second, 0 otherwise.</string>
|
<string name="c_fun_description_gt">Greater function - gives 1 if first argument is greater than second, 0 otherwise.</string>
|
||||||
<string name="c_fun_description_rad">Converts degrees into radians: d - degrees, m - minutes (default = 0), s - seconds (default = 0) </string>
|
<string name="c_fun_description_rad">Converts degrees into radians: d - degrees, m - minutes (default = 0), s - seconds (default = 0).</string>
|
||||||
<string name="c_fun_description_dms">Converts degrees from DMS notation to decimal notation: d - degrees, m - minutes (default = 0), s - seconds (default = 0) </string>
|
<string name="c_fun_description_dms">Converts degrees from DMS notation to decimal notation: d - degrees, m - minutes (default = 0), s - seconds (default = 0).</string>
|
||||||
<string name="c_fun_description_deg">Converts radians into degrees.</string>
|
<string name="c_fun_description_deg">Converts radians into degrees.</string>
|
||||||
|
|
||||||
<string name="c_empty_var_error">Unable to create empty constant!</string>
|
<string name="c_empty_var_error">Unable to create empty constant!</string>
|
||||||
<string name="c_not_valid_result">Current result is not valid!</string>
|
<string name="c_not_valid_result">Current result is not valid!</string>
|
||||||
<string name="c_operators">Operators</string>
|
<string name="c_operators">Operators</string>
|
||||||
|
|
||||||
|
<string name="c_op_description_mod">Modulo operation finds the remainder of division of \'x\' by \'y\'.</string>
|
||||||
|
<string name="c_op_description_sum">Sums functions \'f(i)\', iterating through \'i\' from \'from\' to \'to\'.</string>
|
||||||
|
<string name="c_op_description_product">Gives product of functions \'f(i)\', iterating through \'i\' from \'from\' to \'to\'.</string>
|
||||||
|
<string name="c_op_description_derivative">Gives derivative of order \'order\' of functions \'f(x)\' by \'x\' variable and calculates at point \'x_point\'.</string>
|
||||||
|
<string name="c_op_description_integral">Gives integral of function \'f(x)\' by \'x\' variable.</string>
|
||||||
|
<string name="c_op_description_integral_ab">Integrates function \'f(x)\' by \'x\' variable from \'a\' to \'b\'.</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -96,6 +96,18 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
|
|||||||
final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor<CalculatorHistoryState>(this.calculatorModel), dragPreferences), vibrator, preferences);
|
final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor<CalculatorHistoryState>(this.calculatorModel), dragPreferences), vibrator, preferences);
|
||||||
((DragButton) findViewById(R.id.historyButton)).setOnDragListener(historyOnDragListener);
|
((DragButton) findViewById(R.id.historyButton)).setOnDragListener(historyOnDragListener);
|
||||||
|
|
||||||
|
((DragButton) findViewById(R.id.subtractionButton)).setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new SimpleOnDragListener.DragProcessor() {
|
||||||
|
@Override
|
||||||
|
public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
|
||||||
|
if (dragDirection == DragDirection.down) {
|
||||||
|
operatorsButtonClickHandler(dragButton);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, dragPreferences), vibrator, preferences));
|
||||||
|
|
||||||
|
|
||||||
final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(calculatorModel), dragPreferences), vibrator, preferences);
|
final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(calculatorModel), dragPreferences), vibrator, preferences);
|
||||||
((DragButton) findViewById(R.id.rightButton)).setOnDragListener(toPositionOnDragListener);
|
((DragButton) findViewById(R.id.rightButton)).setOnDragListener(toPositionOnDragListener);
|
||||||
((DragButton) findViewById(R.id.leftButton)).setOnDragListener(toPositionOnDragListener);
|
((DragButton) findViewById(R.id.leftButton)).setOnDragListener(toPositionOnDragListener);
|
||||||
|
@ -269,6 +269,9 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
|||||||
textToBeInserted.append("()");
|
textToBeInserted.append("()");
|
||||||
cursorPositionOffset = -1;
|
cursorPositionOffset = -1;
|
||||||
break;
|
break;
|
||||||
|
case comma:
|
||||||
|
textToBeInserted.append(" ");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursorPositionOffset == 0) {
|
if (cursorPositionOffset == 0) {
|
||||||
|
@ -118,6 +118,8 @@ public enum MathType {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
comma(1150, false, false, ","),
|
||||||
|
|
||||||
text(1200, false, false) {
|
text(1200, false, false) {
|
||||||
@Override
|
@Override
|
||||||
public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) {
|
public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) {
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
|
* or visit http://se.solovyev.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.solovyev.android.calculator.model;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.solovyev.common.math.MathEntity;
|
||||||
|
import org.solovyev.common.math.MathRegistry;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: serso
|
||||||
|
* Date: 11/17/11
|
||||||
|
* Time: 11:28 PM
|
||||||
|
*/
|
||||||
|
public class AndroidFunctionsMathRegistry<T extends MathEntity> extends AndroidMathRegistryImpl<T> {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static final Map<String, String> substitutes = new HashMap<String, String>();
|
||||||
|
static {
|
||||||
|
substitutes.put("√", "sqrt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static final String FUNCTION_DESCRIPTION_PREFIX = "c_fun_description_";
|
||||||
|
|
||||||
|
public AndroidFunctionsMathRegistry(@NotNull MathRegistry<T> functionsRegistry) {
|
||||||
|
super(functionsRegistry, FUNCTION_DESCRIPTION_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
protected Map<String, String> getSubstitutes() {
|
||||||
|
return substitutes;
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,6 @@
|
|||||||
package org.solovyev.android.calculator.model;
|
package org.solovyev.android.calculator.model;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import jscl.math.function.Function;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.android.calculator.R;
|
import org.solovyev.android.calculator.R;
|
||||||
@ -24,32 +23,40 @@ import java.util.Map;
|
|||||||
* Date: 10/30/11
|
* Date: 10/30/11
|
||||||
* Time: 1:03 AM
|
* Time: 1:03 AM
|
||||||
*/
|
*/
|
||||||
public class AndroidMathRegistryImpl<T extends MathEntity> implements AndroidMathRegistry<T> {
|
public abstract class AndroidMathRegistryImpl<T extends MathEntity> implements AndroidMathRegistry<T> {
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static final String FUNCTION_DESCRIPTION_PREFIX = "c_fun_description_";
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final MathRegistry<T> functionsRegistry;
|
private final MathRegistry<T> functionsRegistry;
|
||||||
|
|
||||||
public AndroidMathRegistryImpl(@NotNull MathRegistry<T> functionsRegistry) {
|
@NotNull
|
||||||
|
private final String prefix;
|
||||||
|
|
||||||
|
protected AndroidMathRegistryImpl(@NotNull MathRegistry<T> functionsRegistry, @NotNull String prefix) {
|
||||||
this.functionsRegistry = functionsRegistry;
|
this.functionsRegistry = functionsRegistry;
|
||||||
|
this.prefix = prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected abstract Map<String, String> getSubstitutes();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String getDescription(@NotNull Context context, @NotNull String functionName) {
|
public String getDescription(@NotNull Context context, @NotNull String name) {
|
||||||
final String result;
|
final String result;
|
||||||
|
|
||||||
final Map<String, Integer> stringsCache = RClassUtils.getCache(R.string.class);
|
final Map<String, Integer> stringsCache = RClassUtils.getCache(R.string.class);
|
||||||
|
|
||||||
final Integer stringId;
|
final Integer stringId;
|
||||||
if (!functionName.equals("√")) {
|
|
||||||
stringId = stringsCache.get(FUNCTION_DESCRIPTION_PREFIX + functionName);
|
final Map<String, String> substitutes = getSubstitutes();
|
||||||
|
final String substitute = substitutes.get(name);
|
||||||
|
if (substitute == null) {
|
||||||
|
stringId = stringsCache.get(prefix + name);
|
||||||
} else {
|
} else {
|
||||||
// todo serso: think
|
// todo serso: think
|
||||||
stringId = stringsCache.get(FUNCTION_DESCRIPTION_PREFIX + "sqrt");
|
stringId = stringsCache.get(prefix + substitute);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stringId != null) {
|
if (stringId != null) {
|
||||||
result = context.getString(stringId);
|
result = context.getString(stringId);
|
||||||
} else {
|
} else {
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
|
* or visit http://se.solovyev.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.solovyev.android.calculator.model;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.solovyev.common.math.MathEntity;
|
||||||
|
import org.solovyev.common.math.MathRegistry;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: serso
|
||||||
|
* Date: 11/17/11
|
||||||
|
* Time: 11:29 PM
|
||||||
|
*/
|
||||||
|
public class AndroidOperatorsMathRegistry<T extends MathEntity> extends AndroidMathRegistryImpl<T> {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static final Map<String, String> substitutes = new HashMap<String, String>();
|
||||||
|
static {
|
||||||
|
substitutes.put("Σ", "sum");
|
||||||
|
substitutes.put("∏", "product");
|
||||||
|
substitutes.put("∂", "derivative");
|
||||||
|
substitutes.put("∫ab", "integral_ab");
|
||||||
|
substitutes.put("∫", "integral");
|
||||||
|
substitutes.put("Σ", "sum");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static final String OPERATOR_DESCRIPTION_PREFIX = "c_op_description_";
|
||||||
|
|
||||||
|
protected AndroidOperatorsMathRegistry(@NotNull MathRegistry<T> functionsRegistry) {
|
||||||
|
super(functionsRegistry, OPERATOR_DESCRIPTION_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
protected Map<String, String> getSubstitutes() {
|
||||||
|
return substitutes;
|
||||||
|
}
|
||||||
|
}
|
@ -13,24 +13,18 @@ import jscl.math.operator.Operator;
|
|||||||
import jscl.text.ParseInterruptedException;
|
import jscl.text.ParseInterruptedException;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.android.calculator.R;
|
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
import org.solovyev.android.msg.AndroidMessage;
|
import org.solovyev.android.msg.AndroidMessage;
|
||||||
import org.solovyev.common.NumberMapper;
|
import org.solovyev.common.NumberMapper;
|
||||||
import org.solovyev.common.math.MathRegistry;
|
import org.solovyev.common.math.MathRegistry;
|
||||||
import org.solovyev.common.msg.MessageRegistry;
|
import org.solovyev.common.msg.MessageRegistry;
|
||||||
import org.solovyev.common.msg.MessageType;
|
|
||||||
import org.solovyev.common.utils.CollectionsUtils;
|
|
||||||
import org.solovyev.common.utils.Formatter;
|
|
||||||
import org.solovyev.common.utils.MutableObject;
|
import org.solovyev.common.utils.MutableObject;
|
||||||
import org.solovyev.common.utils.StringUtils;
|
import org.solovyev.common.utils.StringUtils;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.text.DecimalFormatSymbols;
|
import java.text.DecimalFormatSymbols;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -70,18 +64,16 @@ public enum CalculatorEngine {
|
|||||||
private final AndroidVarsRegistry varsRegister = new AndroidVarsRegistryImpl(engine.getConstantsRegistry());
|
private final AndroidVarsRegistry varsRegister = new AndroidVarsRegistryImpl(engine.getConstantsRegistry());
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final AndroidMathRegistry functionsRegistry = new AndroidMathRegistryImpl(engine.getFunctionsRegistry());
|
private final AndroidMathRegistry functionsRegistry = new AndroidFunctionsMathRegistry(engine.getFunctionsRegistry());
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final AndroidMathRegistry operatorsRegistry = new AndroidMathRegistryImpl(engine.getOperatorsRegistry());
|
private final AndroidMathRegistry operatorsRegistry = new AndroidOperatorsMathRegistry(engine.getOperatorsRegistry());
|
||||||
|
|
||||||
private final MathRegistry<Operator> postfixFunctionsRegistry = engine.getPostfixFunctionsRegistry();
|
private final MathRegistry<Operator> postfixFunctionsRegistry = engine.getPostfixFunctionsRegistry();
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final static Set<String> tooLongExecutionCache = new HashSet<String>();
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault());
|
private DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault());
|
||||||
|
|
||||||
{
|
{
|
||||||
decimalGroupSymbols.setDecimalSeparator('.');
|
decimalGroupSymbols.setDecimalSeparator('.');
|
||||||
decimalGroupSymbols.setGroupingSeparator(GROUPING_SEPARATOR_DEFAULT.charAt(0));
|
decimalGroupSymbols.setGroupingSeparator(GROUPING_SEPARATOR_DEFAULT.charAt(0));
|
||||||
@ -106,7 +98,7 @@ public enum CalculatorEngine {
|
|||||||
final DecimalFormat df = new DecimalFormat();
|
final DecimalFormat df = new DecimalFormat();
|
||||||
df.setDecimalFormatSymbols(decimalGroupSymbols);
|
df.setDecimalFormatSymbols(decimalGroupSymbols);
|
||||||
df.setGroupingUsed(useGroupingSeparator);
|
df.setGroupingUsed(useGroupingSeparator);
|
||||||
if (round ) {
|
if (round) {
|
||||||
if (isRoundResult()) {
|
if (isRoundResult()) {
|
||||||
df.setMaximumFractionDigits(instance.getPrecision());
|
df.setMaximumFractionDigits(instance.getPrecision());
|
||||||
return df.format(new BigDecimal(value).setScale(instance.getPrecision(), BigDecimal.ROUND_HALF_UP).doubleValue());
|
return df.format(new BigDecimal(value).setScale(instance.getPrecision(), BigDecimal.ROUND_HALF_UP).doubleValue());
|
||||||
@ -178,75 +170,70 @@ public enum CalculatorEngine {
|
|||||||
final JsclOperation finalOperation = operation;
|
final JsclOperation finalOperation = operation;
|
||||||
|
|
||||||
final String result;
|
final String result;
|
||||||
if (!tooLongExecutionCache.contains(jsclExpression)) {
|
final MutableObject<String> calculationResult = new MutableObject<String>(null);
|
||||||
final MutableObject<String> calculationResult = new MutableObject<String>(null);
|
final MutableObject<ParseException> exception = new MutableObject<ParseException>(null);
|
||||||
final MutableObject<ParseException> exception = new MutableObject<ParseException>(null);
|
final MutableObject<Thread> calculationThread = new MutableObject<Thread>(null);
|
||||||
final MutableObject<Thread> calculationThread = new MutableObject<Thread>(null);
|
|
||||||
|
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final Thread thread = Thread.currentThread();
|
final Thread thread = Thread.currentThread();
|
||||||
try {
|
try {
|
||||||
//Log.d(CalculatorEngine.class.getName(), "Calculation thread started work: " + thread.getName());
|
//Log.d(CalculatorEngine.class.getName(), "Calculation thread started work: " + thread.getName());
|
||||||
//System.out.println(jsclExpression);
|
//System.out.println(jsclExpression);
|
||||||
calculationThread.setObject(thread);
|
calculationThread.setObject(thread);
|
||||||
calculationResult.setObject(finalOperation.evaluate(jsclExpression));
|
calculationResult.setObject(finalOperation.evaluate(jsclExpression));
|
||||||
} catch (ArithmeticException e) {
|
} catch (ArithmeticException e) {
|
||||||
//System.out.println(e.getMessage());
|
//System.out.println(e.getMessage());
|
||||||
exception.setObject(new ParseException(e.getMessage(), e));
|
exception.setObject(new ParseException(e.getMessage(), e));
|
||||||
} catch (jscl.text.ParseException e) {
|
} catch (jscl.text.ParseException e) {
|
||||||
//System.out.println(e.getMessage());
|
//System.out.println(e.getMessage());
|
||||||
exception.setObject(new ParseException(e.getMessage(), e));
|
exception.setObject(new ParseException(e.getMessage(), e));
|
||||||
} catch (ParseInterruptedException e) {
|
} catch (ParseInterruptedException e) {
|
||||||
//System.out.println(e.getMessage());
|
//System.out.println(e.getMessage());
|
||||||
// do nothing - we ourselves interrupt the calculations
|
// do nothing - we ourselves interrupt the calculations
|
||||||
} finally {
|
} finally {
|
||||||
//Log.d(CalculatorEngine.class.getName(), "Calculation thread ended work: " + thread.getName());
|
//Log.d(CalculatorEngine.class.getName(), "Calculation thread ended work: " + thread.getName());
|
||||||
calculationThread.setObject(null);
|
calculationThread.setObject(null);
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).start();
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//Log.d(CalculatorEngine.class.getName(), "Main thread is waiting: " + Thread.currentThread().getName());
|
//Log.d(CalculatorEngine.class.getName(), "Main thread is waiting: " + Thread.currentThread().getName());
|
||||||
latch.await(timeout, TimeUnit.MILLISECONDS);
|
latch.await(timeout, TimeUnit.MILLISECONDS);
|
||||||
//Log.d(CalculatorEngine.class.getName(), "Main thread got up: " + Thread.currentThread().getName());
|
//Log.d(CalculatorEngine.class.getName(), "Main thread got up: " + Thread.currentThread().getName());
|
||||||
|
|
||||||
final ParseException evalErrorLocal = exception.getObject();
|
final ParseException evalErrorLocal = exception.getObject();
|
||||||
final Object calculationResultLocal = calculationResult.getObject();
|
final Object calculationResultLocal = calculationResult.getObject();
|
||||||
final Thread calculationThreadLocal = calculationThread.getObject();
|
final Thread calculationThreadLocal = calculationThread.getObject();
|
||||||
|
|
||||||
if (calculationThreadLocal != null) {
|
if (calculationThreadLocal != null) {
|
||||||
// todo serso: interrupt doesn't stop the thread but it MUST be killed
|
// todo serso: interrupt doesn't stop the thread but it MUST be killed
|
||||||
threadKiller.killThread(calculationThreadLocal);
|
threadKiller.killThread(calculationThreadLocal);
|
||||||
//calculationThreadLocal.stop();
|
//calculationThreadLocal.stop();
|
||||||
}
|
|
||||||
|
|
||||||
if ( evalErrorLocal != null ) {
|
|
||||||
if ( finalOperation == JsclOperation.numeric && preparedExpression.isExistsUndefinedVar() ) {
|
|
||||||
return evaluate(JsclOperation.simplify, expression, mr);
|
|
||||||
}
|
|
||||||
throw evalErrorLocal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( calculationResultLocal == null ) {
|
|
||||||
tooLongExecutionCache.add(jsclExpression);
|
|
||||||
throw new ParseException("Too long calculation for: " + jsclExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new ParseException(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = String.valueOf(calculationResult.getObject()).trim();
|
if (evalErrorLocal != null) {
|
||||||
} else {
|
if (finalOperation == JsclOperation.numeric && preparedExpression.isExistsUndefinedVar()) {
|
||||||
throw new ParseException("Too long calculation for: " + jsclExpression);
|
return evaluate(JsclOperation.simplify, expression, mr);
|
||||||
|
}
|
||||||
|
throw evalErrorLocal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calculationResultLocal == null) {
|
||||||
|
throw new ParseException("Too long calculation for: " + jsclExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new ParseException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = String.valueOf(calculationResult.getObject()).trim();
|
||||||
|
|
||||||
return new Result(operation.getFromProcessor().process(result), operation);
|
return new Result(operation.getFromProcessor().process(result), operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -330,6 +317,7 @@ public enum CalculatorEngine {
|
|||||||
void setTimeout(int timeout) {
|
void setTimeout(int timeout) {
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for tests only
|
// for tests only
|
||||||
void setThreadKiller(@NotNull ThreadKiller threadKiller) {
|
void setThreadKiller(@NotNull ThreadKiller threadKiller) {
|
||||||
this.threadKiller = threadKiller;
|
this.threadKiller = threadKiller;
|
||||||
|
Loading…
Reference in New Issue
Block a user