ResultController.java
/*
* Copyright (c) 2016 Vivid Solutions.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.locationtech.jtstest.testbuilder.controller;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.swing.Timer;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.util.Stopwatch;
import org.locationtech.jtstest.geomfunction.GeometryFunction;
import org.locationtech.jtstest.geomfunction.GeometryFunctionInvocation;
import org.locationtech.jtstest.testbuilder.FunctionPanel;
import org.locationtech.jtstest.testbuilder.JTSTestBuilder;
import org.locationtech.jtstest.testbuilder.JTSTestBuilderFrame;
import org.locationtech.jtstest.testbuilder.ResultWKTPanel;
import org.locationtech.jtstest.testbuilder.ScalarFunctionPanel;
import org.locationtech.jtstest.testbuilder.SpatialFunctionPanel;
import org.locationtech.jtstest.testbuilder.model.TestBuilderModel;
import org.locationtech.jtstest.testbuilder.ui.SwingWorker;
public class ResultController
{
private static NumberFormat timeFmt;
static {
timeFmt = NumberFormat.getNumberInstance();
timeFmt.setMinimumFractionDigits(3);
}
public ResultController()
{
}
private static JTSTestBuilderFrame frame() {
return JTSTestBuilderController.frame();
}
private static TestBuilderModel model() {
return JTSTestBuilderController.model();
}
private ResultWKTPanel resultWKTPanel() {
return frame().getResultWKTPanel();
}
public void execute(boolean isCreateNew)
{
SpatialFunctionPanel spatialPanel = frame().getTestCasePanel().getSpatialFunctionPanel();
GeometryFunctionInvocation functionDesc = functionInvocation(spatialPanel);
model().setOpName(functionDesc.getSignature());
resultWKTPanel().setOpName(model().getOpName());
// initialize UI view
clearResult();
// don't run anything if function is null
if (! spatialPanel.isFunctionSelected()) {
return;
}
frame().setCursorWait();
spatialPanel.enableExecuteControl(false);
startFunctionMonitor();
runFunctionWorker(functionDesc, isCreateNew);
// show result unless create new, in which case new case is shown
if (! isCreateNew) frame().showResultWKTTab();
}
private GeometryFunctionInvocation functionInvocation(FunctionPanel functionPanel) {
GeometryFunctionInvocation functionDesc = new GeometryFunctionInvocation(
functionPanel.getFunction(),
model().getGeometryEditModel().getGeometry(0),
functionPanel.getFunctionParams());
return functionDesc;
}
private void clearResult()
{
resultWKTPanel().clearResult();
// for good measure do a GC
System.gc();
updateResult(null,null,null);
}
/**
* If result is null, clears result info.
*
* @param result
* @param object
* @param object
* @param timer
*/
private void resetUI() {
frame().getTestCasePanel().getSpatialFunctionPanel()
.enableExecuteControl(true);
frame().setCursorNormal();
}
private void updateResult(GeometryFunctionInvocation function, Object result, Stopwatch timer) {
model().setResult(result);
String timeString = timer != null ? timer.getTimeString() : "";
resultWKTPanel().setExecutedTime(timeString);
resultWKTPanel().setResult(result);
JTSTestBuilder.controller().geometryViewChanged();
// log it
resultLogEntry(function, timeString, result);
}
private void resultLogEntry(GeometryFunctionInvocation function, String timeString, Object result) {
if (function == null) return;
String funTimeLine = function.getSignature() + " : " + timeString;
String entry = funTimeLine;
String resultDesc = GeometryFunctionInvocation.toString(result);
if (resultDesc != null && resultDesc.length() < 40) entry += "\n ==> " + resultDesc;
JTSTestBuilder.controller().displayInfo(entry, false);
}
private SwingWorker worker = null;
private void runFunctionWorker(final GeometryFunctionInvocation functionInvoc, final boolean createNew)
{
worker = new SwingWorker() {
Stopwatch timer;
public Object construct()
{
return computeResult();
}
private Object computeResult() {
Object result = null;
GeometryFunction currentFunc = functionInvoc.getFunction();
if (currentFunc == null)
return null;
try {
timer = new Stopwatch();
try {
result = currentFunc.invoke(model().getGeometryEditModel()
.getGeometry(0), functionInvoc.getArgs());
} finally {
timer.stop();
}
// result = currentState.getActualValue();
}
catch (Exception ex) {
ex.printStackTrace(System.out);
result = ex;
}
return result;
}
public void finished() {
stopFunctionMonitor();
resetUI();
Object result = getValue();
if (createNew) {
String desc = "Result of " + functionInvoc.getSignature();
JTSTestBuilder.controller().addTestCase(new Geometry[] { (Geometry) result, null }, desc);
} else {
updateResult(functionInvoc, result, timer);
}
worker = null;
}
};
worker.start();
}
private Timer funcTimer;
private long runMillis = 0;
private static final int TIMER_DELAY_IN_MILLIS = 10;
private void startFunctionMonitor()
{
runMillis = 0;
if (funcTimer != null) {
funcTimer.stop();
}
funcTimer = new Timer(TIMER_DELAY_IN_MILLIS, new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Stopwatch timer = testCasePanel.getSpatialFunctionPanel().getTimer();
runMillis += TIMER_DELAY_IN_MILLIS;
String timeStr = "";
if (runMillis < 10000) {
timeStr = runMillis + " ms";
}
else {
timeStr = timeFmt.format(runMillis/1000.0) + " s";
}
resultWKTPanel().setRunningTime(timeStr);
}
});
funcTimer.setInitialDelay(0);
funcTimer.start();
}
private void stopFunctionMonitor()
{
funcTimer.stop();
}
public void executeScalarFunction()
{
/**
* For now scalar functions are executed on the calling thread.
* They are expected to be of short duration
*/
ScalarFunctionPanel scalarPanel = frame().getTestCasePanel().getScalarFunctionPanel();
String opName = scalarPanel.getOpName();
// initialize UI view
frame().getResultValuePanel().setResult(opName, "", null);
frame().showResultValueTab();
frame().setCursorWait();
Object result = scalarPanel.getResult();
frame().setCursorNormal();
Stopwatch timer = scalarPanel.getTimer();
String timeString = timer.getTimeString();
frame().getResultValuePanel().setResult(opName, timer.getTimeString(), result);
resultLogEntry(functionInvocation(scalarPanel), timeString, result);
}
}