package org.geogebra.common.jre.cas.giac;
import org.geogebra.common.cas.CASparser;
import org.geogebra.common.cas.error.TimeoutException;
import org.geogebra.common.cas.giac.CASgiacB;
import org.geogebra.common.cas.giac.binding.CASGiacBinding;
import org.geogebra.common.jre.cas.giac.binding.CASGiacBindingJre;
import org.geogebra.common.util.debug.Log;
/**
* Giac for Desktop and Android
*/
public abstract class CASgiacJre extends CASgiacB {
/**
* @param casParser casParser
* @param k Kernel
*/
public CASgiacJre(CASparser casParser) {
super(casParser);
}
@Override
public CASGiacBinding createBinding() {
return new CASGiacBindingJre();
}
@Override
protected void callEvaluateFunction(Runnable evaluateFunction) throws Throwable {
if (useThread()) {
// send expression to CAS
Thread thread = new EvaluateThread(evaluateFunction);
thread.start();
thread.join(timeoutMillis);
thread.interrupt();
// thread.interrupt() doesn't seem to stop it, so add this for
// good measure:
stopThread(thread);
// in fact, stop will do nothing (never implemented)
// Log.debug("giac: after interrupt/stop");
// if we haven't got a result, CAS took too long to return
// eg Solve[sin(5/4 pi+x)-cos(x-3/4 pi)=sqrt(6) *
// cos(x)-sqrt(2)]
if (threadResult == null) {
Log.debug("Thread timeout from Giac");
throw new TimeoutException("Thread timeout from Giac");
}
} else {
evaluateFunction.run();
}
}
protected abstract boolean useThread();
protected abstract void stopThread(Thread thread);
class EvaluateThread extends Thread {
private Runnable evaluateFunction;
public EvaluateThread(Runnable evaluateFunction) {
this.evaluateFunction = evaluateFunction;
}
@Override
public void run() {
try {
evaluateFunction.run();
} catch (Throwable t) {
Log.debug("problem from JNI Giac: " + t.toString());
// force error in GeoGebra
threadResult = "(";
}
}
}
}