package org.trianacode.shiwaall.iwir.holders;
import org.trianacode.shiwaall.iwir.factory.AbstractTaskHolder;
import org.trianacode.shiwaall.iwir.factory.models.IWIRControlComponentModel;
import org.trianacode.taskgraph.*;
import org.trianacode.taskgraph.imp.RenderingHintImp;
import org.trianacode.taskgraph.imp.ToolImp;
import org.trianacode.taskgraph.proxy.ProxyFactory;
import org.trianacode.taskgraph.proxy.java.JavaProxy;
import org.trianacode.taskgraph.tool.Tool;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
// TODO: Auto-generated Javadoc
/**
* Created by IntelliJ IDEA.
* User: Ian Harvey
* Date: 09/03/2011
* Time: 14:33
* To change this template use File | Settings | File Templates.
*/
public class ParallelForEachTaskHolder extends AbstractTaskHolder {
/** The parallel task. */
private Tool parallelTask;
/** The all inputs. */
ArrayList<Object> allInputs;
/** The attachments. */
HashMap<Task, Node> attachments;
/** The parent. */
TaskGraph parent;
//add arraylists to hold new nodes
/* (non-Javadoc)
* @see org.trianacode.shiwaall.iwir.factory.AbstractTaskHolder#init()
*/
public void init() {
super.init();
defineParameter("count", "0", Unit.USER_ACCESSIBLE);
setGUIBuilderV2Info("Loops $title count IntScroller 0 100 0");
getTask().addRenderingHint(
new RenderingHintImp(
IWIRControlComponentModel.IWIR_CONTROL_RENDERING_HINT, false
)
);
}
/* (non-Javadoc)
* @see org.trianacode.taskgraph.Unit#process()
*/
@Override
public void process() throws Exception {
parent = this.getTask().getParent();
ArrayList<Task> addedTasks = new ArrayList<Task>();
//assuming the parallel task is atomic, not something loopy and horrible.
Unit parallelUnit = new AtomicTaskHolder();
//assuming theres an executable which can do something.
// ((AtomicTaskHolder) parallelUnit).setExecutable(new Executable());
int parallelNumber = 0;
allInputs = new ArrayList<Object>();
System.out.println("Connected nodes : " + this.getInputNodeCount());
for (int i = 0; i < this.getInputNodeCount(); i++) {
Object inputObject = getInputAtNode(i);
allInputs.add(inputObject);
if (inputObject instanceof List) {
int thisSize = ((List) inputObject).size();
if (thisSize > parallelNumber) {
parallelNumber = thisSize;
}
}
}
attachments = new HashMap<Task, Node>();
for (int i = 0; i < allInputs.size(); i++) {
Object inputData = allInputs.get(i);
if (inputData instanceof List) {
System.out.println("\nRuntime task creator will attempt to add : " + ((List) inputData).size());
for (Object inputFromList : (List) inputData) {
Unit unit = parallelUnit.getClass().newInstance();
Task addedTask = createTask(unit);
connectTask(addedTask);
addedTasks.add(addedTask);
}
} else {
Unit unit = parallelUnit.getClass().newInstance();
Task addedTask = createTask(unit);
connectTask(addedTask);
addedTasks.add(addedTask);
}
}
//TODO currently organising before connecting and creating cycles - check for cycles
// DaxOrganize daxOrganize = new DaxOrganize(this.getTask().getParent());
addLoopbackCable(addedTasks);
sendData(addedTasks);
}
/**
* Send data.
*
* @param addedTasks the added tasks
*/
private void sendData(ArrayList<Task> addedTasks) {
for (int i = 0; i < allInputs.size(); i++) {
Object input = allInputs.get(0);
if (input instanceof List) {
List inputList = (List) input;
for (Task task : addedTasks) {
Node node = attachments.get(task);
if (node != null) {
int outputNodeNumber = node.getAbsoluteNodeIndex();
if (outputNodeNumber <= i && inputList.size() >= i) {
outputAtNode(attachments.get(task).getAbsoluteNodeIndex(), inputList.get(i));
System.out.println("Output " +
inputList.get(i) +
" to node : " +
outputNodeNumber);
}
}
}
} else {
for (Task task : addedTasks) {
Node node = attachments.get(task);
if (node != null) {
int outputNodeNumber = node.getAbsoluteNodeIndex();
if (outputNodeNumber <= i) {
outputAtNode(attachments.get(task).getAbsoluteNodeIndex(), input);
}
}
}
}
}
}
/**
* Adds the loopback cable.
*
* @param addedTasks the added tasks
*/
private void addLoopbackCable(ArrayList<Task> addedTasks) {
for (Task newTask : addedTasks) {
try {
Node thisTaskInputNode = this.getTask().addDataInputNode();
System.out.println("Added input node : " + thisTaskInputNode.getNodeIndex());
Node nextTaskOutputNode = newTask.addDataOutputNode();
Cable loopBackCable = parent.connect(nextTaskOutputNode, thisTaskInputNode);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Creates the task.
*
* @param unit the unit
* @return the task
*/
public Task createTask(Unit unit) {
return createTask(createTool(unit));
}
/**
* Creates the task.
*
* @param tool the tool
* @return the task
*/
private Task createTask(Tool tool) {
Task newTask = null;
try {
newTask = parent.createTask(tool);
newTask.setParameter(Task.GUI_X, this.getParameter(Task.GUI_X));
newTask.setParameter(Task.GUI_Y, this.getParameter(Task.GUI_Y));
} catch (TaskException e) {
e.printStackTrace();
}
return newTask;
}
/**
* Connect task.
*
* @param newTask the new task
*/
private void connectTask(Task newTask) {
try {
Node thisTaskOutputNode = this.getTask().addDataOutputNode();
System.out.println("Added output node : " + thisTaskOutputNode.getNodeIndex());
Node nextTaskInputNode = newTask.addDataInputNode();
Cable dataOutCable = parent.connect(thisTaskOutputNode, nextTaskInputNode);
if (dataOutCable.isConnected()) {
attachments.put(newTask, thisTaskOutputNode);
}
} catch (CableException e) {
e.printStackTrace();
} catch (NodeException e) {
e.printStackTrace();
}
}
/**
* Adds the and connect tool.
*
* @param tool the tool
* @param data the data
* @return the task
*/
private Task addAndConnectTool(Tool tool, Object data) {
TaskGraph parent = this.getTask().getParent();
Task newTask = null;
try {
Tool clonedTool = TaskGraphUtils.cloneTool(tool);
newTask = parent.createTask(clonedTool, true);
Node thisTaskOutputNode = this.getTask().addDataOutputNode();
System.out.println("Added output node : " + thisTaskOutputNode.getNodeIndex());
Node nextTaskInputNode = newTask.addDataInputNode();
Cable dataOutCable = parent.connect(thisTaskOutputNode, nextTaskInputNode);
if (dataOutCable.isConnected() && data != null) {
System.out.println("Output " + data.toString() + " to node : " + thisTaskOutputNode.getNodeIndex());
outputAtNode(thisTaskOutputNode.getNodeIndex(), data);
}
} catch (TaskException e) {
e.printStackTrace();
} catch (CableException e) {
System.out.println("Failed to add cable");
e.printStackTrace();
}
return newTask;
}
/**
* Creates the tool.
*
* @param unit the unit
* @return the tool imp
*/
private ToolImp createTool(Unit unit) {
ToolImp tool = null;
ProxyFactory.initProxyFactory();
try {
tool = new ToolImp(this.getTask().getProperties());
tool.setProxy(new JavaProxy(unit, unit.getClass().getSimpleName(), unit.getClass().getPackage().getName()));
tool.setToolName(unit.getClass().getSimpleName());
tool.setToolPackage(unit.getClass().getPackage().getName());
} catch (Exception e) {
System.out.println("Failed to initialise tool from Unit.");
e.printStackTrace();
}
return tool;
}
/**
* Sets the parallel task.
*
* @param parallelTask the new parallel task
*/
public void setParallelTask(Task parallelTask) {
this.parallelTask = parallelTask;
}
}