Changes
This commit is contained in:
parent
8c56dd1083
commit
89680ef544
@ -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,70 +216,73 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
|
||||
return CalculatorConversionEventDataImpl.newInstance(nextEventData(sequenceId), value, from, to, displayViewState);
|
||||
}
|
||||
|
||||
private void evaluateAsync(long sequence,
|
||||
@Nonnull JsclOperation operation,
|
||||
@Nonnull String expression,
|
||||
@Nullable MessageRegistry mr) {
|
||||
checkPreferredPreferences();
|
||||
expression = expression.trim();
|
||||
private void evaluateAsync(long sequence, @Nonnull JsclOperation o, @Nonnull String e) {
|
||||
evaluateAsync(sequence, o, e, new ListMessageRegistry());
|
||||
}
|
||||
|
||||
PreparedExpression preparedExpression = null;
|
||||
try {
|
||||
if (Strings.isEmpty(expression)) {
|
||||
bus.post(new CalculationFinishedEvent(operation, expression, sequence));
|
||||
private void evaluateAsync(long sequence,
|
||||
@Nonnull JsclOperation o,
|
||||
@Nonnull String e,
|
||||
@Nonnull MessageRegistry mr) {
|
||||
e = e.trim();
|
||||
if (Strings.isEmpty(e)) {
|
||||
bus.post(new CalculationFinishedEvent(o, e, sequence));
|
||||
return;
|
||||
}
|
||||
preparedExpression = prepareExpression(expression);
|
||||
|
||||
final String jsclExpression = preparedExpression.toString();
|
||||
checkPreferredPreferences();
|
||||
PreparedExpression pe = null;
|
||||
try {
|
||||
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()) {
|
||||
final String stringResult = o.getFromProcessor().process(result);
|
||||
bus.post(new CalculationFinishedEvent(o, e, sequence, result, stringResult, collectMessages(mr)));
|
||||
|
||||
} catch (JsclArithmeticException exception) {
|
||||
if (o == JsclOperation.numeric && exception.getCause() instanceof NumeralBaseException) {
|
||||
evaluateAsync(sequence, JsclOperation.simplify, e, mr);
|
||||
} else {
|
||||
bus.post(new CalculationFailedEvent(o, e, sequence, exception));
|
||||
}
|
||||
}
|
||||
} 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<Message> collectMessages(@Nonnull MessageRegistry mr) {
|
||||
if (mr.hasMessage()) {
|
||||
try {
|
||||
final List<Message> messages = new ArrayList<>();
|
||||
while (messageRegistry.hasMessage()) {
|
||||
messages.add(messageRegistry.getMessage());
|
||||
while (mr.hasMessage()) {
|
||||
messages.add(mr.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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
bus.post(new CalculationFailedEvent(operation, expression, sequence, e));
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private void checkPreferredPreferences() {
|
||||
@ -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,
|
||||
private void onException(long sequence,
|
||||
@Nonnull JsclOperation operation,
|
||||
@Nonnull String expression,
|
||||
@Nullable MessageRegistry mr,
|
||||
@Nullable PreparedExpression preparedExpression,
|
||||
@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<Message>) 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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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> keyboard;
|
||||
@Inject
|
||||
Lazy<Clipboard> 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
|
||||
|
@ -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
|
||||
|
@ -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<EditorState> CREATOR = new Creator<EditorState>() {
|
||||
@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;
|
||||
|
@ -31,48 +31,43 @@ import java.util.List;
|
||||
public class PreparedExpression implements CharSequence {
|
||||
|
||||
@Nonnull
|
||||
private String expression;
|
||||
public final String value;
|
||||
|
||||
@Nonnull
|
||||
private List<IConstant> undefinedVars;
|
||||
public final List<IConstant> undefinedVariables;
|
||||
|
||||
public PreparedExpression(@Nonnull String expression, @Nonnull List<IConstant> undefinedVars) {
|
||||
this.expression = expression;
|
||||
this.undefinedVars = undefinedVars;
|
||||
public PreparedExpression(@Nonnull String value, @Nonnull List<IConstant> 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<IConstant> 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;
|
||||
}
|
||||
}
|
||||
|
@ -52,9 +52,6 @@ import java.util.Map;
|
||||
@Singleton
|
||||
public class VariablesRegistry extends BaseEntitiesRegistry<IConstant> {
|
||||
|
||||
@Nonnull
|
||||
public static final String ANS = "ans";
|
||||
|
||||
@Nonnull
|
||||
private static final Map<String, String> substitutes = new HashMap<>();
|
||||
|
||||
|
@ -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<Message> 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<Message> messages) {
|
||||
super(operation, expression, sequence);
|
||||
this.result = result;
|
||||
this.stringResult = stringResult;
|
||||
this.messages = messages;
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -61,9 +61,8 @@ public class VariablesFragment extends BaseEntitiesFragment<IConstant> {
|
||||
|
||||
public static boolean isValidValue(@Nonnull String value) {
|
||||
try {
|
||||
final PreparedExpression expression = ToJsclTextProcessor.getInstance().process(value);
|
||||
final List<IConstant> variables = expression.getUndefinedVars();
|
||||
return variables.isEmpty();
|
||||
final PreparedExpression pe = ToJsclTextProcessor.getInstance().process(value);
|
||||
return !pe.hasUndefinedVariables();
|
||||
} catch (RuntimeException e) {
|
||||
return false;
|
||||
}
|
||||
|
@ -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())));
|
||||
|
@ -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"));
|
||||
|
@ -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<String, String> converter) throws jscl.text.ParseException, EvalException, ParseException {
|
||||
public static void testExpression(@Nonnull String[] line, @Nonnull Converter<String, String> 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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,20 +167,17 @@ 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<IConstant>() {
|
||||
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<IConstant>() {
|
||||
public boolean apply(@Nonnull IConstant constant) {
|
||||
if (!localValue.equals(constant.getDoubleValue())) {
|
||||
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;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user