Plotter
This commit is contained in:
parent
4070de7693
commit
f7b66673a5
@ -28,7 +28,11 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import dagger.Lazy;
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.function.Constant;
|
||||
import jscl.math.function.CustomFunction;
|
||||
import org.solovyev.android.Activities;
|
||||
import org.solovyev.android.Check;
|
||||
import org.solovyev.android.calculator.about.AboutActivity;
|
||||
@ -38,31 +42,40 @@ import org.solovyev.android.calculator.functions.FunctionsActivity;
|
||||
import org.solovyev.android.calculator.history.HistoryActivity;
|
||||
import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity;
|
||||
import org.solovyev.android.calculator.operators.OperatorsActivity;
|
||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
||||
import org.solovyev.android.calculator.plot.ExpressionFunction;
|
||||
import org.solovyev.android.calculator.plot.PlotActivity;
|
||||
import org.solovyev.android.calculator.preferences.PreferencesActivity;
|
||||
import org.solovyev.android.calculator.variables.CppVariable;
|
||||
import org.solovyev.android.calculator.variables.EditVariableFragment;
|
||||
import org.solovyev.android.calculator.variables.VariablesActivity;
|
||||
import org.solovyev.android.calculator.variables.VariablesFragment;
|
||||
import org.solovyev.android.plotter.Plotter;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
import org.solovyev.common.text.Strings;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.function.Constant;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Singleton
|
||||
public final class ActivityLauncher implements CalculatorEventListener {
|
||||
|
||||
@Inject
|
||||
Application application;
|
||||
@Inject
|
||||
Lazy<Plotter> plotter;
|
||||
@Inject
|
||||
Lazy<ErrorReporter> errorReporter;
|
||||
@Inject
|
||||
Lazy<Display> display;
|
||||
@Inject
|
||||
Lazy<VariablesRegistry> variablesRegistry;
|
||||
@Inject
|
||||
Notifier notifier;
|
||||
@Nullable
|
||||
private CalculatorActivity activity;
|
||||
|
||||
@ -109,7 +122,7 @@ public final class ActivityLauncher implements CalculatorEventListener {
|
||||
final CppFunction.Builder builder = CppFunction.builder("", functionBody);
|
||||
final Generic generic = viewState.getResult();
|
||||
if (generic != null) {
|
||||
final Set<Constant> constants = CalculatorUtils.getNotSystemConstants(generic);
|
||||
final Set<Constant> constants = generic.getUndefinedConstants(null);
|
||||
for (Constant constant : constants) {
|
||||
builder.withParameter(constant.getName());
|
||||
}
|
||||
@ -128,26 +141,13 @@ public final class ActivityLauncher implements CalculatorEventListener {
|
||||
return ((CalculatorApplication) App.getApplication()).notifier;
|
||||
}
|
||||
|
||||
public static void tryPlot() {
|
||||
final CalculatorPlotter plotter = Locator.getInstance().getPlotter();
|
||||
final Display display = App.getDisplay();
|
||||
final DisplayState viewState = display.getState();
|
||||
|
||||
if (viewState.valid) {
|
||||
final String functionValue = viewState.text;
|
||||
final Generic expression = viewState.getResult();
|
||||
if (!Strings.isEmpty(functionValue) && expression != null) {
|
||||
if (plotter.isPlotPossibleFor(expression)) {
|
||||
plotter.plot(expression);
|
||||
} else {
|
||||
getNotifier().showMessage(R.string.cpp_plot_too_many_variables, MessageType.error);
|
||||
}
|
||||
} else {
|
||||
getNotifier().showMessage(R.string.cpp_plot_empty_function_error, MessageType.error);
|
||||
}
|
||||
} else {
|
||||
public void plotDisplayedExpression() {
|
||||
final DisplayState state = display.get().getState();
|
||||
if (!state.valid) {
|
||||
getNotifier().showMessage(R.string.not_valid_result, MessageType.error);
|
||||
return;
|
||||
}
|
||||
plot(state.getResult());
|
||||
}
|
||||
|
||||
public void showHistory() {
|
||||
@ -161,7 +161,7 @@ public final class ActivityLauncher implements CalculatorEventListener {
|
||||
public void showWidgetSettings() {
|
||||
final Context context = getContext();
|
||||
show(context, PreferencesActivity.makeIntent(context, R.xml.preferences_widget,
|
||||
R.string.prefs_widget_title));
|
||||
R.string.prefs_widget_title));
|
||||
}
|
||||
|
||||
public void showOperators() {
|
||||
@ -258,4 +258,44 @@ public final class ActivityLauncher implements CalculatorEventListener {
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
void plot(@Nullable Generic expression) {
|
||||
if (expression == null) {
|
||||
notifier.showMessage(R.string.cpp_plot_empty_function_error);
|
||||
return;
|
||||
}
|
||||
final String content = expression.toString();
|
||||
if (TextUtils.isEmpty(content)) {
|
||||
notifier.showMessage(R.string.cpp_plot_empty_function_error);
|
||||
return;
|
||||
}
|
||||
final List<String> parameters = new ArrayList<>();
|
||||
for (Constant parameter : expression.getUndefinedConstants(variablesRegistry.get())) {
|
||||
parameters.add(parameter.getName());
|
||||
}
|
||||
if (parameters.size() > 2) {
|
||||
notifier.showMessage(R.string.cpp_plot_too_many_variables);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final CustomFunction f = new CustomFunction.Builder().setName("").setParameterNames(parameters).setContent(content).create();
|
||||
final ExpressionFunction ef = new ExpressionFunction(f, false);
|
||||
plotter.get().add(ef);
|
||||
showPlotter();
|
||||
} catch (RuntimeException e) {
|
||||
errorReporter.get().onException(e);
|
||||
notifier.showMessage(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canPlot(@Nullable Generic expression) {
|
||||
if (expression == null || TextUtils.isEmpty(expression.toString())) {
|
||||
return false;
|
||||
}
|
||||
if (expression.getUndefinedConstants(variablesRegistry.get()).size() > 2) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,8 @@ import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import android.util.TimingLogger;
|
||||
|
||||
import com.squareup.otto.Bus;
|
||||
|
||||
import jscl.MathEngine;
|
||||
import org.acra.ACRA;
|
||||
import org.acra.ACRAConfiguration;
|
||||
import org.acra.sender.HttpSender;
|
||||
@ -38,18 +37,13 @@ import org.solovyev.android.calculator.floating.FloatingCalculatorActivity;
|
||||
import org.solovyev.android.calculator.history.History;
|
||||
import org.solovyev.android.calculator.language.Language;
|
||||
import org.solovyev.android.calculator.language.Languages;
|
||||
import org.solovyev.android.calculator.plot.AndroidCalculatorPlotter;
|
||||
import org.solovyev.android.calculator.plot.CalculatorPlotterImpl;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
|
||||
import jscl.MathEngine;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class CalculatorApplication extends android.app.Application implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
@ -143,11 +137,7 @@ public class CalculatorApplication extends android.app.Application implements Sh
|
||||
languages.updateContextLocale(this, true);
|
||||
App.getGa().reportInitially(preferences);
|
||||
|
||||
Locator.getInstance().init(calculator,
|
||||
engine,
|
||||
keyboard,
|
||||
new AndroidCalculatorPlotter(this, new CalculatorPlotterImpl(calculator))
|
||||
);
|
||||
Locator.getInstance().init(calculator, engine, keyboard);
|
||||
|
||||
calculator.init(initThread);
|
||||
|
||||
|
@ -22,16 +22,13 @@
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public interface CalculatorLocator {
|
||||
|
||||
void init(@Nonnull Calculator calculator,
|
||||
@Nonnull Engine engine,
|
||||
@Nonnull Keyboard keyboard,
|
||||
@Nonnull CalculatorPlotter plotter);
|
||||
@Nonnull Keyboard keyboard);
|
||||
|
||||
@Nonnull
|
||||
Calculator getCalculator();
|
||||
@ -42,6 +39,4 @@ public interface CalculatorLocator {
|
||||
@Nonnull
|
||||
Keyboard getKeyboard();
|
||||
|
||||
@Nonnull
|
||||
CalculatorPlotter getPlotter();
|
||||
}
|
||||
|
@ -22,15 +22,6 @@
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.function.Constant;
|
||||
import jscl.math.function.IConstant;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 9/22/12
|
||||
@ -42,18 +33,4 @@ public final class CalculatorUtils {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static Set<Constant> getNotSystemConstants(@Nonnull Generic expression) {
|
||||
final Set<Constant> notSystemConstants = new HashSet<Constant>();
|
||||
|
||||
for (Constant constant : expression.getConstants()) {
|
||||
IConstant var = Locator.getInstance().getEngine().getVariablesRegistry().get(constant.getName());
|
||||
if (var != null && !var.isSystem() && !var.isDefined()) {
|
||||
notSystemConstants.add(constant);
|
||||
}
|
||||
}
|
||||
|
||||
return notSystemConstants;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -57,8 +57,6 @@ public class Display {
|
||||
Lazy<Notifier> notifier;
|
||||
@Inject
|
||||
Lazy<PreferredPreferences> preferredPreferences;
|
||||
@Inject
|
||||
ActivityLauncher launcher;
|
||||
@Nullable
|
||||
private DisplayView view;
|
||||
@Nonnull
|
||||
|
@ -37,17 +37,12 @@ import butterknife.ButterKnife;
|
||||
import com.squareup.otto.Bus;
|
||||
import jscl.NumeralBase;
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.function.Constant;
|
||||
import jscl.math.function.CustomFunction;
|
||||
import org.solovyev.android.calculator.converter.ConverterFragment;
|
||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.calculator.plot.ExpressionFunction;
|
||||
import org.solovyev.android.plotter.Plotter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DisplayFragment extends BaseFragment implements View.OnClickListener,
|
||||
MenuItem.OnMenuItemClickListener {
|
||||
@ -146,8 +141,7 @@ public class DisplayFragment extends BaseFragment implements View.OnClickListene
|
||||
addMenu(menu, R.string.c_convert, this);
|
||||
}
|
||||
}
|
||||
final int parameters = CalculatorUtils.getNotSystemConstants(result).size();
|
||||
if (parameters >= 0 && parameters <= 2) {
|
||||
if (launcher.canPlot(result)) {
|
||||
addMenu(menu, R.string.c_plot, this);
|
||||
}
|
||||
}
|
||||
@ -216,21 +210,7 @@ public class DisplayFragment extends BaseFragment implements View.OnClickListene
|
||||
ConverterFragment.show(getActivity(), getValue(result));
|
||||
return true;
|
||||
case R.string.c_plot:
|
||||
if (result != null) {
|
||||
try {
|
||||
final List<String> parameters = new ArrayList<>();
|
||||
for (Constant parameter : CalculatorUtils.getNotSystemConstants(result)) {
|
||||
parameters.add(parameter.getName());
|
||||
}
|
||||
new CustomFunction.Builder().setParameterNames(parameters).setContent(state.text).create();
|
||||
final CustomFunction f = new CustomFunction.Builder().setName("").setParameterNames(parameters).setContent(result.toString()).create();
|
||||
final ExpressionFunction ef = new ExpressionFunction(f, false);
|
||||
plotter.add(ef);
|
||||
launcher.showPlotter();
|
||||
} catch (RuntimeException e) {
|
||||
errorReporter.onException(e);
|
||||
}
|
||||
}
|
||||
launcher.plot(result);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -22,8 +22,6 @@
|
||||
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class Locator implements CalculatorLocator {
|
||||
@ -36,8 +34,6 @@ public class Locator implements CalculatorLocator {
|
||||
private Calculator calculator;
|
||||
@Nonnull
|
||||
private Keyboard keyboard;
|
||||
@Nonnull
|
||||
private CalculatorPlotter calculatorPlotter;
|
||||
|
||||
public Locator() {
|
||||
}
|
||||
@ -50,13 +46,10 @@ public class Locator implements CalculatorLocator {
|
||||
@Override
|
||||
public void init(@Nonnull Calculator calculator,
|
||||
@Nonnull Engine engine,
|
||||
@Nonnull Keyboard keyboard,
|
||||
@Nonnull CalculatorPlotter plotter) {
|
||||
@Nonnull Keyboard keyboard) {
|
||||
|
||||
this.calculator = calculator;
|
||||
this.engine = engine;
|
||||
this.calculatorPlotter = plotter;
|
||||
|
||||
this.keyboard = keyboard;
|
||||
}
|
||||
|
||||
@ -78,9 +71,4 @@ public class Locator implements CalculatorLocator {
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public CalculatorPlotter getPlotter() {
|
||||
return calculatorPlotter;
|
||||
}
|
||||
}
|
||||
|
@ -24,17 +24,14 @@ package org.solovyev.android.calculator;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.widget.Toast;
|
||||
import org.solovyev.android.Threads;
|
||||
import org.solovyev.android.msg.AndroidMessage;
|
||||
import org.solovyev.common.msg.Message;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class Notifier {
|
||||
@ -48,27 +45,27 @@ public class Notifier {
|
||||
}
|
||||
|
||||
public void showMessage(@Nonnull Message message) {
|
||||
showMessageInUiThread(message.getLocalizedMessage());
|
||||
showMessage(message.getLocalizedMessage());
|
||||
}
|
||||
|
||||
public void showMessage(@Nonnull Integer messageCode, @Nonnull MessageType messageType, @Nonnull List<Object> parameters) {
|
||||
showMessage(new AndroidMessage(messageCode, messageType, application, parameters));
|
||||
public void showMessage(@StringRes int message, Object... parameters) {
|
||||
showMessage(application.getString(message, parameters));
|
||||
}
|
||||
|
||||
public void showMessage(@Nonnull Integer messageCode, @Nonnull MessageType messageType, @Nullable Object... parameters) {
|
||||
showMessage(new AndroidMessage(messageCode, messageType, application, parameters));
|
||||
public void showMessage(@StringRes int message) {
|
||||
showMessage(application.getString(message));
|
||||
}
|
||||
|
||||
private void showMessageInUiThread(@Nonnull final String message) {
|
||||
public void showMessage(@Nonnull final String message) {
|
||||
if (Threads.isUiThread()) {
|
||||
Toast.makeText(application, message, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(application, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(application, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,5 @@
|
||||
package org.solovyev.android.calculator.keyboard;
|
||||
|
||||
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING;
|
||||
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING;
|
||||
import static android.view.HapticFeedbackConstants.KEYBOARD_TAP;
|
||||
import static org.solovyev.android.calculator.App.cast;
|
||||
import static org.solovyev.android.calculator.App.getScreenMetrics;
|
||||
import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple;
|
||||
import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple_mobile;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
@ -20,15 +12,8 @@ import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.solovyev.android.Views;
|
||||
import org.solovyev.android.calculator.ActivityUi;
|
||||
import org.solovyev.android.calculator.App;
|
||||
import org.solovyev.android.calculator.Calculator;
|
||||
import org.solovyev.android.calculator.Editor;
|
||||
import org.solovyev.android.calculator.Keyboard;
|
||||
import org.solovyev.android.calculator.Preferences;
|
||||
import org.solovyev.android.calculator.PreferredPreferences;
|
||||
import org.solovyev.android.calculator.*;
|
||||
import org.solovyev.android.calculator.buttons.CppSpecialButton;
|
||||
import org.solovyev.android.calculator.view.ScreenMetrics;
|
||||
import org.solovyev.android.views.Adjuster;
|
||||
@ -37,11 +22,16 @@ import org.solovyev.android.views.dragbutton.DragButton;
|
||||
import org.solovyev.android.views.dragbutton.DragDirection;
|
||||
import org.solovyev.android.views.dragbutton.SimpleDragListener;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import static android.view.HapticFeedbackConstants.*;
|
||||
import static org.solovyev.android.calculator.App.cast;
|
||||
import static org.solovyev.android.calculator.App.getScreenMetrics;
|
||||
import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple;
|
||||
import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple_mobile;
|
||||
|
||||
public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPreferenceChangeListener, SimpleDragListener.DragProcessor, View.OnClickListener {
|
||||
|
||||
@ -67,6 +57,8 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
|
||||
@Inject
|
||||
Calculator calculator;
|
||||
@Inject
|
||||
ActivityLauncher launcher;
|
||||
@Inject
|
||||
PreferredPreferences preferredPreferences;
|
||||
protected int orientation = Configuration.ORIENTATION_PORTRAIT;
|
||||
private int textSize;
|
||||
|
@ -17,7 +17,6 @@ import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
import jscl.NumeralBase;
|
||||
import org.solovyev.android.Check;
|
||||
import org.solovyev.android.calculator.ActivityLauncher;
|
||||
import org.solovyev.android.calculator.Engine;
|
||||
import org.solovyev.android.calculator.Preferences;
|
||||
import org.solovyev.android.calculator.R;
|
||||
@ -121,7 +120,7 @@ public class PartialKeyboardUi extends BaseKeyboardUi {
|
||||
return true;
|
||||
case R.id.cpp_button_equals:
|
||||
if (direction == down) {
|
||||
ActivityLauncher.tryPlot();
|
||||
launcher.plotDisplayedExpression();
|
||||
return true;
|
||||
} else if (direction == up) {
|
||||
calculator.simplify();
|
||||
|
@ -1,442 +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.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;
|
||||
|
||||
public class CalculatorPlotterImpl implements CalculatorPlotter {
|
||||
|
||||
@Nonnull
|
||||
private final List<PlotFunction> functions = new ArrayList<PlotFunction>();
|
||||
|
||||
@Nonnull
|
||||
private final Calculator calculator;
|
||||
|
||||
private final PlotResourceManager resourceManager = new MapPlotResourceManager();
|
||||
|
||||
private boolean plot3d = false;
|
||||
private boolean adjustYAxis = true;
|
||||
|
||||
private boolean plotImag = false;
|
||||
|
||||
private int arity = 0;
|
||||
|
||||
@Nonnull
|
||||
private PlotBoundaries plotBoundaries = PlotBoundaries.newDefaultInstance();
|
||||
|
||||
@Nonnull
|
||||
private PlotData plotData = new PlotData(Collections.<PlotFunction>emptyList(), plot3d, true, plotBoundaries);
|
||||
|
||||
public CalculatorPlotterImpl(@Nonnull Calculator calculator) {
|
||||
this.calculator = calculator;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public PlotData getPlotData() {
|
||||
return plotData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addFunction(@Nonnull Generic expression) {
|
||||
final List<Constant> variables = new ArrayList<Constant>(CalculatorUtils.getNotSystemConstants(expression));
|
||||
|
||||
if (variables.size() > 2) throw new AssertionError();
|
||||
|
||||
final Constant xVariable;
|
||||
if (variables.size() > 0) {
|
||||
xVariable = variables.get(0);
|
||||
} else {
|
||||
xVariable = null;
|
||||
}
|
||||
|
||||
final Constant yVariable;
|
||||
if (variables.size() > 1) {
|
||||
yVariable = variables.get(1);
|
||||
} else {
|
||||
yVariable = null;
|
||||
}
|
||||
|
||||
final XyFunction realXyFunction = new XyFunction(expression, xVariable, yVariable, false);
|
||||
final XyFunction imagXyFunction = new XyFunction(expression, xVariable, yVariable, true);
|
||||
|
||||
// first create plot functions with default line definitions
|
||||
PlotFunction realPlotFunction = new PlotFunction(realXyFunction);
|
||||
PlotFunction imagPlotFunction = new PlotFunction(imagXyFunction);
|
||||
|
||||
// then remove all unpinned graphs and free their line definitions
|
||||
removeAllUnpinnedExcept(realPlotFunction, imagPlotFunction);
|
||||
|
||||
// create plot functions with freed line definitions
|
||||
realPlotFunction = newPlotFunction(realXyFunction);
|
||||
imagPlotFunction = newPlotFunction(imagXyFunction);
|
||||
|
||||
final boolean realAdded = addFunction(realPlotFunction);
|
||||
final boolean imagAdded = addFunction(plotImag ? imagPlotFunction : PlotFunction.invisible(imagPlotFunction));
|
||||
|
||||
return imagAdded || realAdded;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private PlotFunction newPlotFunction(@Nonnull XyFunction xyFunction) {
|
||||
return new PlotFunction(xyFunction, resourceManager.generateAndRegister());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addFunction(@Nonnull PlotFunction plotFunction) {
|
||||
synchronized (functions) {
|
||||
if (!functions.contains(plotFunction)) {
|
||||
resourceManager.register(plotFunction.getPlotLineDef());
|
||||
functions.add(plotFunction);
|
||||
onFunctionsChanged();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean removeAllUnpinnedExcept(@Nonnull final PlotFunction... exceptFunctions) {
|
||||
synchronized (functions) {
|
||||
|
||||
boolean changed = Iterables.removeIf(functions, new Predicate<PlotFunction>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable PlotFunction function) {
|
||||
if (function != null && !function.isPinned()) {
|
||||
|
||||
for (PlotFunction exceptFunction : exceptFunctions) {
|
||||
if (exceptFunction.equals(function)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
resourceManager.unregister(function.getPlotLineDef());
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
onFunctionsChanged();
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeAllUnpinned() {
|
||||
synchronized (functions) {
|
||||
boolean changed = Iterables.removeIf(functions, new Predicate<PlotFunction>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable PlotFunction function) {
|
||||
boolean removed = function != null && !function.isPinned();
|
||||
|
||||
if (removed) {
|
||||
resourceManager.unregister(function.getPlotLineDef());
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
onFunctionsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFunction(@Nonnull PlotFunction plotFunction) {
|
||||
synchronized (functions) {
|
||||
boolean changed = functions.remove(plotFunction);
|
||||
if (changed) {
|
||||
resourceManager.unregister(plotFunction.getPlotLineDef());
|
||||
onFunctionsChanged();
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addFunction(@Nonnull XyFunction xyFunction) {
|
||||
return addFunction(newPlotFunction(xyFunction));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addFunction(@Nonnull XyFunction xyFunction, @Nonnull PlotLineDef functionLineDef) {
|
||||
return addFunction(new PlotFunction(xyFunction, functionLineDef));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateFunction(@Nonnull XyFunction xyFunction, @Nonnull PlotLineDef functionLineDef) {
|
||||
final PlotFunction newFunction = new PlotFunction(xyFunction, functionLineDef);
|
||||
|
||||
return updateFunction(newFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateFunction(@Nonnull PlotFunction newFunction) {
|
||||
boolean changed = updateFunction0(newFunction);
|
||||
if (changed) {
|
||||
firePlotDataChangedEvent();
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
public boolean updateFunction0(@Nonnull PlotFunction newFunction) {
|
||||
boolean changed = false;
|
||||
|
||||
synchronized (functions) {
|
||||
for (int i = 0; i < functions.size(); i++) {
|
||||
final PlotFunction oldFunction = functions.get(i);
|
||||
if (oldFunction.equals(newFunction)) {
|
||||
|
||||
resourceManager.unregister(oldFunction.getPlotLineDef());
|
||||
resourceManager.register(newFunction.getPlotLineDef());
|
||||
|
||||
// update old function
|
||||
functions.set(i, newFunction);
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFunction(@Nonnull XyFunction xyFunction) {
|
||||
return removeFunction(new PlotFunction(xyFunction));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public PlotFunction pin(@Nonnull PlotFunction plotFunction) {
|
||||
final PlotFunction newFunction = PlotFunction.pin(plotFunction);
|
||||
updateFunction0(newFunction);
|
||||
return newFunction;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public PlotFunction unpin(@Nonnull PlotFunction plotFunction) {
|
||||
final PlotFunction newFunction = PlotFunction.unpin(plotFunction);
|
||||
updateFunction0(newFunction);
|
||||
return newFunction;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public PlotFunction show(@Nonnull PlotFunction plotFunction) {
|
||||
final PlotFunction newFunction = PlotFunction.visible(plotFunction);
|
||||
|
||||
updateFunction(newFunction);
|
||||
|
||||
return newFunction;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public PlotFunction hide(@Nonnull PlotFunction plotFunction) {
|
||||
final PlotFunction newFunction = PlotFunction.invisible(plotFunction);
|
||||
|
||||
updateFunction(newFunction);
|
||||
|
||||
return newFunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAllFunctions() {
|
||||
synchronized (functions) {
|
||||
resourceManager.unregisterAll();
|
||||
functions.clear();
|
||||
onFunctionsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PlotFunction getFunctionById(@Nonnull final String functionId) {
|
||||
synchronized (functions) {
|
||||
return Iterables.find(functions, new Predicate<PlotFunction>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable PlotFunction function) {
|
||||
return function != null && function.getXyFunction().getId().equals(functionId);
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: this method must be called from synchronized block
|
||||
private void onFunctionsChanged() {
|
||||
if (!Thread.holdsLock(functions)) throw new AssertionError();
|
||||
|
||||
int maxArity = 0;
|
||||
for (PlotFunction function : functions) {
|
||||
final XyFunction xyFunction = function.getXyFunction();
|
||||
|
||||
maxArity = Math.max(maxArity, xyFunction.getArity());
|
||||
}
|
||||
|
||||
plot3d = maxArity > 1;
|
||||
|
||||
if (functions.isEmpty()) {
|
||||
// no functions => new plot => default boundaries
|
||||
this.plotBoundaries = PlotBoundaries.newDefaultInstance();
|
||||
this.adjustYAxis = true;
|
||||
}
|
||||
|
||||
arity = maxArity;
|
||||
|
||||
firePlotDataChangedEvent();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<PlotFunction> getFunctions() {
|
||||
synchronized (functions) {
|
||||
return new ArrayList<PlotFunction>(functions);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<PlotFunction> getVisibleFunctions() {
|
||||
synchronized (functions) {
|
||||
return Lists.newArrayList(Iterables.filter(functions, new Predicate<PlotFunction>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable PlotFunction function) {
|
||||
return function != null && function.isVisible();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void plot() {
|
||||
calculator.fireCalculatorEvent(CalculatorEventType.plot_graph, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void plot(@Nonnull Generic expression) {
|
||||
addFunction(expression);
|
||||
plot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is2dPlotPossible() {
|
||||
return arity < 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlotPossibleFor(@Nonnull Generic expression) {
|
||||
boolean result = false;
|
||||
|
||||
int size = CalculatorUtils.getNotSystemConstants(expression).size();
|
||||
if (size == 0 || size == 1 || size == 2) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlot3d(boolean plot3d) {
|
||||
if (this.plot3d != plot3d) {
|
||||
this.plot3d = plot3d;
|
||||
firePlotDataChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
private void firePlotDataChangedEvent() {
|
||||
updatePlotData();
|
||||
calculator.fireCalculatorEvent(CalculatorEventType.plot_data_changed, plotData);
|
||||
}
|
||||
|
||||
private void updatePlotData() {
|
||||
plotData = new PlotData(getVisibleFunctions(), plot3d, adjustYAxis, plotBoundaries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlotImag(boolean plotImag) {
|
||||
if (this.plotImag != plotImag) {
|
||||
this.plotImag = plotImag;
|
||||
if (toggleImagFunctions(this.plotImag)) {
|
||||
firePlotDataChangedEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void savePlotBoundaries(@Nonnull PlotBoundaries plotBoundaries) {
|
||||
if (!this.plotBoundaries.equals(plotBoundaries)) {
|
||||
this.plotBoundaries = plotBoundaries;
|
||||
this.adjustYAxis = false;
|
||||
updatePlotData();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlotBoundaries(@Nonnull PlotBoundaries plotBoundaries) {
|
||||
if (!this.plotBoundaries.equals(plotBoundaries)) {
|
||||
this.plotBoundaries = plotBoundaries;
|
||||
this.adjustYAxis = false;
|
||||
firePlotDataChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean toggleImagFunctions(boolean show) {
|
||||
boolean changed = false;
|
||||
|
||||
synchronized (functions) {
|
||||
for (int i = 0; i < functions.size(); i++) {
|
||||
final PlotFunction plotFunction = functions.get(i);
|
||||
if (plotFunction.getXyFunction().isImag()) {
|
||||
functions.set(i, show ? PlotFunction.visible(plotFunction) : PlotFunction.invisible(plotFunction));
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
}
|
@ -1,152 +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.plot;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.solovyev.android.calculator.Locator;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.list.ListItem;
|
||||
import org.solovyev.android.view.ViewBuilder;
|
||||
import org.solovyev.android.view.ViewFromLayoutBuilder;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class PlotFunctionListItem implements ListItem {
|
||||
|
||||
private static final String PREFIX = "plot_function_";
|
||||
|
||||
@Nonnull
|
||||
private PlotFunction plotFunction;
|
||||
|
||||
@Nonnull
|
||||
private ViewBuilder<View> viewBuilder;
|
||||
|
||||
@Nonnull
|
||||
private String tag;
|
||||
|
||||
public PlotFunctionListItem(@Nonnull PlotFunction plotFunction) {
|
||||
this.plotFunction = plotFunction;
|
||||
this.viewBuilder = ViewFromLayoutBuilder.newInstance(R.layout.cpp_plot_function_list_item);
|
||||
this.tag = PREFIX + plotFunction.getXyFunction().getExpressionString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public OnClickAction getOnClickAction() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public OnClickAction getOnLongClickAction() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public View updateView(@Nonnull Context context, @Nonnull View view) {
|
||||
final Object viewTag = view.getTag();
|
||||
if (viewTag instanceof String) {
|
||||
if (this.tag.equals(viewTag)) {
|
||||
return view;
|
||||
} else if (((String) viewTag).startsWith(PREFIX)) {
|
||||
fillView(view, context);
|
||||
return view;
|
||||
} else {
|
||||
return build(context);
|
||||
}
|
||||
}
|
||||
|
||||
return build(context);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public View build(@Nonnull Context context) {
|
||||
final View root = buildView(context);
|
||||
fillView(root, context);
|
||||
return root;
|
||||
}
|
||||
|
||||
private View buildView(@Nonnull Context context) {
|
||||
return viewBuilder.build(context);
|
||||
}
|
||||
|
||||
private void fillView(@Nonnull View root, @Nonnull final Context context) {
|
||||
root.setTag(tag);
|
||||
|
||||
final CalculatorPlotter plotter = Locator.getInstance().getPlotter();
|
||||
|
||||
final TextView expressionTextView = (TextView) root.findViewById(R.id.cpp_plot_function_expression_textview);
|
||||
expressionTextView.setText(plotFunction.getXyFunction().getExpressionString());
|
||||
|
||||
final CheckBox pinnedCheckBox = (CheckBox) root.findViewById(R.id.cpp_plot_function_pinned_checkbox);
|
||||
pinnedCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean pin) {
|
||||
if (pin) {
|
||||
if (!plotFunction.isPinned()) {
|
||||
plotFunction = plotter.pin(plotFunction);
|
||||
}
|
||||
} else {
|
||||
if (plotFunction.isPinned()) {
|
||||
plotFunction = plotter.unpin(plotFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
pinnedCheckBox.setChecked(plotFunction.isPinned());
|
||||
|
||||
final CheckBox visibleCheckBox = (CheckBox) root.findViewById(R.id.cpp_plot_function_visible_checkbox);
|
||||
visibleCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean show) {
|
||||
if (show) {
|
||||
if (!plotFunction.isVisible()) {
|
||||
plotFunction = plotter.show(plotFunction);
|
||||
}
|
||||
} else {
|
||||
if (plotFunction.isVisible()) {
|
||||
plotFunction = plotter.hide(plotFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
visibleCheckBox.setChecked(plotFunction.isVisible());
|
||||
|
||||
final ImageButton settingsButton = (ImageButton) root.findViewById(R.id.cpp_plot_function_settings_button);
|
||||
settingsButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// FIXME: 2016-02-01
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ package org.solovyev.android.calculator;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import com.squareup.otto.Bus;
|
||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@ -38,7 +37,7 @@ import static org.mockito.Mockito.mock;
|
||||
public class AbstractCalculatorTest {
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
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().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), CalculatorTestUtils.newCalculatorEngine(), mock(Keyboard.class));
|
||||
Locator.getInstance().getEngine().init(new Executor() {
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
|
@ -36,7 +36,6 @@ import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||
import org.solovyev.android.calculator.language.Languages;
|
||||
import org.solovyev.android.calculator.operators.OperatorsRegistry;
|
||||
import org.solovyev.android.calculator.operators.PostfixFunctionsRegistry;
|
||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
||||
|
||||
import jscl.JsclMathEngine;
|
||||
|
||||
@ -68,7 +67,7 @@ public class CalculatorTestUtils {
|
||||
|
||||
public static void staticSetUp() throws Exception {
|
||||
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), 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));
|
||||
Locator.getInstance().getEngine().init(new Executor() {
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
@ -83,7 +82,7 @@ public class CalculatorTestUtils {
|
||||
}
|
||||
|
||||
public static void staticSetUp(@Nullable Context context) throws Exception {
|
||||
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().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), newCalculatorEngine(), mock(Keyboard.class));
|
||||
Locator.getInstance().getEngine().init(new Executor() {
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
|
@ -1,17 +1,40 @@
|
||||
package jscl.math;
|
||||
|
||||
import jscl.math.function.Constant;
|
||||
import jscl.math.function.IConstant;
|
||||
import jscl.mathml.MathML;
|
||||
import jscl.text.ParserUtils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Set;
|
||||
import org.solovyev.common.math.MathRegistry;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class Generic implements Arithmetic<Generic>, Comparable {
|
||||
|
||||
@Nonnull
|
||||
public Set<Constant> getUndefinedConstants(@Nonnull MathRegistry<IConstant> constantsRegistry) {
|
||||
final Set<Constant> result = new HashSet<>();
|
||||
|
||||
for (Constant expressionConstant : getConstants()) {
|
||||
final IConstant registryConstant = constantsRegistry.get(expressionConstant.getName());
|
||||
if (registryConstant == null) {
|
||||
continue;
|
||||
}
|
||||
if (registryConstant.isSystem()) {
|
||||
continue;
|
||||
}
|
||||
if(registryConstant.isDefined()) {
|
||||
continue;
|
||||
}
|
||||
result.add(expressionConstant);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public BigInteger toBigInteger() {
|
||||
return null;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public class CustomFunction extends Function implements IFunction {
|
||||
private CustomFunction(@Nonnull String name,
|
||||
@Nonnull List<String> parameterNames,
|
||||
@Nonnull String content,
|
||||
@Nullable String description) {
|
||||
@Nullable String description) throws CustomFunctionCalculationException {
|
||||
super(name, new Generic[parameterNames.size()]);
|
||||
this.parameterNames = parameterNames;
|
||||
try {
|
||||
@ -321,7 +321,7 @@ public class CustomFunction extends Function implements IFunction {
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public CustomFunction create() {
|
||||
public CustomFunction create() throws CustomFunctionCalculationException {
|
||||
final CustomFunction customFunction = new CustomFunction(name, parameterNames, prepareContent(content), description);
|
||||
customFunction.setSystem(system);
|
||||
if (id != null) {
|
||||
|
Loading…
Reference in New Issue
Block a user