+/* $Id: PipeAndFilterModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.PipeAndFilter;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.Resource;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the main program.
+ */
+public class PipeAndFilterModuleVisitor extends PNVisitor {
+
+ /**
+ * Constructor.
+ */
+ public PipeAndFilterModuleVisitor(String dir) {
+ _dir = dir;
+ }
+
+ public void visitComponent(ProcessNetwork x) {
+ try {
+ String filename = _dir + _delimiter + "sc_application.cpp";
+ OutputStream file = new FileOutputStream(filename);
+ _code = new CodePrintStream(file);
+
+ _code.println("#include <iostream>");
+ _code.println();
+
+ _code.printPrefixln("#include \"lib/Fifo.h\"");
+ _code.printPrefixln("#include \"lib/Scheduler.h\"");
+ _code.printPrefixln("#include \"lib/WindowedFifo.h\"");
+ _code.println();
+ _code.printPrefixln("#include \"wrappers/wrappers.h\"");
+ _code.println();
+ _code.printPrefixln("#include \"processnetwork.h\"");
+ _code.println();
+ _code.printPrefixln("int main(void)");
+ _code.printLeftBracket();
+
+ _code.printPrefixln("std::map<std::string, "
+ + "ProcessWrapper* > *processes");
+ _code.printPrefixln(" = new std::map<std::string, "
+ + "ProcessWrapper* >();");
+ _code.println();
+
+ _code.printPrefixln("Scheduler *scheduler = "
+ + "new Scheduler();");
+ _code.println();
+
+ //instantiate channels
+ for (Channel c : x.getChannelList()) {
+ if (c.getType().equals("fifo")) {
+ printProcessNetwork("Fifo *" + c.getName()
+ + " = new Fifo(\"" + c.getName()
+ + "\", " + c.getSize() * c.getTokenSize()
+ + ");");
+ } else if (c.getType().equals("wfifo")) {
+ printProcessNetwork("WindowedFifo *" + c.getName()
+ + " = new WindowedFifo(\"" + c.getName()
+ + "\", " + c.getSize() * c.getTokenSize()
+ + ");");
+ }
+ }
+ printProcessNetwork("");
+
+ // instantiate processes and connect to channels
+ for (Process p : x.getProcessList()) {
+ printProcessNetwork(p.getBasename() + "_wrapper *"
+ + p.getName() + " = new "
+ + p.getBasename() + "_wrapper(\""
+ + p.getName() + "\");");
+ printProcessNetwork("processes->insert(std::pair"
+ + "<std::string, ProcessWrapper* >(\""
+ + p.getName() + "\", " + p.getName() + "));");
+ printProcessNetwork("");
+ }
+
+ //build the network
+ for (Channel ch : x.getChannelList()) {
+ ch.accept(this);
+ }
+
+ printProcessNetwork("}");
+
+ String headerfilename = _dir + _delimiter
+ + "processnetwork.h";
+ OutputStream headerfile = new FileOutputStream(
+ headerfilename);
+ CodePrintStream processnetworkHeader = new
+ CodePrintStream(headerfile);
+ processnetworkHeader.printPrefixln(
+ "#ifndef PROCESSNETWORK_H");
+ processnetworkHeader.printPrefixln(
+ "#define PROCESSNETWORK_H");
+ processnetworkHeader.println();
+
+ for (int counter = 1; counter <= _processNetworkCounter;
+ counter++) {
+ _code.printPrefixln("processnetwork_part"
+ + String.format("%03d", counter) + "::create("
+ + "processes);");
+ processnetworkHeader.println("#include "
+ + "\"processnetwork_part"
+ + String.format("%03d", counter) + ".h\"");
+ }
+ _code.println();
+
+ processnetworkHeader.println();
+ processnetworkHeader.printPrefixln("#endif");
+
+
+ //register processes
+ _code.printPrefixln("std::map<std::string, "
+ + "ProcessWrapper* >::iterator process_iterator;");
+ _code.printPrefixln("for (process_iterator = "
+ + "processes->begin();");
+ _code.printPrefixln(" process_iterator != "
+ + "processes->end();");
+ _code.printPrefixln(" process_iterator++) {");
+ _code.printPrefixln(" scheduler->registerProcess("
+ + "static_cast<ProcessWrapper* >");
+ _code.printPrefixln(" ((*process_iterator).second));");
+ _code.printPrefixln("}");
+ _code.println();
+
+ //run scheduler
+ _code.printPrefixln("scheduler->run();");
+ _code.println();
+
+ //clean up
+ _code.println();
+ _code.printPrefixln("for (process_iterator = "
+ + "processes->begin();");
+ _code.printPrefixln(" process_iterator != "
+ + "processes->end();");
+ _code.printPrefixln(" process_iterator++) {");
+ _code.printPrefixln(" delete static_cast<ProcessWrapper* >"
+ + "((*process_iterator).second);");
+ _code.printPrefixln("}");
+ _code.println();
+ //_code.printPrefixln("std::cout << \"End.\" << std::endl;");
+ _code.printPrefixln("return 0;");
+ _code.printRightBracket();
+ }
+ catch (Exception e) {
+ System.out.println("PipeAndFilterModuleVisitor: "
+ + "exception occured: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ *
+ */
+ protected void createProcessNetworkHeader(int part)
+ throws IOException {
+ String partString = String.format("%03d", part);
+ String filename = _dir + _delimiter + "processnetwork_part"
+ + partString + ".h";
+ OutputStream file = new FileOutputStream(filename);
+ CodePrintStream header = new CodePrintStream(file);
+
+ header.println("#ifndef PROCESSNETWORK_PART"
+ + partString + "_H");
+ header.println("#define PROCESSNETWORK_PART"
+ + partString + "_H");
+ header.println();
+ header.println("#include <map>");
+ header.println("#include <string>");
+ header.println();
+ header.println("#include \"lib/ProcessWrapper.h\"");
+ header.println("#include \"lib/Fifo.h\"");
+ header.println("#include \"lib/WindowedFifo.h\"");
+ header.println();
+ header.println("#include \"wrappers/wrappers.h\"");
+ header.println();
+ header.println("class processnetwork_part" + partString + " {");
+ header.println(" public:");
+ header.println(" processnetwork_part"
+ + partString + "();");
+ header.println(" virtual ~processnetwork_part"
+ + partString + "();");
+ header.println(" static void create(");
+ header.println(" std::map<std::string, "
+ + "ProcessWrapper* > *processes);");
+ header.println("};");
+ header.println();
+ header.println("#endif");
+ }
+
+
+ /**
+ *
+ */
+ protected void printProcessNetwork(String nextLine)
+ throws IOException {
+ if (!_fileOpen ||
+ (_numberOfLines >= MAX_NUMBER_OF_LINES &&
+ !nextLine.contains("->insert") &&
+ !nextLine.equals("") &&
+ !nextLine.contains("Port(") &&
+ !nextLine.contains("<std::string, Port* >"))) {
+
+ if (_fileOpen) {
+ _pn.printRightBracket();
+ }
+
+ _processNetworkCounter++;
+ _numberOfLines = 0;
+ createProcessNetworkHeader(_processNetworkCounter);
+ String partString = String.format("%03d",
+ _processNetworkCounter);
+ String processNetworkFilename = _dir + _delimiter
+ + "processnetwork_part" + partString + ".cpp";
+
+ _file = new FileOutputStream(processNetworkFilename);
+ _pn = new CodePrintStream(_file);
+ _fileOpen = true;
+
+ _pn.printPrefixln("#include \"processnetwork_part"
+ + partString + ".h\"");
+ _pn.println();
+
+ _pn.printPrefixln("processnetwork_part" + partString
+ + "::processnetwork_part" + partString + "() {");
+ _pn.printPrefixln(" //nothing to do");
+ _pn.printPrefixln("}");
+ _pn.println();
+ _pn.printPrefixln("processnetwork_part" + partString
+ + "::~processnetwork_part" + partString + "() {");
+ _pn.printPrefixln(" //nothing to do");
+ _pn.printPrefixln("}");
+ _pn.println();
+ _pn.printPrefixln("void processnetwork_part" + partString
+ + "::create(");
+ _pn.printPrefixln(" std::map<std::string, "
+ + "ProcessWrapper* > *processes)");
+ _pn.printLeftBracket();
+ }
+
+ _pn.printPrefixln(nextLine);
+ _numberOfLines++;
+ }
+
+ /**
+ *
+ * @param x channel that needs to be rendered
+ */
+ public void visitComponent(Channel x) {
+ try {
+ for (Port p : x.getPortList()) {
+ Port peerPort = (Port)(p.getPeerPort());
+ Resource peerResource = p.getPeerResource();
+ String codeLine = "";
+ if (peerPort.getRange() != null) {
+ if (p.isOutPort()) {
+ codeLine = peerResource.getName()
+ + "->INPORT_"
+ + peerPort.getBasename()
+ + peerPort.getName().replaceAll(
+ "_([0-9]+)", "[$1]").replaceFirst(
+ peerPort.getBasename(), "");
+ }
+ else if (p.isInPort()) {
+ codeLine = peerResource.getName()
+ + "->OUTPORT_"
+ + peerPort.getBasename()
+ + peerPort.getName().replaceAll(
+ "_([0-9]+)", "[$1]").replaceFirst(
+ peerPort.getBasename(), "");
+ }
+ }
+ else {
+ if (p.isOutPort()) {
+ codeLine = peerResource.getName()
+ + "->INPORT_" + peerPort.getName();
+ }
+ else if (p.isInPort()) {
+ codeLine = peerResource.getName()
+ + "->OUTPORT_" + peerPort.getName();
+ }
+ }
+ printProcessNetwork(codeLine + " = " + x.getName() + ";");
+ }
+ }
+ catch (Exception e) {
+ System.out.println("PipeAndFilterModuleVisitor: "
+ + "exception occured: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ protected CodePrintStream _code = null;
+ protected String _dir = null;
+ protected boolean _fileOpen = false;
+ protected int _processNetworkCounter = 0;
+ protected int _numberOfLines = 0;
+ protected static final int MAX_NUMBER_OF_LINES = 1000;
+ protected OutputStream _file;
+ protected CodePrintStream _pn;
+}
+