Skip to content

Commit

Permalink
csg based instrumentation seems to work! (related to issue #58)
Browse files Browse the repository at this point in the history
  • Loading branch information
miho committed Aug 10, 2015
1 parent d387b5d commit 813a8a7
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public void start(Stage primaryStage) {
primaryStage.setScene(scene);
primaryStage.show();

controller.loadTextFile(new File("MainWithChainedInvocations.groovy"));
controller.loadTextFile(new File("InstrumentationMain.groovy"));
// controller.loadTextFile(new File("NB-Sample/src/main/groovy/Main.groovy"));

scene.getStylesheets().add("/eu/mihosoft/vrl/ui/codevisualization/default.css");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
package eu.mihosoft.vrl.ui.codevisualization;

import com.thoughtworks.xstream.XStream;
import eu.mihosoft.vrl.instrumentation.InstrumentationEvent;
import eu.mihosoft.vrl.instrumentation.InstrumentationEventType;
import eu.mihosoft.vrl.instrumentation.VRLInstrumentationUtil;
import eu.mihosoft.vrl.instrumentation.VRLVisualizationTransformation;
import eu.mihosoft.vrl.lang.model.Scope2Code;
import eu.mihosoft.vrl.lang.model.ScopeInvocation;
Expand All @@ -64,6 +67,7 @@
import eu.mihosoft.vrl.lang.model.Invocation;
import eu.mihosoft.vrl.lang.model.Scope;
import eu.mihosoft.vrl.lang.model.WhileDeclaration;
import eu.mihosoft.vrl.lang.model.transform.InstrumentCode;
import eu.mihosoft.vrl.workflow.Connection;
import eu.mihosoft.vrl.workflow.Connections;
import eu.mihosoft.vrl.workflow.Connector;
Expand All @@ -78,11 +82,13 @@
import eu.mihosoft.vrl.workflow.fx.ScaleBehavior;
import eu.mihosoft.vrl.workflow.fx.TranslateBehavior;
import eu.mihosoft.vrl.workflow.fx.VCanvas;
import eu.mihosoft.vrl.workflow.skin.VNodeSkin;
import groovy.lang.GroovyClassLoader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
Expand Down Expand Up @@ -120,6 +126,7 @@
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer;

Expand Down Expand Up @@ -163,10 +170,9 @@ public void initialize(URL url, ResourceBundle rb) {
canvas.setMinScaleY(0.2);
canvas.setMaxScaleX(1);
canvas.setMaxScaleY(1);

// canvas.setScaleBehavior(ScaleBehavior.IF_NECESSARY);
// canvas.setTranslateBehavior(TranslateBehavior.IF_NECESSARY);

addResetViewMenu(canvas);

ScrollPane scrollPane = new ScrollPane(canvas);
Expand All @@ -179,7 +185,6 @@ public void initialize(URL url, ResourceBundle rb) {

rootPane.setStyle("-fx-background-color: linear-gradient(to bottom, rgb(10,32,60), rgb(42,52,120));");


flow = FlowFactory.newFlow();
flow.setVisible(true);
flow.getModel().getVisualizationRequest().set(
Expand Down Expand Up @@ -292,6 +297,11 @@ public void onSaveAsAction(ActionEvent e) {
public void onCloseAction(ActionEvent e) {
}

@FXML
public void onRunCodeAction(ActionEvent e) {
runCode();
}

public void loadTextFile(File f) {

try {
Expand Down Expand Up @@ -358,6 +368,99 @@ public void onFileChange(File file) {

}

private Optional<VNode> getNodeByCodeId(VFlowModel flow, String id) {

System.out.println("-> searching for: " + id);

for (VNode vn : flow.getNodes()) {

boolean valObjectIsCodeEntity
= vn.getValueObject().getValue() instanceof CodeEntity;

if (valObjectIsCodeEntity) {
CodeEntity ce = (CodeEntity) vn.getValueObject().getValue();

if (Objects.equals(ce.getId(), id)) {
return Optional.of(vn);
}
}

if (vn instanceof VFlowModel) {
VFlowModel subFlow = (VFlowModel) vn;
Optional<VNode> res = getNodeByCodeId(subFlow, id);

if (res.isPresent()) {
return res;
}
}

}

return Optional.empty();
}

// private Optional<VNode> _getNodeByCodeId(VFlow flow, String id) {
// return flow.getNodes().stream().
// filter((vn) -> {
// return vn.getValueObject() instanceof CodeEntity;
// }).
// map((vn) -> {
// return (CodeEntity) vn.getValueObject();
// }).
// filter((ce) -> {
// return Objects.equals(ce.getId(),
// id);
// }).findFirst().map(ce -> ce.getNode());
// }
private void runCode() {

CompilationUnitDeclaration cu
= (CompilationUnitDeclaration) UIBinding.scopes.values().
iterator().next().get(0);

// copy cu
// TODO 10.08.2015 add copy/cloning functionality (see todos in model)
updateView();
InstrumentCode instrumentCode = new InstrumentCode();
CompilationUnitDeclaration newCu = instrumentCode.transform(cu);

String instrumentedCode = Scope2Code.getCode(newCu);

VRLInstrumentationUtil.addEventHandler(
InstrumentationEventType.PRE_INVOCATION,
(evt) -> {
System.out.println("pre-evt:\t" + evt.toString());
});
VRLInstrumentationUtil.addEventHandler(
InstrumentationEventType.POST_INVOCATION,
(evt) -> {
System.out.println("post-evt:\t" + evt.toString());
});

VRLInstrumentationUtil.addEventHandler(
InstrumentationEventType.POST_INVOCATION,
(evt) -> {
getNodeByCodeId(
flow.getModel(),
evt.getSource().getId()).ifPresent(
vn -> {
visualizeEvent(evt, vn);
});
});

System.out.println(instrumentedCode);

try {
GroovyClassLoader gcl = new GroovyClassLoader();
Class<?> instrumentedCodeClass = gcl.parseClass(instrumentedCode);
instrumentedCodeClass.getMethod("main", String[].class).
invoke(instrumentedCodeClass, (Object) new String[0]);

} catch (CompilationFailedException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(MainWindowController.class.getName()).log(Level.SEVERE, null, ex);
}
}

private void updateView() {

savePositions();
Expand Down Expand Up @@ -745,6 +848,25 @@ static void addResetViewMenu(VCanvas canvas) {
}
});
}

private void visualizeEvent(InstrumentationEvent evt, VNode vn) {
System.out.println("vn: " + vn.getId());

if (vn.getValueObject().getValue() instanceof CodeEntity) {
CodeEntity ce = (CodeEntity) vn.getValueObject().getValue();
ce.getMetaData().put("VRL:retVal", evt.getSource().getReturnValue().orElse(null));
}

// List<VNodeSkin> skins = flow.getNodeSkinLookup().getById(vn.getId());
//
// skins.stream().filter(sk -> sk instanceof VariableFlowNodeSkin).
// map((sk) -> {
// return (VariableFlowNodeSkin) sk;
// }).
// forEach(sk -> {
// sk.updateOutputView(evt.getSource().getReturnValue());
// });
}
}

class LayoutData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import eu.mihosoft.vrl.lang.model.Argument;
import eu.mihosoft.vrl.lang.model.ArgumentType;
import eu.mihosoft.vrl.lang.model.CodeEntity;
import eu.mihosoft.vrl.lang.model.CodeEvent;
import eu.mihosoft.vrl.lang.model.CodeEventType;
import eu.mihosoft.vrl.lang.model.IArgument;
Expand All @@ -15,23 +16,34 @@
import eu.mihosoft.vrl.lang.model.Scope;
import eu.mihosoft.vrl.lang.model.ScopeInvocation;
import eu.mihosoft.vrl.lang.model.Type;
import eu.mihosoft.vrl.v3d.jcsg.CSG;
import eu.mihosoft.vrl.v3d.jcsg.MeshContainer;
import eu.mihosoft.vrl.v3d.jcsg.VFX3DUtil;
import eu.mihosoft.vrl.workflow.VFlow;
import eu.mihosoft.vrl.workflow.VNode;
import eu.mihosoft.vrl.workflow.fx.FXSkinFactory;
import eu.mihosoft.vrl.workflow.fx.ScaleBehavior;
import eu.mihosoft.vrl.workflow.fx.TranslateBehavior;
import eu.mihosoft.vrl.workflow.fx.VCanvas;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.collections.ListChangeListener;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.PerspectiveCamera;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.MeshView;

/**
*
Expand All @@ -40,6 +52,7 @@
public class VariableFlowNodeSkin extends CustomFlowNodeSkin {

private boolean updating;
private VBox outputs;

public VariableFlowNodeSkin(FXSkinFactory skinFactory, VNode model, VFlow controller) {
super(skinFactory, model, controller);
Expand All @@ -55,11 +68,11 @@ public void configureCanvas(VCanvas canvas) {

@Override
protected Node createView() {

ComboBox<MethodDeclaration> box = new ComboBox<>();

VBox parent = new VBox(box);

parent.setAlignment(Pos.CENTER);

Object value = getModel().getValueObject().getValue();
Expand All @@ -80,11 +93,11 @@ protected Node createView() {
// }
// }
Invocation invocation = (Invocation) value;

box.setVisible(!invocation.getArguments().isEmpty());

VBox inputs = new VBox();
VBox outputs = new VBox();
outputs = new VBox();
HBox hbox = new HBox(inputs, outputs);
hbox.setPadding(new Insets(0, 15, 0, 15));

Expand All @@ -101,6 +114,26 @@ protected Node createView() {
});
parent.getChildren().add(hbox);
}



if (getModel().getValueObject().getValue() instanceof CodeEntity) {
CodeEntity ce = (CodeEntity) getModel().getValueObject().getValue();
updateOutputView(ce.getMetaData().get("VRL:retVal"));

ce.getMetaData().addListener((Observable observable) -> {
updateOutputView(ce.getMetaData().get("VRL:retVal"));
});
}

getModel().getValueObject().valueProperty().addListener((ov, oldV, newV) -> {
if (newV instanceof CodeEntity) {
CodeEntity ce = (CodeEntity) newV;
ce.getMetaData().addListener((Observable observable) -> {
updateOutputView(ce.getMetaData().get("VRL:retVal"));
});
}
});

return parent;
}
Expand Down Expand Up @@ -204,4 +237,63 @@ private void createArgView(Invocation invocation, VBox inputs, boolean update) {

updating = false;
}

private void setMeshScale(MeshContainer meshContainer, Bounds t1, final MeshView meshView) {
double maxDim
= Math.max(meshContainer.getWidth(),
Math.max(meshContainer.getHeight(), meshContainer.getDepth()));

double minContDim = Math.min(t1.getWidth(), t1.getHeight());

double scale = minContDim / (maxDim * 2);

//System.out.println("scale: " + scale + ", maxDim: " + maxDim + ", " + meshContainer);
meshView.setScaleX(scale);
meshView.setScaleY(scale);
meshView.setScaleZ(scale);
}

void updateOutputView(Object retVal) {
if (outputs == null) {
return;
}

outputs.getChildren().clear();

CSG csg;

if (retVal instanceof CSG) {
csg = (CSG) retVal;

Group viewGroup = new Group();

SubScene subScene = new SubScene(viewGroup, 300, 200, true, SceneAntialiasing.DISABLED);
// subScene.setFill(Color.WHEAT);
PerspectiveCamera subSceneCamera = new PerspectiveCamera(false);
subScene.setCamera(subSceneCamera);

MeshContainer mc = csg.toJavaFXMesh();

MeshView mv = mc.getAsMeshViews().get(0);
// mv.setScaleX(10);
// mv.setScaleY(10);
// mv.setScaleZ(10);

setMeshScale(mc, subScene.getBoundsInLocal(), mv);

VFX3DUtil.addMouseBehavior(mv, subScene, MouseButton.PRIMARY);

viewGroup.layoutXProperty().bind(subScene.widthProperty().divide(2));
viewGroup.layoutYProperty().bind(subScene.heightProperty().divide(2));

viewGroup.getChildren().addAll(mv);

outputs.getChildren().addAll(subScene);
} else if (retVal != null) {
outputs.getChildren().add(new Label(retVal.toString()));
} else {
outputs.getChildren().add(new Label("null"));
}

}
}

0 comments on commit 813a8a7

Please sign in to comment.