From 89680ef54483545f18ae98a18271aaa154150e60 Mon Sep 17 00:00:00 2001 From: serso Date: Mon, 1 Feb 2016 23:15:10 +0100 Subject: [PATCH] Changes --- .../android/calculator/Calculator.java | 169 +++++++++--------- .../android/calculator/CalculatorUtils.java | 13 +- .../solovyev/android/calculator/Display.java | 9 + .../android/calculator/DisplayState.java | 6 +- .../android/calculator/EditorState.java | 9 +- .../calculator/PreparedExpression.java | 31 ++-- .../android/calculator/VariablesRegistry.java | 3 - .../CalculationFinishedEvent.java | 9 +- .../functions/EditFunctionFragment.java | 4 +- .../android/calculator/history/History.java | 2 +- .../variables/VariablesFragment.java | 5 +- .../view/NumeralBaseConverterDialog.java | 2 +- .../calculator/model/AndroidEngineTest.java | 2 +- .../calculator/model/NumeralBaseTest.java | 30 ++-- .../model/ToJsclTextProcessorTest.java | 2 +- jscl/src/main/java/jscl/JsclMathEngine.java | 22 +-- .../java/jscl/math/function/Constants.java | 4 + 17 files changed, 158 insertions(+), 164 deletions(-) diff --git a/app/src/main/java/org/solovyev/android/calculator/Calculator.java b/app/src/main/java/org/solovyev/android/calculator/Calculator.java index 511541ed..6d490a62 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Calculator.java +++ b/app/src/main/java/org/solovyev/android/calculator/Calculator.java @@ -28,17 +28,14 @@ import android.text.TextUtils; import android.util.Log; import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; -import jscl.JsclArithmeticException; -import jscl.MathEngine; -import jscl.NumeralBase; -import jscl.NumeralBaseException; +import jscl.*; import jscl.math.Generic; +import jscl.math.function.Constants; import jscl.math.function.IConstant; import jscl.text.ParseInterruptedException; import org.solovyev.android.calculator.calculations.CalculationCancelledEvent; import org.solovyev.android.calculator.calculations.CalculationFailedEvent; import org.solovyev.android.calculator.calculations.CalculationFinishedEvent; -import org.solovyev.android.calculator.errors.FixableErrorsActivity; import org.solovyev.android.calculator.functions.FunctionsRegistry; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.units.CalculatorNumeralBase; @@ -57,6 +54,7 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -65,12 +63,13 @@ import java.util.concurrent.atomic.AtomicLong; @Singleton public class Calculator implements CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener { + public static final long NO_SEQUENCE = -1; private static final long PREFERENCE_CHECK_INTERVAL = TimeUnit.MINUTES.toMillis(15); @Nonnull private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer(); @Nonnull - private final AtomicLong counter = new AtomicLong(CalculatorUtils.FIRST_ID); + private static final AtomicLong SEQUENCER = new AtomicLong(NO_SEQUENCE); @Nonnull private final ToJsclTextProcessor preprocessor = ToJsclTextProcessor.getInstance(); @Nonnull @@ -90,6 +89,8 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On PreferredPreferences preferredPreferences; @Inject Editor editor; + @Inject + JsclMathEngine mathEngine; @Inject public Calculator(@Nonnull SharedPreferences preferences, @Nonnull Bus bus, @Named(AppModule.THREAD_UI) @Nonnull Executor ui, @Named(AppModule.THREAD_BACKGROUND) @Nonnull Executor background) { @@ -113,7 +114,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On String fromString = generic.toString(); if (!Strings.isEmpty(fromString)) { try { - fromString = ToJsclTextProcessor.getInstance().process(fromString).getExpression(); + fromString = ToJsclTextProcessor.getInstance().process(fromString).getValue(); } catch (ParseException e) { // ok, problems while processing occurred } @@ -130,19 +131,19 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On @Nonnull private CalculatorEventData nextEventData() { - long eventId = counter.incrementAndGet(); + final long eventId = nextSequence(); return CalculatorEventDataImpl.newInstance(eventId, eventId); } @Nonnull private CalculatorEventData nextEventData(@Nonnull Object source) { - long eventId = counter.incrementAndGet(); + long eventId = nextSequence(); return CalculatorEventDataImpl.newInstance(eventId, eventId, source); } @Nonnull private CalculatorEventData nextEventData(@Nonnull Long sequenceId) { - long eventId = counter.incrementAndGet(); + long eventId = nextSequence(); return CalculatorEventDataImpl.newInstance(eventId, sequenceId); } @@ -167,7 +168,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On background.execute(new Runnable() { @Override public void run() { - Calculator.this.evaluateAsync(eventDataId.getSequenceId(), operation, expression, null); + evaluateAsync(eventDataId.getSequenceId(), operation, expression); } }); @@ -181,7 +182,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On background.execute(new Runnable() { @Override public void run() { - evaluateAsync(eventDataId.getSequenceId(), operation, expression, null); + evaluateAsync(eventDataId.getSequenceId(), operation, expression); } }); @@ -215,72 +216,75 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On return CalculatorConversionEventDataImpl.newInstance(nextEventData(sequenceId), value, from, to, displayViewState); } + private void evaluateAsync(long sequence, @Nonnull JsclOperation o, @Nonnull String e) { + evaluateAsync(sequence, o, e, new ListMessageRegistry()); + } + private void evaluateAsync(long sequence, - @Nonnull JsclOperation operation, - @Nonnull String expression, - @Nullable MessageRegistry mr) { + @Nonnull JsclOperation o, + @Nonnull String e, + @Nonnull MessageRegistry mr) { + e = e.trim(); + if (Strings.isEmpty(e)) { + bus.post(new CalculationFinishedEvent(o, e, sequence)); + return; + } + checkPreferredPreferences(); - expression = expression.trim(); - - PreparedExpression preparedExpression = null; + PreparedExpression pe = null; try { - if (Strings.isEmpty(expression)) { - bus.post(new CalculationFinishedEvent(operation, expression, sequence)); - return; - } - preparedExpression = prepareExpression(expression); - - final String jsclExpression = preparedExpression.toString(); + pe = prepare(e); try { - final MathEngine mathEngine = Locator.getInstance().getEngine().getMathEngine(); + Locator.getInstance().getEngine().getMathEngine().setMessageRegistry(mr); - final MessageRegistry messageRegistry = new ListMessageRegistry(); - Locator.getInstance().getEngine().getMathEngine().setMessageRegistry(messageRegistry); - - final Generic result = operation.evaluateGeneric(jsclExpression, mathEngine); + final Generic result = o.evaluateGeneric(pe.value, mathEngine); // NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!) + //noinspection ResultOfMethodCallIgnored result.toString(); - if (messageRegistry.hasMessage()) { - try { - final List messages = new ArrayList<>(); - while (messageRegistry.hasMessage()) { - messages.add(messageRegistry.getMessage()); - } - if (!messages.isEmpty()) { - fireCalculatorEvent(newCalculationEventData(operation, expression, sequence), CalculatorEventType.calculation_messages, messages); - } - } catch (Throwable e) { - // todo serso: not good but we need proper synchronization - Log.e("Calculator", e.getMessage(), e); - } - } + final String stringResult = o.getFromProcessor().process(result); + bus.post(new CalculationFinishedEvent(o, e, sequence, result, stringResult, collectMessages(mr))); - final String stringResult = operation.getFromProcessor().process(result); - bus.post(new CalculationFinishedEvent(operation, expression, sequence, result, stringResult)); - - } catch (JsclArithmeticException e) { - if (operation == JsclOperation.numeric && e.getCause() instanceof NumeralBaseException) { - evaluateAsync(sequence, JsclOperation.simplify, expression, mr); + } catch (JsclArithmeticException exception) { + if (o == JsclOperation.numeric && exception.getCause() instanceof NumeralBaseException) { + evaluateAsync(sequence, JsclOperation.simplify, e, mr); } else { - bus.post(new CalculationFailedEvent(operation, expression, sequence, e)); + bus.post(new CalculationFailedEvent(o, e, sequence, exception)); } } - } catch (ArithmeticException e) { - handleException(sequence, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage()))); - } catch (StackOverflowError e) { - handleException(sequence, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error))); - } catch (jscl.text.ParseException e) { - handleException(sequence, operation, expression, mr, preparedExpression, new ParseException(e)); - } catch (ParseInterruptedException e) { - bus.post(new CalculationCancelledEvent(operation, expression, sequence)); - } catch (ParseException e) { - handleException(sequence, operation, expression, mr, preparedExpression, e); + } catch (ArithmeticException exception) { + onException(sequence, o, e, mr, pe, new ParseException(e, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, exception.getMessage()))); + } catch (StackOverflowError exception) { + onException(sequence, o, e, mr, pe, new ParseException(e, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error))); + } catch (jscl.text.ParseException exception) { + onException(sequence, o, e, mr, pe, new ParseException(exception)); + } catch (ParseInterruptedException exception) { + bus.post(new CalculationCancelledEvent(o, e, sequence)); + } catch (ParseException exception) { + onException(sequence, o, e, mr, pe, exception); } } + @Nonnull + private List collectMessages(@Nonnull MessageRegistry mr) { + if (mr.hasMessage()) { + try { + final List messages = new ArrayList<>(); + while (mr.hasMessage()) { + messages.add(mr.getMessage()); + } + return messages; + } catch (Throwable exception) { + // several threads might use the same instance of MessageRegistry, as no proper synchronization is done + // catch Throwable here + Log.e("Calculator", exception.getMessage(), exception); + } + } + return Collections.emptyList(); + } + private void checkPreferredPreferences() { if (shouldCheckPreferredPreferences()) { preferredPreferences.check(false); @@ -298,30 +302,23 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On } @Nonnull - public PreparedExpression prepareExpression(@Nonnull String expression) throws ParseException { + public PreparedExpression prepare(@Nonnull String expression) throws ParseException { return preprocessor.process(expression); } - @Nonnull - private CalculatorEventData newCalculationEventData(@Nonnull JsclOperation operation, - @Nonnull String expression, - @Nonnull Long calculationId) { - return new CalculatorEvaluationEventDataImpl(nextEventData(calculationId), operation, expression); - } - - private void handleException(long sequence, - @Nonnull JsclOperation operation, - @Nonnull String expression, - @Nullable MessageRegistry mr, - @Nullable PreparedExpression preparedExpression, - @Nonnull ParseException parseException) { + private void onException(long sequence, + @Nonnull JsclOperation operation, + @Nonnull String e, + @Nonnull MessageRegistry mr, + @Nullable PreparedExpression pe, + @Nonnull ParseException parseException) { if (operation == JsclOperation.numeric - && preparedExpression != null - && preparedExpression.isExistsUndefinedVar()) { - evaluateAsync(sequence, JsclOperation.simplify, expression, mr); - } else { - bus.post(new CalculationFailedEvent(operation, expression, sequence, parseException)); + && pe != null + && pe.hasUndefinedVariables()) { + evaluateAsync(sequence, JsclOperation.simplify, e, mr); + return; } + bus.post(new CalculationFailedEvent(operation, e, sequence, parseException)); } @Nonnull @@ -423,9 +420,9 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On private void updateAnsVariable(@NonNull String value) { final VariablesRegistry variablesRegistry = Locator.getInstance().getEngine().getVariablesRegistry(); - final IConstant variable = variablesRegistry.get(VariablesRegistry.ANS); + final IConstant variable = variablesRegistry.get(Constants.ANS); - final CppVariable.Builder b = variable != null ? CppVariable.builder(variable) : CppVariable.builder(VariablesRegistry.ANS); + final CppVariable.Builder b = variable != null ? CppVariable.builder(variable) : CppVariable.builder(Constants.ANS); b.withValue(value); b.withSystem(true); b.withDescription(CalculatorMessages.getBundle().getString(CalculatorMessages.ans_description)); @@ -460,7 +457,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On @Subscribe public void onVariableChanged(@NonNull VariablesRegistry.ChangedEvent e) { - if (!e.newVariable.getName().equals(VariablesRegistry.ANS)) { + if (!e.newVariable.getName().equals(Constants.ANS)) { evaluate(); } } @@ -468,9 +465,6 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On @Override public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { switch (calculatorEventType) { - case calculation_messages: - FixableErrorsActivity.show(App.getApplication(), (List) data); - break; case show_history: ActivityLauncher.showHistory(App.getApplication()); break; @@ -520,4 +514,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On } } + public static long nextSequence() { + return SEQUENCER.incrementAndGet(); + } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorUtils.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorUtils.java index e3f05498..6a347e3d 100644 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorUtils.java +++ b/app/src/main/java/org/solovyev/android/calculator/CalculatorUtils.java @@ -22,15 +22,14 @@ package org.solovyev.android.calculator; -import java.util.HashSet; -import java.util.Set; - -import javax.annotation.Nonnull; - import jscl.math.Generic; import jscl.math.function.Constant; import jscl.math.function.IConstant; +import javax.annotation.Nonnull; +import java.util.HashSet; +import java.util.Set; + /** * User: serso * Date: 9/22/12 @@ -38,15 +37,13 @@ import jscl.math.function.IConstant; */ public final class CalculatorUtils { - static final long FIRST_ID = 0; - private CalculatorUtils() { throw new AssertionError(); } @Nonnull public static CalculatorEventData createFirstEventDataId() { - return CalculatorEventDataImpl.newInstance(FIRST_ID, FIRST_ID); + return CalculatorEventDataImpl.newInstance(Calculator.NO_SEQUENCE, Calculator.NO_SEQUENCE); } @Nonnull diff --git a/app/src/main/java/org/solovyev/android/calculator/Display.java b/app/src/main/java/org/solovyev/android/calculator/Display.java index 747abf5e..fee0a75c 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Display.java +++ b/app/src/main/java/org/solovyev/android/calculator/Display.java @@ -22,6 +22,8 @@ package org.solovyev.android.calculator; +import android.app.Application; +import android.content.Context; import android.view.ContextMenu; import android.view.MenuItem; import android.view.View; @@ -33,6 +35,7 @@ import org.solovyev.android.Check; import org.solovyev.android.calculator.calculations.CalculationCancelledEvent; import org.solovyev.android.calculator.calculations.CalculationFailedEvent; import org.solovyev.android.calculator.calculations.CalculationFinishedEvent; +import org.solovyev.android.calculator.errors.FixableErrorsActivity; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.view.NumeralBaseConverterDialog; @@ -53,6 +56,8 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V @Nonnull private final Bus bus; @Inject + Application application; + @Inject Lazy keyboard; @Inject Lazy clipboard; @@ -84,6 +89,10 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V public void onCalculationFinished(@Nonnull CalculationFinishedEvent e) { if (e.sequence < state.sequence) return; setState(DisplayState.createValid(e.operation, e.result, e.stringResult, e.sequence)); + if (!e.messages.isEmpty()) { + final Context context = view != null ? view.getContext() : application; + FixableErrorsActivity.show(context, e.messages); + } } @Subscribe diff --git a/app/src/main/java/org/solovyev/android/calculator/DisplayState.java b/app/src/main/java/org/solovyev/android/calculator/DisplayState.java index c1b3c764..2a2297f7 100644 --- a/app/src/main/java/org/solovyev/android/calculator/DisplayState.java +++ b/app/src/main/java/org/solovyev/android/calculator/DisplayState.java @@ -64,18 +64,18 @@ public class DisplayState implements Parcelable, ContextMenu.ContextMenuInfo { } DisplayState(@Nonnull JSONObject json) { - this(json.optString(JSON_TEXT), true, EditorState.NO_SEQUENCE); + this(json.optString(JSON_TEXT), true, Calculator.NO_SEQUENCE); } private DisplayState(Parcel in) { text = in.readString(); valid = in.readByte() != 0; - sequence = EditorState.NO_SEQUENCE; + sequence = Calculator.NO_SEQUENCE; } @Nonnull public static DisplayState empty() { - return new DisplayState("", true, EditorState.NO_SEQUENCE); + return new DisplayState("", true, Calculator.NO_SEQUENCE); } @Nonnull diff --git a/app/src/main/java/org/solovyev/android/calculator/EditorState.java b/app/src/main/java/org/solovyev/android/calculator/EditorState.java index 0368f65b..14784dea 100644 --- a/app/src/main/java/org/solovyev/android/calculator/EditorState.java +++ b/app/src/main/java/org/solovyev/android/calculator/EditorState.java @@ -25,18 +25,14 @@ package org.solovyev.android.calculator; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; - import org.json.JSONException; import org.json.JSONObject; -import java.util.concurrent.atomic.AtomicLong; - import javax.annotation.Nonnull; import javax.annotation.Nullable; public class EditorState implements Parcelable { - public static final long NO_SEQUENCE = -1; public static final Creator CREATOR = new Creator() { @Override public EditorState createFromParcel(Parcel in) { @@ -50,7 +46,6 @@ public class EditorState implements Parcelable { }; private static final String JSON_TEXT = "t"; private static final String JSON_SELECTION = "s"; - private static AtomicLong counter = new AtomicLong(NO_SEQUENCE + 1); public final long sequence; @Nonnull public final CharSequence text; @@ -63,7 +58,7 @@ public class EditorState implements Parcelable { } private EditorState(@Nonnull CharSequence text, int selection) { - this.sequence = counter.getAndIncrement(); + this.sequence = Calculator.nextSequence(); this.text = text; this.selection = selection; } @@ -73,7 +68,7 @@ public class EditorState implements Parcelable { } private EditorState(Parcel in) { - sequence = NO_SEQUENCE; + sequence = Calculator.NO_SEQUENCE; selection = in.readInt(); textString = in.readString(); text = textString; diff --git a/app/src/main/java/org/solovyev/android/calculator/PreparedExpression.java b/app/src/main/java/org/solovyev/android/calculator/PreparedExpression.java index b81f5a41..78ad5600 100644 --- a/app/src/main/java/org/solovyev/android/calculator/PreparedExpression.java +++ b/app/src/main/java/org/solovyev/android/calculator/PreparedExpression.java @@ -31,48 +31,43 @@ import java.util.List; public class PreparedExpression implements CharSequence { @Nonnull - private String expression; + public final String value; @Nonnull - private List undefinedVars; + public final List undefinedVariables; - public PreparedExpression(@Nonnull String expression, @Nonnull List undefinedVars) { - this.expression = expression; - this.undefinedVars = undefinedVars; + public PreparedExpression(@Nonnull String value, @Nonnull List undefinedVariables) { + this.value = value; + this.undefinedVariables = undefinedVariables; } @Nonnull - public String getExpression() { - return expression; + public String getValue() { + return value; } - public boolean isExistsUndefinedVar() { - return !this.undefinedVars.isEmpty(); - } - - @Nonnull - public List getUndefinedVars() { - return undefinedVars; + public boolean hasUndefinedVariables() { + return !undefinedVariables.isEmpty(); } @Override public int length() { - return expression.length(); + return value.length(); } @Override public char charAt(int i) { - return expression.charAt(i); + return value.charAt(i); } @Override public CharSequence subSequence(int i, int i1) { - return expression.subSequence(i, i1); + return value.subSequence(i, i1); } @NonNull @Override public String toString() { - return this.expression; + return this.value; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/VariablesRegistry.java b/app/src/main/java/org/solovyev/android/calculator/VariablesRegistry.java index 8d66f6cb..d6feb80a 100644 --- a/app/src/main/java/org/solovyev/android/calculator/VariablesRegistry.java +++ b/app/src/main/java/org/solovyev/android/calculator/VariablesRegistry.java @@ -52,9 +52,6 @@ import java.util.Map; @Singleton public class VariablesRegistry extends BaseEntitiesRegistry { - @Nonnull - public static final String ANS = "ans"; - @Nonnull private static final Map substitutes = new HashMap<>(); diff --git a/app/src/main/java/org/solovyev/android/calculator/calculations/CalculationFinishedEvent.java b/app/src/main/java/org/solovyev/android/calculator/calculations/CalculationFinishedEvent.java index 097722ec..bb1aa3e9 100644 --- a/app/src/main/java/org/solovyev/android/calculator/calculations/CalculationFinishedEvent.java +++ b/app/src/main/java/org/solovyev/android/calculator/calculations/CalculationFinishedEvent.java @@ -2,25 +2,32 @@ package org.solovyev.android.calculator.calculations; import jscl.math.Generic; import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.common.msg.Message; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Collections; +import java.util.List; public final class CalculationFinishedEvent extends BaseCalculationEvent { @Nullable public final Generic result; @Nonnull public final String stringResult; + @Nonnull + public final List messages; public CalculationFinishedEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence) { super(operation, expression, sequence); result = null; stringResult = ""; + messages = Collections.emptyList(); } - public CalculationFinishedEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence, @Nullable Generic result, @Nonnull String stringResult) { + public CalculationFinishedEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence, @Nullable Generic result, @Nonnull String stringResult, @Nonnull List messages) { super(operation, expression, sequence); this.result = result; this.stringResult = stringResult; + this.messages = messages; } } diff --git a/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java b/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java index 1eb841ea..e47dad63 100644 --- a/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/functions/EditFunctionFragment.java @@ -271,7 +271,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC private boolean applyData() { try { - final String body = calculator.prepareExpression(bodyView.getText().toString()).getExpression(); + final String body = calculator.prepare(bodyView.getText().toString()).getValue(); final CppFunction newFunction = CppFunction.builder(nameView.getText().toString(), body) .withId(isNewFunction() ? NO_ID : function.id) @@ -326,7 +326,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC return false; } try { - calculator.prepareExpression(body); + calculator.prepare(body); clearError(bodyLabel); return true; } catch (ParseException e) { diff --git a/app/src/main/java/org/solovyev/android/calculator/history/History.java b/app/src/main/java/org/solovyev/android/calculator/history/History.java index bd3acb4e..4f232793 100644 --- a/app/src/main/java/org/solovyev/android/calculator/history/History.java +++ b/app/src/main/java/org/solovyev/android/calculator/history/History.java @@ -100,7 +100,7 @@ public class History { final OldDisplayHistoryState oldDisplay = state.getDisplayState(); final String editorText = oldEditor.getText(); final EditorState editor = EditorState.create(Strings.nullToEmpty(editorText), oldEditor.getCursorPosition()); - final DisplayState display = DisplayState.createValid(oldDisplay.getJsclOperation(), null, Strings.nullToEmpty(oldDisplay.getEditorState().getText()), EditorState.NO_SEQUENCE); + final DisplayState display = DisplayState.createValid(oldDisplay.getJsclOperation(), null, Strings.nullToEmpty(oldDisplay.getEditorState().getText()), Calculator.NO_SEQUENCE); states.add(HistoryState.builder(editor, display).withTime(state.getTime()).withComment(state.getComment()).build()); } return states; diff --git a/app/src/main/java/org/solovyev/android/calculator/variables/VariablesFragment.java b/app/src/main/java/org/solovyev/android/calculator/variables/VariablesFragment.java index 9edf2512..d3d43aa4 100644 --- a/app/src/main/java/org/solovyev/android/calculator/variables/VariablesFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/variables/VariablesFragment.java @@ -61,9 +61,8 @@ public class VariablesFragment extends BaseEntitiesFragment { public static boolean isValidValue(@Nonnull String value) { try { - final PreparedExpression expression = ToJsclTextProcessor.getInstance().process(value); - final List variables = expression.getUndefinedVars(); - return variables.isEmpty(); + final PreparedExpression pe = ToJsclTextProcessor.getInstance().process(value); + return !pe.hasUndefinedVariables(); } catch (RuntimeException e) { return false; } diff --git a/app/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java b/app/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java index 55e64426..d7c50fdd 100644 --- a/app/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java +++ b/app/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java @@ -57,7 +57,7 @@ public class NumeralBaseConverterDialog { if (!Strings.isEmpty(initialFromValue)) { String value = initialFromValue; try { - value = ToJsclTextProcessor.getInstance().process(value).getExpression(); + value = ToJsclTextProcessor.getInstance().process(value).getValue(); b.setFromValue(UnitImpl.newInstance(value, CalculatorNumeralBase.valueOf(Locator.getInstance().getEngine().getMathEngine().getNumeralBase()))); } catch (ParseException e) { b.setFromValue(UnitImpl.newInstance(value, CalculatorNumeralBase.valueOf(Locator.getInstance().getEngine().getMathEngine().getNumeralBase()))); diff --git a/app/src/test/java/org/solovyev/android/calculator/model/AndroidEngineTest.java b/app/src/test/java/org/solovyev/android/calculator/model/AndroidEngineTest.java index e684dcd2..d7e84a18 100644 --- a/app/src/test/java/org/solovyev/android/calculator/model/AndroidEngineTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/model/AndroidEngineTest.java @@ -90,7 +90,7 @@ public class AndroidEngineTest extends AbstractCalculatorTest { } @Test - public void testI() throws ParseException, EvalException { + public void testI() throws ParseException { final MathEngine cm = Locator.getInstance().getEngine().getMathEngine(); CalculatorTestUtils.assertEval("-i", cm.evaluate("i^3")); diff --git a/app/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java b/app/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java index 73c6f067..8ab0bfe0 100644 --- a/app/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java @@ -22,26 +22,24 @@ package org.solovyev.android.calculator.model; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.solovyev.android.calculator.AbstractCalculatorTest; -import org.solovyev.android.calculator.ParseException; -import org.solovyev.android.calculator.CalculatorTestUtils; -import org.solovyev.android.calculator.Locator; -import org.solovyev.common.Converter; - -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.Nonnull; - import au.com.bytecode.opencsv.CSVReader; import jscl.JsclMathEngine; import jscl.MathEngine; import jscl.math.Expression; import jscl.util.ExpressionGeneratorWithInput; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.solovyev.android.calculator.AbstractCalculatorTest; +import org.solovyev.android.calculator.CalculatorTestUtils; +import org.solovyev.android.calculator.Locator; +import org.solovyev.android.calculator.ParseException; +import org.solovyev.common.Converter; + +import javax.annotation.Nonnull; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; /** * User: serso @@ -56,7 +54,7 @@ public class NumeralBaseTest extends AbstractCalculatorTest { Locator.getInstance().getEngine().getMathEngine().setPrecision(3); } - public static void testExpression(@Nonnull String[] line, @Nonnull Converter converter) throws jscl.text.ParseException, EvalException, ParseException { + public static void testExpression(@Nonnull String[] line, @Nonnull Converter converter) throws jscl.text.ParseException, ParseException { final String dec = line[0].toUpperCase(); final String hex = "0x:" + line[1].toUpperCase(); final String bin = "0b:" + line[2].toUpperCase(); diff --git a/app/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java b/app/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java index e29c804e..cb3f586b 100644 --- a/app/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java @@ -149,7 +149,7 @@ public class ToJsclTextProcessorTest extends AbstractCalculatorTest { Assert.assertEquals("101", JsclMathEngine.getInstance().evaluate("10+11")); JsclMathEngine.getInstance().setNumeralBase(NumeralBase.hex); - Assert.assertEquals("56CE+CAD", processor.process("56CE+CAD").getExpression()); + Assert.assertEquals("56CE+CAD", processor.process("56CE+CAD").getValue()); } finally { JsclMathEngine.getInstance().setNumeralBase(defaultNumeralBase); } diff --git a/jscl/src/main/java/jscl/JsclMathEngine.java b/jscl/src/main/java/jscl/JsclMathEngine.java index 7473d16d..dd5da63a 100644 --- a/jscl/src/main/java/jscl/JsclMathEngine.java +++ b/jscl/src/main/java/jscl/JsclMathEngine.java @@ -16,7 +16,6 @@ import org.solovyev.common.msg.MessageRegistry; import org.solovyev.common.msg.Messages; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; @@ -168,19 +167,16 @@ public class JsclMathEngine implements MathEngine { // detect if current number is precisely equals to constant in constants' registry (NOTE: ONLY FOR SYSTEM CONSTANTS) final Double localValue = value; - IConstant constant = Collections.find(this.getConstantsRegistry().getSystemEntities(), new JPredicate() { - public boolean apply(@Nullable IConstant constant) { - if (constant != null) { - if (localValue.equals(constant.getDoubleValue())) { - if (!constant.getName().equals(Constants.PI_INV.getName())) { - if (!constant.getName().equals(Constants.PI.getName()) || JsclMathEngine.getInstance().getAngleUnits() == AngleUnit.rad) { - return true; - } - } - } + IConstant constant = Collections.find(getConstantsRegistry().getSystemEntities(), new JPredicate() { + public boolean apply(@Nonnull IConstant constant) { + if (!localValue.equals(constant.getDoubleValue())) { + return false; } - - return false; + final String name = constant.getName(); + if (name.equals(Constants.PI_INV.getName()) || name.equals(Constants.ANS)) { + return false; + } + return !name.equals(Constants.PI.getName()) || JsclMathEngine.getInstance().getAngleUnits() == AngleUnit.rad; } }); diff --git a/jscl/src/main/java/jscl/math/function/Constants.java b/jscl/src/main/java/jscl/math/function/Constants.java index 6e9e23c0..3f23c9a4 100644 --- a/jscl/src/main/java/jscl/math/function/Constants.java +++ b/jscl/src/main/java/jscl/math/function/Constants.java @@ -2,6 +2,8 @@ package jscl.math.function; import jscl.math.JsclInteger; +import javax.annotation.Nonnull; + /** * User: serso * Date: 1/7/12 @@ -14,6 +16,8 @@ public final class Constants { public static final Constant I = new Constant("i"); public static final Constant INF = new Constant("∞"); public static final Constant INF_2 = new Constant("Infinity"); + @Nonnull + public static final String ANS = "ans"; // not intended for instantiation private Constants() {