Substitute calculator events with Otto bus events
This commit is contained in:
parent
9c5652def0
commit
8c56dd1083
@ -124,6 +124,8 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
|
|||||||
@Inject
|
@Inject
|
||||||
Keyboard keyboard;
|
Keyboard keyboard;
|
||||||
@Inject
|
@Inject
|
||||||
|
Calculator calculator;
|
||||||
|
@Inject
|
||||||
PreferredPreferences preferredPreferences;
|
PreferredPreferences preferredPreferences;
|
||||||
|
|
||||||
protected void onCreate(@Nonnull Activity activity) {
|
protected void onCreate(@Nonnull Activity activity) {
|
||||||
@ -205,7 +207,7 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
|
|||||||
|
|
||||||
final DragButton equalsButton = getButton(views, R.id.cpp_button_equals);
|
final DragButton equalsButton = getButton(views, R.id.cpp_button_equals);
|
||||||
if (equalsButton != null) {
|
if (equalsButton != null) {
|
||||||
equalsButton.setOnDragListener(newDragListener(new EqualsDragProcessor(), activity));
|
equalsButton.setOnDragListener(newDragListener(new EqualsDragProcessor(calculator), activity));
|
||||||
}
|
}
|
||||||
|
|
||||||
angleUnitsButton = getButton(views, R.id.cpp_button_6);
|
angleUnitsButton = getButton(views, R.id.cpp_button_6);
|
||||||
|
@ -28,13 +28,16 @@ import android.text.TextUtils;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.squareup.otto.Bus;
|
import com.squareup.otto.Bus;
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
import jscl.AbstractJsclArithmeticException;
|
import jscl.JsclArithmeticException;
|
||||||
import jscl.MathEngine;
|
import jscl.MathEngine;
|
||||||
import jscl.NumeralBase;
|
import jscl.NumeralBase;
|
||||||
import jscl.NumeralBaseException;
|
import jscl.NumeralBaseException;
|
||||||
import jscl.math.Generic;
|
import jscl.math.Generic;
|
||||||
import jscl.math.function.IConstant;
|
import jscl.math.function.IConstant;
|
||||||
import jscl.text.ParseInterruptedException;
|
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.errors.FixableErrorsActivity;
|
||||||
import org.solovyev.android.calculator.functions.FunctionsRegistry;
|
import org.solovyev.android.calculator.functions.FunctionsRegistry;
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
@ -56,46 +59,46 @@ import javax.inject.Singleton;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class Calculator implements CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
public class Calculator implements CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
// one minute
|
private static final long PREFERENCE_CHECK_INTERVAL = TimeUnit.MINUTES.toMillis(15);
|
||||||
private static final long PREFERENCE_CHECK_INTERVAL = 1000L * 60L;
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer();
|
private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer();
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final AtomicLong counter = new AtomicLong(CalculatorUtils.FIRST_ID);
|
private final AtomicLong counter = new AtomicLong(CalculatorUtils.FIRST_ID);
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final ToJsclTextProcessor preprocessor = ToJsclTextProcessor.getInstance();
|
private final ToJsclTextProcessor preprocessor = ToJsclTextProcessor.getInstance();
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private final Executor calculationsExecutor = Executors.newFixedThreadPool(10);
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final SharedPreferences preferences;
|
private final SharedPreferences preferences;
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final Executor eventExecutor;
|
private final Bus bus;
|
||||||
|
@Nonnull
|
||||||
|
private final Executor ui;
|
||||||
|
@Nonnull
|
||||||
|
private final Executor background;
|
||||||
|
|
||||||
private volatile boolean calculateOnFly = true;
|
private volatile boolean calculateOnFly = true;
|
||||||
|
|
||||||
private volatile long lastPreferenceCheck = 0L;
|
private long lastPreferredPreferenceCheck = 0L;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
PreferredPreferences preferredPreferences;
|
PreferredPreferences preferredPreferences;
|
||||||
|
@Inject
|
||||||
|
Editor editor;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public Calculator(@Nonnull SharedPreferences preferences, @Nonnull Bus bus, @Named(AppModule.THREAD_UI) @Nonnull Executor eventExecutor) {
|
public Calculator(@Nonnull SharedPreferences preferences, @Nonnull Bus bus, @Named(AppModule.THREAD_UI) @Nonnull Executor ui, @Named(AppModule.THREAD_BACKGROUND) @Nonnull Executor background) {
|
||||||
this.preferences = preferences;
|
this.preferences = preferences;
|
||||||
this.eventExecutor = eventExecutor;
|
this.bus = bus;
|
||||||
|
this.ui = ui;
|
||||||
|
this.background = background;
|
||||||
bus.register(this);
|
bus.register(this);
|
||||||
addCalculatorEventListener(this);
|
addCalculatorEventListener(this);
|
||||||
|
|
||||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,15 +147,15 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void evaluate() {
|
public void evaluate() {
|
||||||
final EditorState viewState = getEditor().getState();
|
final EditorState state = editor.getState();
|
||||||
final CalculatorEventData eventData = fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState);
|
final CalculatorEventData eventData = fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, state);
|
||||||
this.evaluate(JsclOperation.numeric, viewState.getTextString(), eventData.getSequenceId());
|
evaluate(JsclOperation.numeric, state.getTextString(), eventData.getSequenceId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void simplify() {
|
public void simplify() {
|
||||||
final EditorState viewState = getEditor().getState();
|
final EditorState state = editor.getState();
|
||||||
final CalculatorEventData eventData = fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState);
|
final CalculatorEventData eventData = fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, state);
|
||||||
this.evaluate(JsclOperation.simplify, viewState.getTextString(), eventData.getSequenceId());
|
evaluate(JsclOperation.simplify, state.getTextString(), eventData.getSequenceId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -161,10 +164,10 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
|
|||||||
|
|
||||||
final CalculatorEventData eventDataId = nextEventData();
|
final CalculatorEventData eventDataId = nextEventData();
|
||||||
|
|
||||||
calculationsExecutor.execute(new Runnable() {
|
background.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Calculator.this.evaluate(eventDataId.getSequenceId(), operation, expression, null);
|
Calculator.this.evaluateAsync(eventDataId.getSequenceId(), operation, expression, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -175,18 +178,18 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
|
|||||||
public CalculatorEventData evaluate(@Nonnull final JsclOperation operation, @Nonnull final String expression, long sequenceId) {
|
public CalculatorEventData evaluate(@Nonnull final JsclOperation operation, @Nonnull final String expression, long sequenceId) {
|
||||||
final CalculatorEventData eventDataId = nextEventData(sequenceId);
|
final CalculatorEventData eventDataId = nextEventData(sequenceId);
|
||||||
|
|
||||||
calculationsExecutor.execute(new Runnable() {
|
background.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Calculator.this.evaluate(eventDataId.getSequenceId(), operation, expression, null);
|
evaluateAsync(eventDataId.getSequenceId(), operation, expression, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return eventDataId;
|
return eventDataId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(@Nonnull Executor initThread) {
|
public void init(@Nonnull Executor init) {
|
||||||
Locator.getInstance().getEngine().init(initThread);
|
Locator.getInstance().getEngine().init(init);
|
||||||
setCalculateOnFly(Preferences.Calculations.calculateOnFly.getPreference(preferences));
|
setCalculateOnFly(Preferences.Calculations.calculateOnFly.getPreference(preferences));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,86 +215,88 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
|
|||||||
return CalculatorConversionEventDataImpl.newInstance(nextEventData(sequenceId), value, from, to, displayViewState);
|
return CalculatorConversionEventDataImpl.newInstance(nextEventData(sequenceId), value, from, to, displayViewState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void evaluate(@Nonnull Long sequenceId,
|
private void evaluateAsync(long sequence,
|
||||||
@Nonnull JsclOperation operation,
|
@Nonnull JsclOperation operation,
|
||||||
@Nonnull String expression,
|
@Nonnull String expression,
|
||||||
@Nullable MessageRegistry mr) {
|
@Nullable MessageRegistry mr) {
|
||||||
|
|
||||||
checkPreferredPreferences();
|
checkPreferredPreferences();
|
||||||
|
expression = expression.trim();
|
||||||
|
|
||||||
PreparedExpression preparedExpression = null;
|
PreparedExpression preparedExpression = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
expression = expression.trim();
|
|
||||||
|
|
||||||
if (Strings.isEmpty(expression)) {
|
if (Strings.isEmpty(expression)) {
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, CalculatorOutputImpl.newEmptyOutput(operation));
|
bus.post(new CalculationFinishedEvent(operation, expression, sequence));
|
||||||
} else {
|
return;
|
||||||
preparedExpression = prepareExpression(expression);
|
}
|
||||||
|
preparedExpression = prepareExpression(expression);
|
||||||
|
|
||||||
final String jsclExpression = preparedExpression.toString();
|
final String jsclExpression = preparedExpression.toString();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
final MathEngine mathEngine = Locator.getInstance().getEngine().getMathEngine();
|
||||||
|
|
||||||
final MathEngine mathEngine = Locator.getInstance().getEngine().getMathEngine();
|
final MessageRegistry messageRegistry = new ListMessageRegistry();
|
||||||
|
Locator.getInstance().getEngine().getMathEngine().setMessageRegistry(messageRegistry);
|
||||||
|
|
||||||
final MessageRegistry messageRegistry = new ListMessageRegistry();
|
final Generic result = operation.evaluateGeneric(jsclExpression, mathEngine);
|
||||||
Locator.getInstance().getEngine().getMathEngine().setMessageRegistry(messageRegistry);
|
|
||||||
|
|
||||||
final Generic result = operation.evaluateGeneric(jsclExpression, mathEngine);
|
// NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!)
|
||||||
|
result.toString();
|
||||||
|
|
||||||
// NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!)
|
if (messageRegistry.hasMessage()) {
|
||||||
result.toString();
|
try {
|
||||||
|
final List<Message> messages = new ArrayList<>();
|
||||||
if (messageRegistry.hasMessage()) {
|
while (messageRegistry.hasMessage()) {
|
||||||
try {
|
messages.add(messageRegistry.getMessage());
|
||||||
final List<Message> messages = new ArrayList<Message>();
|
|
||||||
while (messageRegistry.hasMessage()) {
|
|
||||||
messages.add(messageRegistry.getMessage());
|
|
||||||
}
|
|
||||||
if (!messages.isEmpty()) {
|
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_messages, messages);
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
// todo serso: not good but we need proper synchronization
|
|
||||||
Log.e("Calculator", e.getMessage(), e);
|
|
||||||
}
|
}
|
||||||
|
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 CalculatorOutput data = CalculatorOutputImpl.newOutput(operation.getFromProcessor().process(result), operation, result);
|
final String stringResult = operation.getFromProcessor().process(result);
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, data);
|
bus.post(new CalculationFinishedEvent(operation, expression, sequence, result, stringResult));
|
||||||
|
|
||||||
} catch (AbstractJsclArithmeticException e) {
|
} catch (JsclArithmeticException e) {
|
||||||
handleException(sequenceId, operation, expression, mr, new CalculatorEvalException(e, e, jsclExpression));
|
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) {
|
} catch (ArithmeticException e) {
|
||||||
handleException(sequenceId, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage())));
|
handleException(sequence, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage())));
|
||||||
} catch (StackOverflowError e) {
|
} catch (StackOverflowError e) {
|
||||||
handleException(sequenceId, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error)));
|
handleException(sequence, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error)));
|
||||||
} catch (jscl.text.ParseException e) {
|
} catch (jscl.text.ParseException e) {
|
||||||
handleException(sequenceId, operation, expression, mr, preparedExpression, new ParseException(e));
|
handleException(sequence, operation, expression, mr, preparedExpression, new ParseException(e));
|
||||||
} catch (ParseInterruptedException e) {
|
} catch (ParseInterruptedException e) {
|
||||||
|
bus.post(new CalculationCancelledEvent(operation, expression, sequence));
|
||||||
// do nothing - we ourselves interrupt the calculations
|
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_cancelled, null);
|
|
||||||
|
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
handleException(sequenceId, operation, expression, mr, preparedExpression, e);
|
handleException(sequence, operation, expression, mr, preparedExpression, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkPreferredPreferences() {
|
private void checkPreferredPreferences() {
|
||||||
final long currentTime = System.currentTimeMillis();
|
if (shouldCheckPreferredPreferences()) {
|
||||||
|
|
||||||
if (currentTime - lastPreferenceCheck > PREFERENCE_CHECK_INTERVAL) {
|
|
||||||
lastPreferenceCheck = currentTime;
|
|
||||||
preferredPreferences.check(false);
|
preferredPreferences.check(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized boolean shouldCheckPreferredPreferences() {
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
if (now - lastPreferredPreferenceCheck > PREFERENCE_CHECK_INTERVAL) {
|
||||||
|
lastPreferredPreferenceCheck = now;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public PreparedExpression prepareExpression(@Nonnull String expression) throws ParseException {
|
public PreparedExpression prepareExpression(@Nonnull String expression) throws ParseException {
|
||||||
return preprocessor.process(expression);
|
return preprocessor.process(expression);
|
||||||
@ -304,34 +309,18 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
|
|||||||
return new CalculatorEvaluationEventDataImpl(nextEventData(calculationId), operation, expression);
|
return new CalculatorEvaluationEventDataImpl(nextEventData(calculationId), operation, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleException(@Nonnull Long sequenceId,
|
private void handleException(long sequence,
|
||||||
@Nonnull JsclOperation operation,
|
@Nonnull JsclOperation operation,
|
||||||
@Nonnull String expression,
|
@Nonnull String expression,
|
||||||
@Nullable MessageRegistry mr,
|
@Nullable MessageRegistry mr,
|
||||||
@Nullable PreparedExpression preparedExpression,
|
@Nullable PreparedExpression preparedExpression,
|
||||||
@Nonnull ParseException parseException) {
|
@Nonnull ParseException parseException) {
|
||||||
|
|
||||||
if (operation == JsclOperation.numeric
|
if (operation == JsclOperation.numeric
|
||||||
&& preparedExpression != null
|
&& preparedExpression != null
|
||||||
&& preparedExpression.isExistsUndefinedVar()) {
|
&& preparedExpression.isExistsUndefinedVar()) {
|
||||||
|
evaluateAsync(sequence, JsclOperation.simplify, expression, mr);
|
||||||
evaluate(sequenceId, JsclOperation.simplify, expression, mr);
|
|
||||||
} else {
|
} else {
|
||||||
|
bus.post(new CalculationFailedEvent(operation, expression, sequence, parseException));
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(parseException));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleException(@Nonnull Long calculationId,
|
|
||||||
@Nonnull JsclOperation operation,
|
|
||||||
@Nonnull String expression,
|
|
||||||
@Nullable MessageRegistry mr,
|
|
||||||
@Nonnull CalculatorEvalException evalException) {
|
|
||||||
|
|
||||||
if (operation == JsclOperation.numeric && evalException.getCause() instanceof NumeralBaseException) {
|
|
||||||
evaluate(calculationId, JsclOperation.simplify, expression, mr);
|
|
||||||
} else {
|
|
||||||
fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(evalException));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,7 +332,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
|
|||||||
final DisplayState displayViewState = App.getDisplay().getState();
|
final DisplayState displayViewState = App.getDisplay().getState();
|
||||||
final NumeralBase from = Locator.getInstance().getEngine().getMathEngine().getNumeralBase();
|
final NumeralBase from = Locator.getInstance().getEngine().getMathEngine().getNumeralBase();
|
||||||
|
|
||||||
calculationsExecutor.execute(new Runnable() {
|
background.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final Long sequenceId = eventDataId.getSequenceId();
|
final Long sequenceId = eventDataId.getSequenceId();
|
||||||
@ -382,7 +371,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void fireCalculatorEvent(@Nonnull final CalculatorEventData calculatorEventData, @Nonnull final CalculatorEventType calculatorEventType, @Nullable final Object data) {
|
public void fireCalculatorEvent(@Nonnull final CalculatorEventData calculatorEventData, @Nonnull final CalculatorEventType calculatorEventType, @Nullable final Object data) {
|
||||||
eventExecutor.execute(new Runnable() {
|
ui.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
calculatorEventContainer.fireCalculatorEvent(calculatorEventData, calculatorEventType, data);
|
calculatorEventContainer.fireCalculatorEvent(calculatorEventData, calculatorEventType, data);
|
||||||
@ -476,11 +465,6 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private Editor getEditor() {
|
|
||||||
return App.getEditor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
|
||||||
switch (calculatorEventType) {
|
switch (calculatorEventType) {
|
||||||
@ -535,4 +519,5 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
|
|||||||
setCalculateOnFly(Preferences.Calculations.calculateOnFly.getPreference(prefs));
|
setCalculateOnFly(Preferences.Calculations.calculateOnFly.getPreference(prefs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 serso aka se.solovyev
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
* Contact details
|
|
||||||
*
|
|
||||||
* Email: se.solovyev@gmail.com
|
|
||||||
* Site: http://se.solovyev.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.solovyev.android.calculator;
|
|
||||||
|
|
||||||
import org.solovyev.common.msg.Message;
|
|
||||||
import org.solovyev.common.msg.MessageLevel;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User: serso
|
|
||||||
* Date: 12/8/11
|
|
||||||
* Time: 1:27 AM
|
|
||||||
*/
|
|
||||||
public class CalculatorEvalException extends Exception implements Message {
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private final Message message;
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private final String expression;
|
|
||||||
|
|
||||||
public CalculatorEvalException(@Nonnull Message message, @Nonnull Throwable cause, String expression) {
|
|
||||||
super(cause);
|
|
||||||
this.message = message;
|
|
||||||
this.expression = expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public String getExpression() {
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public String getMessageCode() {
|
|
||||||
return this.message.getMessageCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public List<Object> getParameters() {
|
|
||||||
return this.message.getParameters();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public MessageLevel getMessageLevel() {
|
|
||||||
return this.message.getMessageLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nonnull
|
|
||||||
public String getLocalizedMessage() {
|
|
||||||
return this.message.getLocalizedMessage(Locale.getDefault());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public String getLocalizedMessage(@Nonnull Locale locale) {
|
|
||||||
return this.message.getLocalizedMessage(locale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -44,11 +44,6 @@ public enum CalculatorEventType {
|
|||||||
// @Nonnull CalculatorEditorViewState
|
// @Nonnull CalculatorEditorViewState
|
||||||
manual_calculation_requested,
|
manual_calculation_requested,
|
||||||
|
|
||||||
// @Nonnull org.solovyev.android.calculator.CalculatorOutput
|
|
||||||
calculation_result,
|
|
||||||
|
|
||||||
calculation_cancelled,
|
|
||||||
|
|
||||||
// @Nonnull org.solovyev.android.calculator.CalculatorFailure
|
// @Nonnull org.solovyev.android.calculator.CalculatorFailure
|
||||||
calculation_failed,
|
calculation_failed,
|
||||||
|
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 serso aka se.solovyev
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
* Contact details
|
|
||||||
*
|
|
||||||
* Email: se.solovyev@gmail.com
|
|
||||||
* Site: http://se.solovyev.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.solovyev.android.calculator;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User: serso
|
|
||||||
* Date: 9/20/12
|
|
||||||
* Time: 7:33 PM
|
|
||||||
*/
|
|
||||||
public interface CalculatorFailure {
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
Exception getException();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
ParseException getCalculationParseException();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
CalculatorEvalException getCalculationEvalException();
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 serso aka se.solovyev
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
* Contact details
|
|
||||||
*
|
|
||||||
* Email: se.solovyev@gmail.com
|
|
||||||
* Site: http://se.solovyev.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.solovyev.android.calculator;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User: serso
|
|
||||||
* Date: 9/20/12
|
|
||||||
* Time: 7:34 PM
|
|
||||||
*/
|
|
||||||
public class CalculatorFailureImpl implements CalculatorFailure {
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private Exception exception;
|
|
||||||
|
|
||||||
public CalculatorFailureImpl(@Nonnull Exception exception) {
|
|
||||||
this.exception = exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Exception getException() {
|
|
||||||
return this.exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ParseException getCalculationParseException() {
|
|
||||||
return exception instanceof ParseException ? (ParseException) exception : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CalculatorEvalException getCalculationEvalException() {
|
|
||||||
return exception instanceof CalculatorEvalException ? (CalculatorEvalException) exception : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "CalculatorFailureImpl{" +
|
|
||||||
"exception=" + exception +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 serso aka se.solovyev
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
* Contact details
|
|
||||||
*
|
|
||||||
* Email: se.solovyev@gmail.com
|
|
||||||
* Site: http://se.solovyev.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.solovyev.android.calculator;
|
|
||||||
|
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import jscl.math.Generic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User: serso
|
|
||||||
* Date: 9/20/12
|
|
||||||
* Time: 7:29 PM
|
|
||||||
*/
|
|
||||||
public interface CalculatorOutput {
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
String getStringResult();
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
JsclOperation getOperation();
|
|
||||||
|
|
||||||
|
|
||||||
// null in case of empty expression
|
|
||||||
@Nullable
|
|
||||||
Generic getResult();
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 serso aka se.solovyev
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
* Contact details
|
|
||||||
*
|
|
||||||
* Email: se.solovyev@gmail.com
|
|
||||||
* Site: http://se.solovyev.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.solovyev.android.calculator;
|
|
||||||
|
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import jscl.math.Generic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User: serso
|
|
||||||
* Date: 9/20/12
|
|
||||||
* Time: 7:28 PM
|
|
||||||
*/
|
|
||||||
public class CalculatorOutputImpl implements CalculatorOutput {
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private Generic result;
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private String stringResult;
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private JsclOperation operation;
|
|
||||||
|
|
||||||
private CalculatorOutputImpl(@Nonnull String stringResult,
|
|
||||||
@Nonnull JsclOperation operation,
|
|
||||||
@Nullable Generic result) {
|
|
||||||
this.stringResult = stringResult;
|
|
||||||
this.operation = operation;
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public static CalculatorOutput newOutput(@Nonnull String stringResult,
|
|
||||||
@Nonnull JsclOperation operation,
|
|
||||||
@Nonnull Generic result) {
|
|
||||||
return new CalculatorOutputImpl(stringResult, operation, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public static CalculatorOutput newEmptyOutput(@Nonnull JsclOperation operation) {
|
|
||||||
return new CalculatorOutputImpl("", operation, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nonnull
|
|
||||||
public String getStringResult() {
|
|
||||||
return stringResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nonnull
|
|
||||||
public JsclOperation getOperation() {
|
|
||||||
return operation;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Generic getResult() {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -30,6 +30,9 @@ import com.squareup.otto.Subscribe;
|
|||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
import jscl.math.Generic;
|
import jscl.math.Generic;
|
||||||
import org.solovyev.android.Check;
|
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.jscl.JsclOperation;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
import org.solovyev.android.calculator.view.NumeralBaseConverterDialog;
|
import org.solovyev.android.calculator.view.NumeralBaseConverterDialog;
|
||||||
|
|
||||||
@ -39,7 +42,8 @@ import javax.inject.Inject;
|
|||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import static org.solovyev.android.calculator.BaseFragment.addMenu;
|
import static org.solovyev.android.calculator.BaseFragment.addMenu;
|
||||||
import static org.solovyev.android.calculator.CalculatorEventType.*;
|
import static org.solovyev.android.calculator.CalculatorEventType.conversion_failed;
|
||||||
|
import static org.solovyev.android.calculator.CalculatorEventType.conversion_result;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class Display implements CalculatorEventListener, View.OnClickListener, View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
|
public class Display implements CalculatorEventListener, View.OnClickListener, View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
|
||||||
@ -76,6 +80,31 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V
|
|||||||
notifier.get().showMessage(CalculatorMessage.newInfoMessage(CalculatorMessages.result_copied));
|
notifier.get().showMessage(CalculatorMessage.newInfoMessage(CalculatorMessages.result_copied));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onCalculationFinished(@Nonnull CalculationFinishedEvent e) {
|
||||||
|
if (e.sequence < state.sequence) return;
|
||||||
|
setState(DisplayState.createValid(e.operation, e.result, e.stringResult, e.sequence));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onCalculationCancelled(@Nonnull CalculationCancelledEvent e) {
|
||||||
|
if (e.sequence < state.sequence) return;
|
||||||
|
final String error = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
||||||
|
setState(DisplayState.createError(e.operation, error, e.sequence));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onCalculationFailed(@Nonnull CalculationFailedEvent e) {
|
||||||
|
if (e.sequence < state.sequence) return;
|
||||||
|
final String error;
|
||||||
|
if (e.exception instanceof ParseException) {
|
||||||
|
error = e.exception.getLocalizedMessage();
|
||||||
|
} else {
|
||||||
|
error = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
||||||
|
}
|
||||||
|
setState(DisplayState.createError(e.operation, error, e.sequence));
|
||||||
|
}
|
||||||
|
|
||||||
public void clearView(@Nonnull DisplayView view) {
|
public void clearView(@Nonnull DisplayView view) {
|
||||||
Check.isMainThread();
|
Check.isMainThread();
|
||||||
if (this.view != view) {
|
if (this.view != view) {
|
||||||
@ -112,67 +141,28 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V
|
|||||||
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData,
|
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData,
|
||||||
@Nonnull CalculatorEventType calculatorEventType,
|
@Nonnull CalculatorEventType calculatorEventType,
|
||||||
@Nullable Object data) {
|
@Nullable Object data) {
|
||||||
if (calculatorEventType.isOfType(calculation_result, calculation_failed, calculation_cancelled, conversion_result, conversion_failed)) {
|
if (calculatorEventType.isOfType(conversion_result, conversion_failed)) {
|
||||||
|
|
||||||
final CalculatorEventHolder.Result result = lastEvent.apply(calculatorEventData);
|
final CalculatorEventHolder.Result result = lastEvent.apply(calculatorEventData);
|
||||||
|
|
||||||
if (result.isNewAfter()) {
|
if (result.isNewAfter()) {
|
||||||
switch (calculatorEventType) {
|
switch (calculatorEventType) {
|
||||||
case conversion_failed:
|
case conversion_failed:
|
||||||
processConversationFailed((CalculatorConversionEventData) calculatorEventData, (ConversionFailure) data);
|
processConversationFailed((CalculatorConversionEventData) calculatorEventData);
|
||||||
break;
|
break;
|
||||||
case conversion_result:
|
case conversion_result:
|
||||||
processConversationResult((CalculatorConversionEventData) calculatorEventData, (String) data);
|
processConversationResult((CalculatorConversionEventData) calculatorEventData, (String) data);
|
||||||
break;
|
break;
|
||||||
case calculation_result:
|
|
||||||
processCalculationResult((CalculatorEvaluationEventData) calculatorEventData, (CalculatorOutput) data);
|
|
||||||
break;
|
|
||||||
case calculation_cancelled:
|
|
||||||
processCalculationCancelled((CalculatorEvaluationEventData) calculatorEventData);
|
|
||||||
break;
|
|
||||||
case calculation_failed:
|
|
||||||
processCalculationFailed((CalculatorEvaluationEventData) calculatorEventData, (CalculatorFailure) data);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processConversationFailed(@Nonnull CalculatorConversionEventData calculatorEventData,
|
private void processConversationFailed(@Nonnull CalculatorConversionEventData calculatorEventData) {
|
||||||
@Nonnull ConversionFailure data) {
|
|
||||||
setState(DisplayState.createError(calculatorEventData.getDisplayState().getOperation(), CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error), calculatorEventData.getSequenceId()));
|
setState(DisplayState.createError(calculatorEventData.getDisplayState().getOperation(), CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error), calculatorEventData.getSequenceId()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processCalculationFailed(@Nonnull CalculatorEvaluationEventData calculatorEventData, @Nonnull CalculatorFailure data) {
|
|
||||||
|
|
||||||
final CalculatorEvalException calculatorEvalException = data.getCalculationEvalException();
|
|
||||||
|
|
||||||
final String errorMessage;
|
|
||||||
if (calculatorEvalException != null) {
|
|
||||||
errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
|
||||||
} else {
|
|
||||||
final ParseException calculationParseException = data.getCalculationParseException();
|
|
||||||
if (calculationParseException != null) {
|
|
||||||
errorMessage = calculationParseException.getLocalizedMessage();
|
|
||||||
} else {
|
|
||||||
errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setState(DisplayState.createError(calculatorEventData.getOperation(), errorMessage, calculatorEventData.getSequenceId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processCalculationCancelled(@Nonnull CalculatorEvaluationEventData calculatorEventData) {
|
|
||||||
final String errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
|
|
||||||
setState(DisplayState.createError(calculatorEventData.getOperation(), errorMessage, calculatorEventData.getSequenceId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processCalculationResult(@Nonnull CalculatorEvaluationEventData calculatorEventData, @Nonnull CalculatorOutput data) {
|
|
||||||
final String stringResult = data.getStringResult();
|
|
||||||
setState(DisplayState.createValid(calculatorEventData.getOperation(), data.getResult(), stringResult, calculatorEventData.getSequenceId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processConversationResult(@Nonnull CalculatorConversionEventData calculatorEventData, @Nonnull String result) {
|
private void processConversationResult(@Nonnull CalculatorConversionEventData calculatorEventData, @Nonnull String result) {
|
||||||
// add prefix
|
// add prefix
|
||||||
if (calculatorEventData.getFromNumeralBase() != calculatorEventData.getToNumeralBase()) {
|
if (calculatorEventData.getFromNumeralBase() != calculatorEventData.getToNumeralBase()) {
|
||||||
|
@ -34,6 +34,13 @@ import javax.annotation.Nonnull;
|
|||||||
|
|
||||||
public class EqualsDragProcessor implements SimpleDragListener.DragProcessor {
|
public class EqualsDragProcessor implements SimpleDragListener.DragProcessor {
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private final Calculator calculator;
|
||||||
|
|
||||||
|
public EqualsDragProcessor(@Nonnull Calculator calculator) {
|
||||||
|
this.calculator = calculator;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) {
|
public boolean processDragEvent(@Nonnull DragDirection direction, @Nonnull DragButton button, @Nonnull PointF startPoint, @Nonnull MotionEvent motionEvent) {
|
||||||
if (direction == DragDirection.down) {
|
if (direction == DragDirection.down) {
|
||||||
@ -42,7 +49,7 @@ public class EqualsDragProcessor implements SimpleDragListener.DragProcessor {
|
|||||||
} else if (button instanceof DirectionDragButton) {
|
} else if (button instanceof DirectionDragButton) {
|
||||||
final String text = ((DirectionDragButton) button).getText(direction);
|
final String text = ((DirectionDragButton) button).getText(direction);
|
||||||
if ("≡".equals(text)) {
|
if ("≡".equals(text)) {
|
||||||
Locator.getInstance().getCalculator().simplify();
|
calculator.simplify();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package org.solovyev.android.calculator.calculations;
|
||||||
|
|
||||||
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public abstract class BaseCalculationEvent {
|
||||||
|
@Nonnull
|
||||||
|
public final JsclOperation operation;
|
||||||
|
@Nonnull
|
||||||
|
public final String expression;
|
||||||
|
public final long sequence;
|
||||||
|
|
||||||
|
protected BaseCalculationEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence) {
|
||||||
|
this.operation = operation;
|
||||||
|
this.expression = expression;
|
||||||
|
this.sequence = sequence;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package org.solovyev.android.calculator.calculations;
|
||||||
|
|
||||||
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public final class CalculationCancelledEvent extends BaseCalculationEvent {
|
||||||
|
public CalculationCancelledEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence) {
|
||||||
|
super(operation, expression, sequence);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package org.solovyev.android.calculator.calculations;
|
||||||
|
|
||||||
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public final class CalculationFailedEvent extends BaseCalculationEvent {
|
||||||
|
@Nonnull
|
||||||
|
public final Exception exception;
|
||||||
|
|
||||||
|
public CalculationFailedEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence, @Nonnull Exception exception) {
|
||||||
|
super(operation, expression, sequence);
|
||||||
|
this.exception = exception;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package org.solovyev.android.calculator.calculations;
|
||||||
|
|
||||||
|
import jscl.math.Generic;
|
||||||
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public final class CalculationFinishedEvent extends BaseCalculationEvent {
|
||||||
|
@Nullable
|
||||||
|
public final Generic result;
|
||||||
|
@Nonnull
|
||||||
|
public final String stringResult;
|
||||||
|
|
||||||
|
public CalculationFinishedEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence) {
|
||||||
|
super(operation, expression, sequence);
|
||||||
|
result = null;
|
||||||
|
stringResult = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public CalculationFinishedEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence, @Nullable Generic result, @Nonnull String stringResult) {
|
||||||
|
super(operation, expression, sequence);
|
||||||
|
this.result = result;
|
||||||
|
this.stringResult = stringResult;
|
||||||
|
}
|
||||||
|
}
|
@ -24,11 +24,12 @@ package org.solovyev.android.calculator;
|
|||||||
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import com.squareup.otto.Bus;
|
import com.squareup.otto.Bus;
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
* Date: 10/7/12
|
* Date: 10/7/12
|
||||||
@ -37,7 +38,7 @@ import java.util.concurrent.Executor;
|
|||||||
public class AbstractCalculatorTest {
|
public class AbstractCalculatorTest {
|
||||||
|
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
Locator.getInstance().init(new Calculator(Mockito.mock(SharedPreferences.class), Mockito.mock(Bus.class), Mockito.mock(Executor.class)), CalculatorTestUtils.newCalculatorEngine(), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class));
|
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), CalculatorTestUtils.newCalculatorEngine(), mock(Keyboard.class), mock(CalculatorPlotter.class));
|
||||||
Locator.getInstance().getEngine().init(new Executor() {
|
Locator.getInstance().getEngine().init(new Executor() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(Runnable command) {
|
public void execute(Runnable command) {
|
||||||
|
@ -59,7 +59,7 @@ public class CalculatorTestUtils {
|
|||||||
|
|
||||||
public static void staticSetUp() throws Exception {
|
public static void staticSetUp() throws Exception {
|
||||||
App.init(new CalculatorApplication(), new Languages(new RoboSharedPreferences(new HashMap<String, Map<String, Object>>(), "test", 0)));
|
App.init(new CalculatorApplication(), new Languages(new RoboSharedPreferences(new HashMap<String, Map<String, Object>>(), "test", 0)));
|
||||||
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class)), newCalculatorEngine(), mock(Keyboard.class), mock(CalculatorPlotter.class));
|
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), newCalculatorEngine(), mock(Keyboard.class), mock(CalculatorPlotter.class));
|
||||||
Locator.getInstance().getEngine().init(new Executor() {
|
Locator.getInstance().getEngine().init(new Executor() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(Runnable command) {
|
public void execute(Runnable command) {
|
||||||
@ -74,7 +74,7 @@ public class CalculatorTestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void staticSetUp(@Nullable Context context) throws Exception {
|
public static void staticSetUp(@Nullable Context context) throws Exception {
|
||||||
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class)), newCalculatorEngine(), mock(Keyboard.class), mock(CalculatorPlotter.class));
|
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), newCalculatorEngine(), mock(Keyboard.class), mock(CalculatorPlotter.class));
|
||||||
Locator.getInstance().getEngine().init(new Executor() {
|
Locator.getInstance().getEngine().init(new Executor() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(Runnable command) {
|
public void execute(Runnable command) {
|
||||||
|
@ -33,7 +33,6 @@ import junit.framework.Assert;
|
|||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.solovyev.android.calculator.AbstractCalculatorTest;
|
import org.solovyev.android.calculator.AbstractCalculatorTest;
|
||||||
import org.solovyev.android.calculator.CalculatorEvalException;
|
|
||||||
import org.solovyev.android.calculator.CalculatorTestUtils;
|
import org.solovyev.android.calculator.CalculatorTestUtils;
|
||||||
import org.solovyev.android.calculator.Locator;
|
import org.solovyev.android.calculator.Locator;
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
@ -91,7 +90,7 @@ public class AndroidEngineTest extends AbstractCalculatorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testI() throws ParseException, CalculatorEvalException {
|
public void testI() throws ParseException, EvalException {
|
||||||
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine();
|
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine();
|
||||||
|
|
||||||
CalculatorTestUtils.assertEval("-i", cm.evaluate("i^3"));
|
CalculatorTestUtils.assertEval("-i", cm.evaluate("i^3"));
|
||||||
|
@ -26,7 +26,6 @@ import org.junit.Assert;
|
|||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.solovyev.android.calculator.AbstractCalculatorTest;
|
import org.solovyev.android.calculator.AbstractCalculatorTest;
|
||||||
import org.solovyev.android.calculator.CalculatorEvalException;
|
|
||||||
import org.solovyev.android.calculator.ParseException;
|
import org.solovyev.android.calculator.ParseException;
|
||||||
import org.solovyev.android.calculator.CalculatorTestUtils;
|
import org.solovyev.android.calculator.CalculatorTestUtils;
|
||||||
import org.solovyev.android.calculator.Locator;
|
import org.solovyev.android.calculator.Locator;
|
||||||
@ -57,7 +56,7 @@ public class NumeralBaseTest extends AbstractCalculatorTest {
|
|||||||
Locator.getInstance().getEngine().getMathEngine().setPrecision(3);
|
Locator.getInstance().getEngine().getMathEngine().setPrecision(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void testExpression(@Nonnull String[] line, @Nonnull Converter<String, String> converter) throws jscl.text.ParseException, CalculatorEvalException, ParseException {
|
public static void testExpression(@Nonnull String[] line, @Nonnull Converter<String, String> converter) throws jscl.text.ParseException, EvalException, ParseException {
|
||||||
final String dec = line[0].toUpperCase();
|
final String dec = line[0].toUpperCase();
|
||||||
final String hex = "0x:" + line[1].toUpperCase();
|
final String hex = "0x:" + line[1].toUpperCase();
|
||||||
final String bin = "0b:" + line[2].toUpperCase();
|
final String bin = "0b:" + line[2].toUpperCase();
|
||||||
|
@ -6,7 +6,7 @@ import org.solovyev.common.msg.Message;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class CustomFunctionCalculationException extends AbstractJsclArithmeticException {
|
public class CustomFunctionCalculationException extends JsclArithmeticException {
|
||||||
|
|
||||||
public CustomFunctionCalculationException(@Nonnull CustomFunction function, @Nonnull Message message) {
|
public CustomFunctionCalculationException(@Nonnull CustomFunction function, @Nonnull Message message) {
|
||||||
super(Messages.msg_19, function.getName(), message);
|
super(Messages.msg_19, function.getName(), message);
|
||||||
|
@ -9,19 +9,15 @@ import javax.annotation.Nonnull;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public abstract class AbstractJsclArithmeticException extends ArithmeticException implements Message {
|
public abstract class JsclArithmeticException extends ArithmeticException implements Message {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final Message message;
|
private final Message message;
|
||||||
|
|
||||||
public AbstractJsclArithmeticException(@Nonnull String messageCode, Object... parameters) {
|
public JsclArithmeticException(@Nonnull String messageCode, Object... parameters) {
|
||||||
this.message = new JsclMessage(messageCode, MessageType.error, parameters);
|
this.message = new JsclMessage(messageCode, MessageType.error, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractJsclArithmeticException(@Nonnull Message message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public String getMessageCode() {
|
public String getMessageCode() {
|
||||||
return this.message.getMessageCode();
|
return this.message.getMessageCode();
|
||||||
@ -53,10 +49,9 @@ public abstract class AbstractJsclArithmeticException extends ArithmeticExceptio
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
AbstractJsclArithmeticException that = (AbstractJsclArithmeticException) o;
|
JsclArithmeticException that = (JsclArithmeticException) o;
|
||||||
|
|
||||||
return message.equals(that.message);
|
return message.equals(that.message);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -2,7 +2,7 @@ package jscl;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class NotSupportedException extends AbstractJsclArithmeticException {
|
public class NotSupportedException extends JsclArithmeticException {
|
||||||
|
|
||||||
public NotSupportedException(@Nonnull String messageCode, Object... parameters) {
|
public NotSupportedException(@Nonnull String messageCode, Object... parameters) {
|
||||||
super(messageCode, parameters);
|
super(messageCode, parameters);
|
||||||
|
@ -4,7 +4,7 @@ import jscl.text.msg.Messages;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class NumeralBaseException extends AbstractJsclArithmeticException {
|
public class NumeralBaseException extends JsclArithmeticException {
|
||||||
|
|
||||||
public NumeralBaseException(@Nonnull Double value) {
|
public NumeralBaseException(@Nonnull Double value) {
|
||||||
super(Messages.msg_17, value);
|
super(Messages.msg_17, value);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package jscl.math;
|
package jscl.math;
|
||||||
|
|
||||||
import jscl.AbstractJsclArithmeticException;
|
import jscl.JsclArithmeticException;
|
||||||
import jscl.text.msg.Messages;
|
import jscl.text.msg.Messages;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class NotIntegrableException extends AbstractJsclArithmeticException {
|
public class NotIntegrableException extends JsclArithmeticException {
|
||||||
|
|
||||||
public NotIntegrableException(@Nonnull String messageCode, Object... parameters) {
|
public NotIntegrableException(@Nonnull String messageCode, Object... parameters) {
|
||||||
super(messageCode, parameters);
|
super(messageCode, parameters);
|
||||||
|
Loading…
Reference in New Issue
Block a user