diff --git a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java b/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java deleted file mode 100644 index e3cffac7..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/AndroidCalculator.java +++ /dev/null @@ -1,210 +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 android.app.Application; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import com.squareup.otto.Bus; -import jscl.NumeralBase; -import jscl.math.Generic; -import org.solovyev.android.calculator.errors.FixableErrorsActivity; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.common.msg.Message; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.List; -import java.util.concurrent.Executor; - -public class AndroidCalculator implements Calculator, CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener { - - @Nonnull - private final CalculatorImpl calculator; - - @Nonnull - private final Application context; - - public AndroidCalculator(@Nonnull Application application, @Nonnull Bus bus, Executor eventExecutor) { - this.context = application; - this.calculator = new CalculatorImpl(bus, eventExecutor); - this.calculator.addCalculatorEventListener(this); - - PreferenceManager.getDefaultSharedPreferences(application).registerOnSharedPreferenceChangeListener(this); - } - - @Override - @Nonnull - public CalculatorEventData evaluate(@Nonnull JsclOperation operation, @Nonnull String expression) { - return calculator.evaluate(operation, expression); - } - - @Override - @Nonnull - public CalculatorEventData evaluate(@Nonnull JsclOperation operation, @Nonnull String expression, long sequenceId) { - return calculator.evaluate(operation, expression, sequenceId); - } - - @Override - public boolean isCalculateOnFly() { - return calculator.isCalculateOnFly(); - } - - @Override - public void setCalculateOnFly(boolean calculateOnFly) { - calculator.setCalculateOnFly(calculateOnFly); - } - - @Override - public boolean isConversionPossible(@Nonnull Generic generic, @Nonnull NumeralBase from, @Nonnull NumeralBase to) { - return calculator.isConversionPossible(generic, from, to); - } - - @Override - @Nonnull - public CalculatorEventData convert(@Nonnull Generic generic, @Nonnull NumeralBase to) { - return calculator.convert(generic, to); - } - - @Override - @Nonnull - public CalculatorEventData fireCalculatorEvent(@Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { - return calculator.fireCalculatorEvent(calculatorEventType, data); - } - - @Nonnull - @Override - public CalculatorEventData fireCalculatorEvent(@Nonnull CalculatorEventType calculatorEventType, @Nullable Object data, @Nonnull Object source) { - return calculator.fireCalculatorEvent(calculatorEventType, data, source); - } - - @Override - @Nonnull - public CalculatorEventData fireCalculatorEvent(@Nonnull CalculatorEventType calculatorEventType, @Nullable Object data, @Nonnull Long sequenceId) { - return calculator.fireCalculatorEvent(calculatorEventType, data, sequenceId); - } - - @Nonnull - @Override - public PreparedExpression prepareExpression(@Nonnull String expression) throws ParseException { - return calculator.prepareExpression(expression); - } - - @Override - public void init(@Nonnull Executor initThread) { - this.calculator.init(initThread); - - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - this.calculator.setCalculateOnFly(Preferences.Calculations.calculateOnFly.getPreference(prefs)); - } - - @Override - public void addCalculatorEventListener(@Nonnull CalculatorEventListener calculatorEventListener) { - calculator.addCalculatorEventListener(calculatorEventListener); - } - - @Override - public void removeCalculatorEventListener(@Nonnull CalculatorEventListener calculatorEventListener) { - calculator.removeCalculatorEventListener(calculatorEventListener); - } - - @Override - public void fireCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) { - calculator.fireCalculatorEvent(calculatorEventData, calculatorEventType, data); - } - - @Override - public void fireCalculatorEvents(@Nonnull List calculatorEvents) { - calculator.fireCalculatorEvents(calculatorEvents); - } - - @Override - public void evaluate() { - calculator.evaluate(); - } - - @Override - public void evaluate(@Nonnull Long sequenceId) { - calculator.evaluate(sequenceId); - } - - @Override - public void simplify() { - calculator.simplify(); - } - - @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: - CalculatorActivityLauncher.showHistory(App.getApplication()); - break; - case show_history_detached: - CalculatorActivityLauncher.showHistory(App.getApplication(), true); - break; - case show_functions: - CalculatorActivityLauncher.showFunctions(App.getApplication()); - break; - case show_functions_detached: - CalculatorActivityLauncher.showFunctions(App.getApplication(), true); - break; - case show_operators: - CalculatorActivityLauncher.showOperators(App.getApplication()); - break; - case show_operators_detached: - CalculatorActivityLauncher.showOperators(App.getApplication(), true); - break; - case show_vars: - CalculatorActivityLauncher.showVars(App.getApplication()); - break; - case show_vars_detached: - CalculatorActivityLauncher.showVars(App.getApplication(), true); - break; - case show_settings: - CalculatorActivityLauncher.showSettings(App.getApplication()); - break; - case show_settings_detached: - CalculatorActivityLauncher.showSettings(App.getApplication(), true); - break; - case show_settings_widget: - CalculatorActivityLauncher.showWidgetSettings(App.getApplication(), true); - break; - case show_like_dialog: - CalculatorActivityLauncher.likeButtonPressed(App.getApplication()); - break; - case open_app: - CalculatorActivityLauncher.openApp(App.getApplication()); - break; - } - } - - @Override - public void onSharedPreferenceChanged(@Nonnull SharedPreferences prefs, @Nonnull String key) { - if (Preferences.Calculations.calculateOnFly.getKey().equals(key)) { - this.calculator.setCalculateOnFly(Preferences.Calculations.calculateOnFly.getPreference(prefs)); - } - } -} diff --git a/app/src/main/java/org/solovyev/android/calculator/AppModule.java b/app/src/main/java/org/solovyev/android/calculator/AppModule.java index 956dfb96..0aa01557 100644 --- a/app/src/main/java/org/solovyev/android/calculator/AppModule.java +++ b/app/src/main/java/org/solovyev/android/calculator/AppModule.java @@ -64,8 +64,8 @@ public class AppModule { @Provides @Singleton - Calculator provideCalculator(Bus bus, @Named(THREAD_UI) Executor executor) { - return new AndroidCalculator(application, bus, executor); + Calculator provideCalculator(SharedPreferences preferences, Bus bus, @Named(THREAD_UI) Executor executor) { + return new Calculator(preferences, bus, executor); } @Provides 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 77d811a9..34874adc 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Calculator.java +++ b/app/src/main/java/org/solovyev/android/calculator/Calculator.java @@ -22,79 +22,510 @@ package org.solovyev.android.calculator; +import android.content.SharedPreferences; +import android.support.annotation.NonNull; +import android.text.TextUtils; +import android.util.Log; +import com.squareup.otto.Bus; +import com.squareup.otto.Subscribe; +import jscl.AbstractJsclArithmeticException; +import jscl.MathEngine; import jscl.NumeralBase; +import jscl.NumeralBaseException; import jscl.math.Generic; +import jscl.math.function.IConstant; +import jscl.text.ParseInterruptedException; +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; +import org.solovyev.android.calculator.variables.CppVariable; +import org.solovyev.common.msg.ListMessageRegistry; +import org.solovyev.common.msg.Message; +import org.solovyev.common.msg.MessageRegistry; +import org.solovyev.common.msg.MessageType; +import org.solovyev.common.text.Strings; +import org.solovyev.common.units.ConversionException; +import org.solovyev.common.units.Conversions; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicLong; -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:38 - */ -public interface Calculator extends CalculatorEventContainer { +public class Calculator implements CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener { - void init(@Nonnull Executor initThread); - - /* - ********************************************************************** - * - * CALCULATIONS - * - ********************************************************************** - */ - - void evaluate(); - - void evaluate(@Nonnull Long sequenceId); - - void simplify(); + // one minute + private static final long PREFERENCE_CHECK_INTERVAL = 1000L * 60L; @Nonnull - CalculatorEventData evaluate(@Nonnull JsclOperation operation, - @Nonnull String expression); + private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer(); @Nonnull - CalculatorEventData evaluate(@Nonnull JsclOperation operation, + private final AtomicLong counter = new AtomicLong(CalculatorUtils.FIRST_ID); + + @Nonnull + private final ToJsclTextProcessor preprocessor = ToJsclTextProcessor.getInstance(); + + @Nonnull + private final Executor calculationsExecutor = Executors.newFixedThreadPool(10); + + @Nonnull + private final SharedPreferences preferences; + @Nonnull + private final Executor eventExecutor; + + private volatile boolean calculateOnFly = true; + + private volatile long lastPreferenceCheck = 0L; + + public Calculator(@Nonnull SharedPreferences preferences, @Nonnull Bus bus, @Nonnull Executor eventExecutor) { + this.preferences = preferences; + this.eventExecutor = eventExecutor; + bus.register(this); + addCalculatorEventListener(this); + + preferences.registerOnSharedPreferenceChangeListener(this); + } + + + @Nonnull + private static String doConversion(@Nonnull Generic generic, + @Nonnull NumeralBase from, + @Nonnull NumeralBase to) throws ConversionException { + final String result; + + if (from != to) { + String fromString = generic.toString(); + if (!Strings.isEmpty(fromString)) { + try { + fromString = ToJsclTextProcessor.getInstance().process(fromString).getExpression(); + } catch (ParseException e) { + // ok, problems while processing occurred + } + } + + + result = Conversions.doConversion(CalculatorNumeralBase.getConverter(), fromString, CalculatorNumeralBase.valueOf(from), CalculatorNumeralBase.valueOf(to)); + } else { + result = generic.toString(); + } + + return result; + } + + @Nonnull + private CalculatorEventData nextEventData() { + long eventId = counter.incrementAndGet(); + return CalculatorEventDataImpl.newInstance(eventId, eventId); + } + + @Nonnull + private CalculatorEventData nextEventData(@Nonnull Object source) { + long eventId = counter.incrementAndGet(); + return CalculatorEventDataImpl.newInstance(eventId, eventId, source); + } + + @Nonnull + private CalculatorEventData nextEventData(@Nonnull Long sequenceId) { + long eventId = counter.incrementAndGet(); + return CalculatorEventDataImpl.newInstance(eventId, sequenceId); + } + + public void evaluate() { + final EditorState viewState = getEditor().getState(); + final CalculatorEventData eventData = fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState); + this.evaluate(JsclOperation.numeric, viewState.getTextString(), eventData.getSequenceId()); + } + + public void simplify() { + final EditorState viewState = getEditor().getState(); + final CalculatorEventData eventData = fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState); + this.evaluate(JsclOperation.simplify, viewState.getTextString(), eventData.getSequenceId()); + } + + @Nonnull + public CalculatorEventData evaluate(@Nonnull final JsclOperation operation, + @Nonnull final String expression) { + + final CalculatorEventData eventDataId = nextEventData(); + + calculationsExecutor.execute(new Runnable() { + @Override + public void run() { + Calculator.this.evaluate(eventDataId.getSequenceId(), operation, expression, null); + } + }); + + return eventDataId; + } + + @Nonnull + public CalculatorEventData evaluate(@Nonnull final JsclOperation operation, @Nonnull final String expression, long sequenceId) { + final CalculatorEventData eventDataId = nextEventData(sequenceId); + + calculationsExecutor.execute(new Runnable() { + @Override + public void run() { + Calculator.this.evaluate(eventDataId.getSequenceId(), operation, expression, null); + } + }); + + return eventDataId; + } + + public void init(@Nonnull Executor initThread) { + Locator.getInstance().getEngine().init(initThread); + setCalculateOnFly(Preferences.Calculations.calculateOnFly.getPreference(preferences)); + } + + public boolean isCalculateOnFly() { + return calculateOnFly; + } + + public void setCalculateOnFly(boolean calculateOnFly) { + if (this.calculateOnFly != calculateOnFly) { + this.calculateOnFly = calculateOnFly; + if (this.calculateOnFly) { + evaluate(); + } + } + } + + @Nonnull + private CalculatorConversionEventData newConversionEventData(@Nonnull Long sequenceId, + @Nonnull Generic value, + @Nonnull NumeralBase from, + @Nonnull NumeralBase to, + @Nonnull DisplayState displayViewState) { + return CalculatorConversionEventDataImpl.newInstance(nextEventData(sequenceId), value, from, to, displayViewState); + } + + private void evaluate(@Nonnull Long sequenceId, + @Nonnull JsclOperation operation, + @Nonnull String expression, + @Nullable MessageRegistry mr) { + + checkPreferredPreferences(); + + PreparedExpression preparedExpression = null; + + try { + + expression = expression.trim(); + + if (Strings.isEmpty(expression)) { + fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, CalculatorOutputImpl.newEmptyOutput(operation)); + } else { + preparedExpression = prepareExpression(expression); + + final String jsclExpression = preparedExpression.toString(); + + try { + + final MathEngine mathEngine = Locator.getInstance().getEngine().getMathEngine(); + + final MessageRegistry messageRegistry = new ListMessageRegistry(); + 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(); + + if (messageRegistry.hasMessage()) { + final ErrorReporter errorReporter = Locator.getInstance().getErrorReporter(); + try { + final List messages = new ArrayList(); + 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); + } + } + + final CalculatorOutput data = CalculatorOutputImpl.newOutput(operation.getFromProcessor().process(result), operation, result); + fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, data); + + } catch (AbstractJsclArithmeticException e) { + handleException(sequenceId, operation, expression, mr, new CalculatorEvalException(e, e, jsclExpression)); + } + } + + } catch (ArithmeticException e) { + handleException(sequenceId, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage()))); + } catch (StackOverflowError e) { + handleException(sequenceId, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error))); + } catch (jscl.text.ParseException e) { + handleException(sequenceId, operation, expression, mr, preparedExpression, new ParseException(e)); + } catch (ParseInterruptedException e) { + + // do nothing - we ourselves interrupt the calculations + fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_cancelled, null); + + } catch (ParseException e) { + handleException(sequenceId, operation, expression, mr, preparedExpression, e); + } + } + + private void checkPreferredPreferences() { + final long currentTime = System.currentTimeMillis(); + + if (currentTime - lastPreferenceCheck > PREFERENCE_CHECK_INTERVAL) { + lastPreferenceCheck = currentTime; + Locator.getInstance().getPreferenceService().check(false); + } + } + + @Nonnull + public PreparedExpression prepareExpression(@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(@Nonnull Long sequenceId, + @Nonnull JsclOperation operation, @Nonnull String expression, - long sequenceId); + @Nullable MessageRegistry mr, + @Nullable PreparedExpression preparedExpression, + @Nonnull ParseException parseException) { - boolean isCalculateOnFly(); + if (operation == JsclOperation.numeric + && preparedExpression != null + && preparedExpression.isExistsUndefinedVar()) { - void setCalculateOnFly(boolean calculateOnFly); + evaluate(sequenceId, JsclOperation.simplify, expression, mr); + } else { - /* - ********************************************************************** - * - * CONVERSION - * - ********************************************************************** - */ + fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(parseException)); + } + } - boolean isConversionPossible(@Nonnull Generic generic, @Nonnull NumeralBase from, @Nonnull NumeralBase to); + 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)); + } + } @Nonnull - CalculatorEventData convert(@Nonnull Generic generic, @Nonnull NumeralBase to); + public CalculatorEventData convert(@Nonnull final Generic value, + @Nonnull final NumeralBase to) { + final CalculatorEventData eventDataId = nextEventData(); - /* - ********************************************************************** - * - * EVENTS - * - ********************************************************************** - */ - @Nonnull - CalculatorEventData fireCalculatorEvent(@Nonnull CalculatorEventType calculatorEventType, @Nullable Object data); + final DisplayState displayViewState = App.getDisplay().getState(); + final NumeralBase from = Locator.getInstance().getEngine().getMathEngine().getNumeralBase(); + + calculationsExecutor.execute(new Runnable() { + @Override + public void run() { + final Long sequenceId = eventDataId.getSequenceId(); + + fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_started, null); + try { + + final String result = doConversion(value, from, to); + + fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_result, result); + + } catch (ConversionException e) { + fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_failed, new ConversionFailureImpl(e)); + } + } + }); + + return eventDataId; + } + + public boolean isConversionPossible(@Nonnull Generic generic, NumeralBase from, @Nonnull NumeralBase to) { + try { + doConversion(generic, from, to); + return true; + } catch (ConversionException e) { + return false; + } + } + + public void addCalculatorEventListener(@Nonnull CalculatorEventListener calculatorEventListener) { + calculatorEventContainer.addCalculatorEventListener(calculatorEventListener); + } + + public void removeCalculatorEventListener(@Nonnull CalculatorEventListener calculatorEventListener) { + calculatorEventContainer.removeCalculatorEventListener(calculatorEventListener); + } + + public void fireCalculatorEvent(@Nonnull final CalculatorEventData calculatorEventData, @Nonnull final CalculatorEventType calculatorEventType, @Nullable final Object data) { + eventExecutor.execute(new Runnable() { + @Override + public void run() { + calculatorEventContainer.fireCalculatorEvent(calculatorEventData, calculatorEventType, data); + } + }); + } @Nonnull - CalculatorEventData fireCalculatorEvent(@Nonnull CalculatorEventType calculatorEventType, @Nullable Object data, @Nonnull Object source); + public CalculatorEventData fireCalculatorEvent(@Nonnull final CalculatorEventType calculatorEventType, @Nullable final Object data) { + final CalculatorEventData eventData = nextEventData(); + + fireCalculatorEvent(eventData, calculatorEventType, data); + + return eventData; + } @Nonnull - CalculatorEventData fireCalculatorEvent(@Nonnull CalculatorEventType calculatorEventType, @Nullable Object data, @Nonnull Long sequenceId); + public CalculatorEventData fireCalculatorEvent(@Nonnull final CalculatorEventType calculatorEventType, @Nullable final Object data, @Nonnull Object source) { + final CalculatorEventData eventData = nextEventData(source); + + fireCalculatorEvent(eventData, calculatorEventType, data); + + return eventData; + } + + @Subscribe + public void onEditorChanged(@Nonnull Editor.ChangedEvent e) { + if (!calculateOnFly) { + return; + } + if (TextUtils.equals(e.newState.text, e.oldState.text)) { + return; + } + evaluate(JsclOperation.numeric, e.newState.getTextString(), e.newState.sequence); + } + + @Subscribe + public void onDisplayChanged(@Nonnull Display.ChangedEvent e) { + final DisplayState newState = e.newState; + if (!newState.valid) { + return; + } + final String text = newState.text; + if (TextUtils.isEmpty(text)) { + return; + } + updateAnsVariable(text); + } + + private void updateAnsVariable(@NonNull String value) { + final VariablesRegistry variablesRegistry = Locator.getInstance().getEngine().getVariablesRegistry(); + final IConstant variable = variablesRegistry.get(VariablesRegistry.ANS); + + final CppVariable.Builder b = variable != null ? CppVariable.builder(variable) : CppVariable.builder(VariablesRegistry.ANS); + b.withValue(value); + b.withSystem(true); + b.withDescription(CalculatorMessages.getBundle().getString(CalculatorMessages.ans_description)); + + variablesRegistry.add(b.build().toJsclBuilder(), variable); + } + + @Subscribe + public void onFunctionAdded(@Nonnull FunctionsRegistry.AddedEvent event) { + evaluate(); + } + + @Subscribe + public void onFunctionsChanged(@Nonnull FunctionsRegistry.ChangedEvent event) { + evaluate(); + } + + @Subscribe + public void onFunctionsRemoved(@Nonnull FunctionsRegistry.RemovedEvent event) { + evaluate(); + } + + @Subscribe + public void onVariableRemoved(@NonNull VariablesRegistry.RemovedEvent e) { + evaluate(); + } + + @Subscribe + public void onVariableAdded(@NonNull VariablesRegistry.AddedEvent e) { + evaluate(); + } + + @Subscribe + public void onVariableChanged(@NonNull VariablesRegistry.ChangedEvent e) { + if (!e.newVariable.getName().equals(VariablesRegistry.ANS)) { + evaluate(); + } + } @Nonnull - PreparedExpression prepareExpression(@Nonnull String expression) throws ParseException; + private Editor getEditor() { + return App.getEditor(); + } + + @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: + CalculatorActivityLauncher.showHistory(App.getApplication()); + break; + case show_history_detached: + CalculatorActivityLauncher.showHistory(App.getApplication(), true); + break; + case show_functions: + CalculatorActivityLauncher.showFunctions(App.getApplication()); + break; + case show_functions_detached: + CalculatorActivityLauncher.showFunctions(App.getApplication(), true); + break; + case show_operators: + CalculatorActivityLauncher.showOperators(App.getApplication()); + break; + case show_operators_detached: + CalculatorActivityLauncher.showOperators(App.getApplication(), true); + break; + case show_vars: + CalculatorActivityLauncher.showVars(App.getApplication()); + break; + case show_vars_detached: + CalculatorActivityLauncher.showVars(App.getApplication(), true); + break; + case show_settings: + CalculatorActivityLauncher.showSettings(App.getApplication()); + break; + case show_settings_detached: + CalculatorActivityLauncher.showSettings(App.getApplication(), true); + break; + case show_settings_widget: + CalculatorActivityLauncher.showWidgetSettings(App.getApplication(), true); + break; + case show_like_dialog: + CalculatorActivityLauncher.likeButtonPressed(App.getApplication()); + break; + case open_app: + CalculatorActivityLauncher.openApp(App.getApplication()); + break; + } + } + + @Override + public void onSharedPreferenceChanged(@Nonnull SharedPreferences prefs, @Nonnull String key) { + if (Preferences.Calculations.calculateOnFly.getKey().equals(key)) { + setCalculateOnFly(Preferences.Calculations.calculateOnFly.getPreference(prefs)); + } + } } diff --git a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java b/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java deleted file mode 100644 index 530aa1d3..00000000 --- a/app/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java +++ /dev/null @@ -1,526 +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 android.support.annotation.NonNull; -import android.text.TextUtils; -import android.util.Log; -import com.squareup.otto.Bus; -import com.squareup.otto.Subscribe; -import jscl.AbstractJsclArithmeticException; -import jscl.MathEngine; -import jscl.NumeralBase; -import jscl.NumeralBaseException; -import jscl.math.Generic; -import jscl.math.function.IConstant; -import jscl.text.ParseInterruptedException; -import org.solovyev.android.calculator.functions.FunctionsRegistry; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.android.calculator.units.CalculatorNumeralBase; -import org.solovyev.android.calculator.variables.CppVariable; -import org.solovyev.common.msg.ListMessageRegistry; -import org.solovyev.common.msg.Message; -import org.solovyev.common.msg.MessageRegistry; -import org.solovyev.common.msg.MessageType; -import org.solovyev.common.text.Strings; -import org.solovyev.common.units.ConversionException; -import org.solovyev.common.units.Conversions; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicLong; - -public class CalculatorImpl implements Calculator { - - // one minute - private static final long PREFERENCE_CHECK_INTERVAL = 1000L * 60L; - - @Nonnull - private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer(); - - @Nonnull - private final AtomicLong counter = new AtomicLong(CalculatorUtils.FIRST_ID); - - @Nonnull - private final ToJsclTextProcessor preprocessor = ToJsclTextProcessor.getInstance(); - - @Nonnull - private final Executor calculationsExecutor = Executors.newFixedThreadPool(10); - - @Nonnull - private final Executor eventExecutor; - - private volatile boolean calculateOnFly = true; - - private volatile long lastPreferenceCheck = 0L; - - public CalculatorImpl(@Nonnull Bus bus, @Nonnull Executor eventExecutor) { - this.eventExecutor = eventExecutor; - bus.register(this); - } - - - @Nonnull - private static String doConversion(@Nonnull Generic generic, - @Nonnull NumeralBase from, - @Nonnull NumeralBase to) throws ConversionException { - final String result; - - if (from != to) { - String fromString = generic.toString(); - if (!Strings.isEmpty(fromString)) { - try { - fromString = ToJsclTextProcessor.getInstance().process(fromString).getExpression(); - } catch (ParseException e) { - // ok, problems while processing occurred - } - } - - - result = Conversions.doConversion(CalculatorNumeralBase.getConverter(), fromString, CalculatorNumeralBase.valueOf(from), CalculatorNumeralBase.valueOf(to)); - } else { - result = generic.toString(); - } - - return result; - } - - @Nonnull - private CalculatorEventData nextEventData() { - long eventId = counter.incrementAndGet(); - return CalculatorEventDataImpl.newInstance(eventId, eventId); - } - - @Nonnull - private CalculatorEventData nextEventData(@Nonnull Object source) { - long eventId = counter.incrementAndGet(); - return CalculatorEventDataImpl.newInstance(eventId, eventId, source); - } - - @Nonnull - private CalculatorEventData nextEventData(@Nonnull Long sequenceId) { - long eventId = counter.incrementAndGet(); - return CalculatorEventDataImpl.newInstance(eventId, sequenceId); - } - - @Override - public void evaluate() { - final EditorState viewState = getEditor().getState(); - final CalculatorEventData eventData = fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState); - this.evaluate(JsclOperation.numeric, viewState.getTextString(), eventData.getSequenceId()); - } - - @Override - public void evaluate(@Nonnull Long sequenceId) { - final EditorState viewState = getEditor().getState(); - fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState, sequenceId); - this.evaluate(JsclOperation.numeric, viewState.getTextString(), sequenceId); - } - - @Override - public void simplify() { - final EditorState viewState = getEditor().getState(); - final CalculatorEventData eventData = fireCalculatorEvent(CalculatorEventType.manual_calculation_requested, viewState); - this.evaluate(JsclOperation.simplify, viewState.getTextString(), eventData.getSequenceId()); - } - - @Nonnull - @Override - public CalculatorEventData evaluate(@Nonnull final JsclOperation operation, - @Nonnull final String expression) { - - final CalculatorEventData eventDataId = nextEventData(); - - calculationsExecutor.execute(new Runnable() { - @Override - public void run() { - CalculatorImpl.this.evaluate(eventDataId.getSequenceId(), operation, expression, null); - } - }); - - return eventDataId; - } - - @Nonnull - @Override - public CalculatorEventData evaluate(@Nonnull final JsclOperation operation, @Nonnull final String expression, long sequenceId) { - final CalculatorEventData eventDataId = nextEventData(sequenceId); - - calculationsExecutor.execute(new Runnable() { - @Override - public void run() { - CalculatorImpl.this.evaluate(eventDataId.getSequenceId(), operation, expression, null); - } - }); - - return eventDataId; - } - - @Override - public void init(@Nonnull Executor initThread) { - Locator.getInstance().getEngine().init(initThread); - } - - @Override - public boolean isCalculateOnFly() { - return calculateOnFly; - } - - @Override - public void setCalculateOnFly(boolean calculateOnFly) { - if (this.calculateOnFly != calculateOnFly) { - this.calculateOnFly = calculateOnFly; - if (this.calculateOnFly) { - evaluate(); - } - } - } - - @Nonnull - private CalculatorConversionEventData newConversionEventData(@Nonnull Long sequenceId, - @Nonnull Generic value, - @Nonnull NumeralBase from, - @Nonnull NumeralBase to, - @Nonnull DisplayState displayViewState) { - return CalculatorConversionEventDataImpl.newInstance(nextEventData(sequenceId), value, from, to, displayViewState); - } - - private void evaluate(@Nonnull Long sequenceId, - @Nonnull JsclOperation operation, - @Nonnull String expression, - @Nullable MessageRegistry mr) { - - checkPreferredPreferences(); - - PreparedExpression preparedExpression = null; - - try { - - expression = expression.trim(); - - if (Strings.isEmpty(expression)) { - fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, CalculatorOutputImpl.newEmptyOutput(operation)); - } else { - preparedExpression = prepareExpression(expression); - - final String jsclExpression = preparedExpression.toString(); - - try { - - final MathEngine mathEngine = Locator.getInstance().getEngine().getMathEngine(); - - final MessageRegistry messageRegistry = new ListMessageRegistry(); - 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(); - - if (messageRegistry.hasMessage()) { - final ErrorReporter errorReporter = Locator.getInstance().getErrorReporter(); - try { - final List messages = new ArrayList(); - 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); - } - } - - final CalculatorOutput data = CalculatorOutputImpl.newOutput(operation.getFromProcessor().process(result), operation, result); - fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_result, data); - - } catch (AbstractJsclArithmeticException e) { - handleException(sequenceId, operation, expression, mr, new CalculatorEvalException(e, e, jsclExpression)); - } - } - - } catch (ArithmeticException e) { - handleException(sequenceId, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage()))); - } catch (StackOverflowError e) { - handleException(sequenceId, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error))); - } catch (jscl.text.ParseException e) { - handleException(sequenceId, operation, expression, mr, preparedExpression, new ParseException(e)); - } catch (ParseInterruptedException e) { - - // do nothing - we ourselves interrupt the calculations - fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_cancelled, null); - - } catch (ParseException e) { - handleException(sequenceId, operation, expression, mr, preparedExpression, e); - } - } - - private void checkPreferredPreferences() { - final long currentTime = System.currentTimeMillis(); - - if (currentTime - lastPreferenceCheck > PREFERENCE_CHECK_INTERVAL) { - lastPreferenceCheck = currentTime; - Locator.getInstance().getPreferenceService().check(false); - } - } - - @Nonnull - @Override - public PreparedExpression prepareExpression(@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(@Nonnull Long sequenceId, - @Nonnull JsclOperation operation, - @Nonnull String expression, - @Nullable MessageRegistry mr, - @Nullable PreparedExpression preparedExpression, - @Nonnull ParseException parseException) { - - if (operation == JsclOperation.numeric - && preparedExpression != null - && preparedExpression.isExistsUndefinedVar()) { - - evaluate(sequenceId, JsclOperation.simplify, expression, mr); - } else { - - fireCalculatorEvent(newCalculationEventData(operation, expression, sequenceId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(parseException)); - } - } - - /* - ********************************************************************** - * - * CONVERSION - * - ********************************************************************** - */ - - 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)); - } - } - - @Nonnull - @Override - public CalculatorEventData convert(@Nonnull final Generic value, - @Nonnull final NumeralBase to) { - final CalculatorEventData eventDataId = nextEventData(); - - final DisplayState displayViewState = App.getDisplay().getState(); - final NumeralBase from = Locator.getInstance().getEngine().getMathEngine().getNumeralBase(); - - calculationsExecutor.execute(new Runnable() { - @Override - public void run() { - final Long sequenceId = eventDataId.getSequenceId(); - - fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_started, null); - try { - - final String result = doConversion(value, from, to); - - fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_result, result); - - } catch (ConversionException e) { - fireCalculatorEvent(newConversionEventData(sequenceId, value, from, to, displayViewState), CalculatorEventType.conversion_failed, new ConversionFailureImpl(e)); - } - } - }); - - return eventDataId; - } - - @Override - public boolean isConversionPossible(@Nonnull Generic generic, NumeralBase from, @Nonnull NumeralBase to) { - try { - doConversion(generic, from, to); - return true; - } catch (ConversionException e) { - return false; - } - } - - /* - ********************************************************************** - * - * EVENTS - * - ********************************************************************** - */ - - @Override - public void addCalculatorEventListener(@Nonnull CalculatorEventListener calculatorEventListener) { - calculatorEventContainer.addCalculatorEventListener(calculatorEventListener); - } - - @Override - public void removeCalculatorEventListener(@Nonnull CalculatorEventListener calculatorEventListener) { - calculatorEventContainer.removeCalculatorEventListener(calculatorEventListener); - } - - @Override - public void fireCalculatorEvent(@Nonnull final CalculatorEventData calculatorEventData, @Nonnull final CalculatorEventType calculatorEventType, @Nullable final Object data) { - eventExecutor.execute(new Runnable() { - @Override - public void run() { - calculatorEventContainer.fireCalculatorEvent(calculatorEventData, calculatorEventType, data); - } - }); - } - - @Override - public void fireCalculatorEvents(@Nonnull final List calculatorEvents) { - eventExecutor.execute(new Runnable() { - @Override - public void run() { - calculatorEventContainer.fireCalculatorEvents(calculatorEvents); - } - }); - } - - @Nonnull - @Override - public CalculatorEventData fireCalculatorEvent(@Nonnull final CalculatorEventType calculatorEventType, @Nullable final Object data) { - final CalculatorEventData eventData = nextEventData(); - - fireCalculatorEvent(eventData, calculatorEventType, data); - - return eventData; - } - - @Nonnull - @Override - public CalculatorEventData fireCalculatorEvent(@Nonnull final CalculatorEventType calculatorEventType, @Nullable final Object data, @Nonnull Object source) { - final CalculatorEventData eventData = nextEventData(source); - - fireCalculatorEvent(eventData, calculatorEventType, data); - - return eventData; - } - - @Nonnull - @Override - public CalculatorEventData fireCalculatorEvent(@Nonnull final CalculatorEventType calculatorEventType, @Nullable final Object data, @Nonnull Long sequenceId) { - final CalculatorEventData eventData = nextEventData(sequenceId); - - fireCalculatorEvent(eventData, calculatorEventType, data); - - return eventData; - } - - @Subscribe - public void onEditorChanged(@Nonnull Editor.ChangedEvent e) { - if (!calculateOnFly) { - return; - } - if (TextUtils.equals(e.newState.text, e.oldState.text)) { - return; - } - evaluate(JsclOperation.numeric, e.newState.getTextString(), e.newState.sequence); - } - - @Subscribe - public void onDisplayChanged(@Nonnull Display.ChangedEvent e) { - final DisplayState newState = e.newState; - if (!newState.valid) { - return; - } - final String text = newState.text; - if (TextUtils.isEmpty(text)) { - return; - } - updateAnsVariable(text); - } - - private void updateAnsVariable(@NonNull String value) { - final VariablesRegistry variablesRegistry = Locator.getInstance().getEngine().getVariablesRegistry(); - final IConstant variable = variablesRegistry.get(VariablesRegistry.ANS); - - final CppVariable.Builder b = variable != null ? CppVariable.builder(variable) : CppVariable.builder(VariablesRegistry.ANS); - b.withValue(value); - b.withSystem(true); - b.withDescription(CalculatorMessages.getBundle().getString(CalculatorMessages.ans_description)); - - variablesRegistry.add(b.build().toJsclBuilder(), variable); - } - - @Subscribe - public void onFunctionAdded(@Nonnull FunctionsRegistry.AddedEvent event) { - evaluate(); - } - - @Subscribe - public void onFunctionsChanged(@Nonnull FunctionsRegistry.ChangedEvent event) { - evaluate(); - } - - @Subscribe - public void onFunctionsRemoved(@Nonnull FunctionsRegistry.RemovedEvent event) { - evaluate(); - } - - @Subscribe - public void onVariableRemoved(@NonNull VariablesRegistry.RemovedEvent e) { - evaluate(); - } - - @Subscribe - public void onVariableAdded(@NonNull VariablesRegistry.AddedEvent e) { - evaluate(); - } - - @Subscribe - public void onVariableChanged(@NonNull VariablesRegistry.ChangedEvent e) { - if (!e.newVariable.getName().equals(VariablesRegistry.ANS)) { - evaluate(); - } - } - - @Nonnull - private Editor getEditor() { - return App.getEditor(); - } - -} diff --git a/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsRegistry.java b/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsRegistry.java index 4330d1ee..a288fb87 100644 --- a/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsRegistry.java +++ b/app/src/main/java/org/solovyev/android/calculator/functions/FunctionsRegistry.java @@ -30,8 +30,8 @@ import jscl.math.function.IFunction; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; import org.solovyev.android.Check; -import org.solovyev.android.calculator.entities.BaseEntitiesRegistry; import org.solovyev.android.calculator.Calculator; +import org.solovyev.android.calculator.entities.BaseEntitiesRegistry; import org.solovyev.android.calculator.entities.Category; import org.solovyev.android.calculator.entities.Entities; import org.solovyev.android.calculator.json.Json; diff --git a/app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java b/app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java index 62a7524b..28e2f872 100644 --- a/app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java +++ b/app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java @@ -25,26 +25,18 @@ package org.solovyev.android.calculator.plot; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; - +import jscl.math.Generic; +import jscl.math.function.Constant; import org.solovyev.android.calculator.Calculator; import org.solovyev.android.calculator.CalculatorEventType; import org.solovyev.android.calculator.CalculatorUtils; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import jscl.math.Generic; -import jscl.math.function.Constant; - -/** - * User: serso - * Date: 1/12/13 - * Time: 8:42 PM - */ public class CalculatorPlotterImpl implements CalculatorPlotter { @Nonnull diff --git a/app/src/test/java/org/solovyev/android/calculator/AbstractCalculatorTest.java b/app/src/test/java/org/solovyev/android/calculator/AbstractCalculatorTest.java index c6d99557..68957636 100644 --- a/app/src/test/java/org/solovyev/android/calculator/AbstractCalculatorTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/AbstractCalculatorTest.java @@ -22,6 +22,7 @@ package org.solovyev.android.calculator; +import android.content.SharedPreferences; import com.squareup.otto.Bus; import org.mockito.Mockito; import org.solovyev.android.calculator.plot.CalculatorPlotter; @@ -36,7 +37,7 @@ import java.util.concurrent.Executor; public class AbstractCalculatorTest { protected void setUp() throws Exception { - Locator.getInstance().init(new CalculatorImpl(Mockito.mock(Bus.class), Mockito.mock(Executor.class)), CalculatorTestUtils.newCalculatorEngine(), Mockito.mock(CalculatorNotifier.class), new SystemErrorReporter(), Mockito.mock(PreferredPreferences.class), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class)); + Locator.getInstance().init(new Calculator(Mockito.mock(SharedPreferences.class), Mockito.mock(Bus.class), Mockito.mock(Executor.class)), CalculatorTestUtils.newCalculatorEngine(), Mockito.mock(CalculatorNotifier.class), new SystemErrorReporter(), Mockito.mock(PreferredPreferences.class), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class)); Locator.getInstance().getEngine().init(new Executor() { @Override public void execute(Runnable command) { diff --git a/app/src/test/java/org/solovyev/android/calculator/CalculatorImplTest.java b/app/src/test/java/org/solovyev/android/calculator/CalculatorTest.java similarity index 96% rename from app/src/test/java/org/solovyev/android/calculator/CalculatorImplTest.java rename to app/src/test/java/org/solovyev/android/calculator/CalculatorTest.java index a5a4488b..75a632a9 100644 --- a/app/src/test/java/org/solovyev/android/calculator/CalculatorImplTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/CalculatorTest.java @@ -30,7 +30,7 @@ import org.junit.Test; * Date: 15.10.12 * Time: 12:30 */ -public class CalculatorImplTest extends AbstractCalculatorTest { +public class CalculatorTest extends AbstractCalculatorTest { @Before public void setUp() throws Exception { diff --git a/app/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java b/app/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java index 8a74f846..bf2e8853 100644 --- a/app/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java +++ b/app/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java @@ -23,10 +23,10 @@ package org.solovyev.android.calculator; import android.content.Context; +import android.content.SharedPreferences; import com.squareup.otto.Bus; import jscl.JsclMathEngine; import org.junit.Assert; -import org.mockito.Mockito; import org.robolectric.fakes.RoboSharedPreferences; import org.solovyev.android.calculator.functions.FunctionsRegistry; import org.solovyev.android.calculator.jscl.JsclOperation; @@ -45,6 +45,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +import static org.mockito.Mockito.mock; + /** * User: serso * Date: 10/7/12 @@ -57,7 +59,7 @@ public class CalculatorTestUtils { public static void staticSetUp() throws Exception { App.init(new CalculatorApplication(), new Languages(new RoboSharedPreferences(new HashMap>(), "test", 0))); - Locator.getInstance().init(new CalculatorImpl(Mockito.mock(Bus.class), Mockito.mock(Executor.class)), newCalculatorEngine(), Mockito.mock(CalculatorNotifier.class), new SystemErrorReporter(), Mockito.mock(PreferredPreferences.class), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class)); + Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class)), newCalculatorEngine(), mock(CalculatorNotifier.class), new SystemErrorReporter(), mock(PreferredPreferences.class), mock(Keyboard.class), mock(CalculatorPlotter.class)); Locator.getInstance().getEngine().init(new Executor() { @Override public void execute(Runnable command) { @@ -72,7 +74,7 @@ public class CalculatorTestUtils { } public static void staticSetUp(@Nullable Context context) throws Exception { - Locator.getInstance().init(new CalculatorImpl(Mockito.mock(Bus.class), Mockito.mock(Executor.class)), newCalculatorEngine(), Mockito.mock(CalculatorNotifier.class), new SystemErrorReporter(), Mockito.mock(PreferredPreferences.class), Mockito.mock(Keyboard.class), Mockito.mock(CalculatorPlotter.class)); + Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class)), newCalculatorEngine(), mock(CalculatorNotifier.class), new SystemErrorReporter(), mock(PreferredPreferences.class), mock(Keyboard.class), mock(CalculatorPlotter.class)); Locator.getInstance().getEngine().init(new Executor() { @Override public void execute(Runnable command) {