Commit 575485a7 authored by Alexander David Hellwig's avatar Alexander David Hellwig
Browse files

Moved template strings into files

parent d83a6800
......@@ -59,7 +59,7 @@ public class DistributedTargetGenerator extends CMakeGenerator {
//TODO:refactor, dont always generate
private File generateRosMsgGen() throws IOException {
File file = new File(generationTargetPath + "rosMsg/CMakeLists.txt");
FileUtils.write(file, TemplateHelper.struct_msgsCmakeTemplate);
FileUtils.write(file, TemplateHelper.getStruct_msgsCmakeTemplate());
return file;
}
......
......@@ -33,7 +33,7 @@ public class MiddlewareGenerator extends CMakeGenerator {
FileContent res = new FileContent();
String name = NameHelper.getComponentNameTargetLanguage(componentInstanceSymbol.getFullName());
res.setFileName("IAdapter_" + name + ".h");
res.setFileContent(TemplateHelper.iAdapterTemplate.replace("${compName}", name));
res.setFileContent(TemplateHelper.getIAdapterTemplate().replace("${compName}", name));
return res;
}
......@@ -59,7 +59,7 @@ public class MiddlewareGenerator extends CMakeGenerator {
.map(fn -> " adapters.push_back(new " + fn + "());")
.collect(Collectors.joining("\n"));
String content = TemplateHelper.coordinatorTemplate
String content = TemplateHelper.getCoordinatorTemplate()
.replace("${compName}", name)
.replace("${includes}", includes)
.replace("${addAdapters}", addAdapters);
......@@ -83,7 +83,7 @@ public class MiddlewareGenerator extends CMakeGenerator {
.map(fn -> fn.substring(0, fn.length() - 2))
.collect(Collectors.joining(" "));
String content = TemplateHelper.coordinatorCmakeListsTemplate
String content = TemplateHelper.getCoordinatorCmakeListsTemplate()
.replace("${targets}", targets)
.replace("${compName}", name);
......
package de.monticore.lang.monticar.generator.middleware.helpers;
public class TemplateHelper {
public static String coordinatorTemplate =
"#include <iostream>\n" +
"#include <thread>\n" +
"#include <chrono>\n" +
"#include <atomic>\n" +
"#include <list>\n" +
"#include \"IAdapter_${compName}.h\"\n" +
"\n" +
"${includes}" +
"\n" +
"using namespace std;\n" +
"using namespace chrono;\n" +
"\n" +
"static int exeMs = 100;\n" +
"\n" +
"bool parseCommandLineParameters(int argc, char* argv[]){\n" +
" if(argc == 1){\n" +
" return true;\n" +
" }\n" +
" if(argc == 3 && string(argv[1]) == \"-t\"){\n" +
" try{\n" +
" int tmp = stoi(argv[2]);\n" +
" if(tmp >= 0){\n" +
" exeMs = tmp;\n" +
" return true;\n" +
" }\n" +
" }catch(...){\n" +
" //Ignore\n" +
" }\n" +
" }\n" +
" cout << \"Usage: \" << argv[0] << \" [-h | -t sleepTimeMs]\\n\";\n" +
" return false;\n" +
"}\n" +
"\n" +
"void startMiddleware(IAdapter_${compName}& adapter,${compName}& comp,atomic<bool>& done){\n" +
" adapter.init(&comp);\n" +
" done = true;\n" +
"}\n" +
"\n" +
"int main(int argc, char* argv[])\n" +
"{\n" +
" if(!parseCommandLineParameters(argc,argv)){\n" +
" return 1;\n" +
" }\n" +
"\n" +
" atomic<bool> done(false);\n" +
" ${compName} comp;\n" +
" comp.init();\n" +
"\n" +
" list<IAdapter_${compName}*> adapters;\n" +
"${addAdapters}" +
"\n" +
" list<thread*> threads;\n" +
" for(auto a : adapters){\n" +
" threads.push_back(new thread(startMiddleware,ref(*a),ref(comp),ref(done)));\n" +
" }\n" +
"\n" +
" cout << \"waiting for all middleware to start\\n\";\n" +
" this_thread::sleep_for(seconds(3));\n" +
" cout << \"started! Executing every \" << exeMs << \"ms\\n\";\n" +
"\n" +
" time_point<system_clock> start, end;\n" +
" while(!done){\n" +
" start = system_clock::now();\n" +
"\n" +
" comp.execute();\n" +
" for(auto a : adapters){\n" +
" (*a).tick();\n" +
" }\n" +
"\n" +
" end = system_clock::now();\n" +
" int elapsedMs = duration_cast<milliseconds>(end-start).count();\n" +
" int newSleep = exeMs - elapsedMs;\n" +
" if(newSleep <= 0){\n" +
" cout << \"Cant keep up! \"<< (-newSleep) <<\"ms late!\\n\";\n" +
" }else{\n" +
" this_thread::sleep_for(milliseconds(newSleep));\n" +
" }\n" +
" }\n" +
"\n" +
" return 0;\n" +
"}";
public static String iAdapterTemplate = "#pragma once\n" +
"#include \"${compName}.h\"\n" +
"\n" +
"class IAdapter_${compName}{\n" +
"\tpublic:\n" +
"\t\tvirtual ~IAdapter_${compName}(){}\n" +
"\t\tvirtual void init(${compName}* comp) = 0;\n" +
"\t\tvirtual void tick() = 0;\n" +
"};";
public static String coordinatorCmakeListsTemplate =
"cmake_minimum_required(VERSION 3.5)\n" +
"project (Coordinator_${compName} CXX)\n" +
"\n" +
"set (CMAKE_CXX_STANDARD 11)\n" +
"set (THREADS_PREFER_PTHREAD_FLAG ON)\n" +
"find_package(Threads REQUIRED)\n" +
"\n" +
"add_executable(Coordinator_${compName} Coordinator_${compName}.cpp)\n" +
"set_target_properties(Coordinator_${compName} PROPERTIES LINKER_LANGUAGE CXX)\n" +
"target_link_libraries(Coordinator_${compName} ${targets} Threads::Threads)\n" +
"target_include_directories(Coordinator_${compName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\n" +
"\n" +
"export(TARGETS Coordinator_${compName} FILE Coordinator_${compName}.cmake)";
import de.se_rwth.commons.logging.Log;
import org.apache.commons.io.FileUtils;
public static String cmakeCppTemplate =
"cmake_minimum_required(VERSION 3.5)\n" +
"project(${compName} LANGUAGES CXX)\n" +
"add_library(${compName} ${compName}.h)\n" +
"target_include_directories(${compName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\n" +
"set_target_properties(${compName} PROPERTIES LINKER_LANGUAGE CXX)\n" +
"export(TARGETS ${compName} FILE ${compName}.cmake)";
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public static String dummyAdapterTemplate = "#pragma once\n" +
"#include \"${compName}.h\"\n" +
"#include <thread>\n" +
"#include <chrono>\n" +
"#include \"IAdapter_${compName}.h\"\n" +
"\n" +
"class DummyAdapter_${compName}: public IAdapter_${compName}{\n" +
"\t${compName}* component;\n" +
"\n" +
"public:\n" +
"\tDummyAdapter_${compName}(){\n" +
"\n" +
"\t}\n" +
"\n" +
"\tvoid tick(){\n" +
"\t\tcout << \"Dummy publish data: component.out1 = \"<< component->out1 << endl;\n" +
"\t}\n" +
"\t\n" +
"\tvoid init(${compName}* comp){\n" +
"\t\tthis->component = comp;\n" +
"\t\twhile(1){\n" +
" \t\t std::this_thread::sleep_for(std::chrono::seconds(1));\n" +
"\t\t component->in2 += 1000;\n" +
"\t\t}\n" +
"\t}\n" +
"\n" +
"\t\n" +
"};";
public static String dummyCmakeTemplate =
"cmake_minimum_required(VERSION 3.5)\n" +
"project (DummyAdapter_${compName})\n" +
"\n" +
"add_library(DummyAdapter_${compName} DummyAdapter_${compName}.h)\n" +
"set_target_properties(DummyAdapter_${compName} PROPERTIES LINKER_LANGUAGE CXX)\n" +
"target_link_libraries(DummyAdapter_${compName} ${compName})\n" +
"target_include_directories(DummyAdapter_${compName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\n" +
"export(TARGETS DummyAdapter_${compName} FILE DummyAdapter_${compName}.cmake)";
public static String struct_msgsCmakeTemplate =
"cmake_minimum_required(VERSION 3.5)\n" +
"project (struct_msgs)\n" +
"\n" +
"find_package(genmsg REQUIRED)\n" +
"\n" +
"FILE(GLOB MSG_FILES_RAW RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ../*/roscpp/struct_msgs/*.msg)\n" +
"\n" +
"#generate struct_msgs iff .msg files where found\n" +
"if(MSG_FILES_RAW)\n" +
" #filter: add each struct msg only once (distinct by filename without path)\n" +
" foreach(CUR_MSG_FILE ${MSG_FILES_RAW})\n" +
" get_filename_component(TMP_MSG_NAME ${CUR_MSG_FILE} NAME)\n" +
" IF(NOT MSG_DEFINED_${TMP_MSG})\n" +
" LIST(APPEND MSG_FILES ${CUR_MSG_FILE})\n" +
" SET(MSG_DEFINED_${TMP_MSG} TRUE)\n" +
" ENDIF()\n" +
" endforeach(CUR_MSG_FILE)\n" +
"\n" +
" #generate messages\n" +
" add_message_files(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} FILES ${MSG_FILES})\n" +
" generate_messages()\n" +
"\n" +
" #export the include_dirs, so that other subprojects can use it\n" +
" set(struct_msgs_INCLUDE_DIRS ${struct_msgs_INCLUDE_DIRS} PARENT_SCOPE)\n" +
"endif()\n";
public class TemplateHelper {
private static Map<String, String> cache = new HashMap<>();
private static String getTemplate(String fileName) {
if (cache.containsKey(fileName)) {
return cache.get(fileName);
}
String tmpStr = "";
String fullFileName = "src/main/resources/de/monticore/lang/monticar/generator/middleware/" + fileName;
try {
tmpStr = FileUtils.readFileToString(new File(fullFileName));
} catch (Exception e) {
//Not recoverable
Log.error("Template file not found: " + fullFileName);
}
cache.put(fileName, tmpStr);
return tmpStr;
}
public static String getCoordinatorTemplate() {
return getTemplate("coordinatorTemplate.ftl");
}
public static String getStruct_msgsCmakeTemplate() {
return getTemplate("struct_msgsCmakeTemplate.ftl");
}
public static String getDummyCmakeTemplate() {
return getTemplate("dummyCmakeTemplate.ftl");
}
public static String getDummyAdapterTemplate() {
return getTemplate("dummyAdapterTemplate.ftl");
}
public static String getIAdapterTemplate() {
return getTemplate("IAdapterTemplate.ftl");
}
public static String getCoordinatorCmakeListsTemplate() {
return getTemplate("coordinatorCmakeListsTemplate.ftl");
}
public static String getCmakeCppTemplate() {
return getTemplate("cmakeCppTemplate.ftl");
}
}
......@@ -39,7 +39,7 @@ public class CPPGenImpl implements GeneratorImpl {
FileContent cmake = new FileContent();
cmake.setFileName("CMakeLists.txt");
String name = NameHelper.getComponentNameTargetLanguage(componentInstanceSymbol.getFullName());
cmake.setFileContent(TemplateHelper.cmakeCppTemplate.replace("${compName}", name));
cmake.setFileContent(TemplateHelper.getCmakeCppTemplate().replace("${compName}", name));
return cmake;
}
}
......@@ -30,7 +30,7 @@ public class DummyMiddlewareGenImpl implements GeneratorImpl {
private FileContent generateAdapter(ExpandedComponentInstanceSymbol componentInstanceSymbol) {
String name = NameHelper.getComponentNameTargetLanguage(componentInstanceSymbol.getFullName());
String content = TemplateHelper.dummyAdapterTemplate
String content = TemplateHelper.getDummyAdapterTemplate()
.replace("${compName}", name);
FileContent res = new FileContent();
......@@ -57,7 +57,7 @@ public class DummyMiddlewareGenImpl implements GeneratorImpl {
private FileContent generateCMake(ExpandedComponentInstanceSymbol componentInstanceSymbol) {
FileContent res = new FileContent();
String name = NameHelper.getComponentNameTargetLanguage(componentInstanceSymbol.getFullName());
String content = TemplateHelper.dummyCmakeTemplate
String content = TemplateHelper.getDummyCmakeTemplate()
.replace("${compName}", name);
res.setFileName("CMakeLists.txt");
......
#pragma once
#include "${compName}.h"
class IAdapter_${compName}{
public:
virtual ~IAdapter_${compName}(){}
virtual void init(${compName}* comp) = 0;
virtual void tick() = 0;
};
cmake_minimum_required(VERSION 3.5)
project(${compName} LANGUAGES CXX)
add_library(${compName} ${compName}.h)
target_include_directories(${compName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(${compName} PROPERTIES LINKER_LANGUAGE CXX)
export(TARGETS ${compName} FILE ${compName}.cmake)
cmake_minimum_required(VERSION 3.5)
project (Coordinator_${compName} CXX)
set (CMAKE_CXX_STANDARD 11)
set (THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
add_executable(Coordinator_${compName} Coordinator_${compName}.cpp)
set_target_properties(Coordinator_${compName} PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(Coordinator_${compName} ${targets} Threads::Threads)
target_include_directories(Coordinator_${compName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
export(TARGETS Coordinator_${compName} FILE Coordinator_${compName}.cmake)
\ No newline at end of file
#include
<iostream>
#include
<thread>
#include
<chrono>
#include
<atomic>
#include
<list>
#include "IAdapter_${compName}.h"
${includes}
using namespace std;
using namespace chrono;
static int exeMs = 100;
bool parseCommandLineParameters(int argc, char* argv[]){
if(argc == 1){
return true;
}
if(argc == 3 && string(argv[1]) == "-t"){
try{
int tmp = stoi(argv[2]);
if(tmp >= 0){
exeMs = tmp;
return true;
}
}catch(...){
//Ignore
}
}
cout << "Usage: " << argv[0] << " [-h | -t sleepTimeMs]\n";
return false;
}
void startMiddleware(IAdapter_${compName}& adapter,${compName}& comp,atomic
<bool>& done){
adapter.init(&comp);
done = true;
}
int main(int argc, char* argv[])
{
if(!parseCommandLineParameters(argc,argv)){
return 1;
}
atomic
<bool> done(false);
${compName} comp;
comp.init();
list
<IAdapter_${compName}
*> adapters;
${addAdapters}
list
<thread
*> threads;
for(auto a : adapters){
threads.push_back(new thread(startMiddleware,ref(*a),ref(comp),ref(done)));
}
cout << "waiting for all middleware to start\n";
this_thread::sleep_for(seconds(3));
cout << "started! Executing every " << exeMs << "ms\n";
time_point
<system_clock> start, end;
while(!done){
start = system_clock::now();
comp.execute();
for(auto a : adapters){
(*a).tick();
}
end = system_clock::now();
int elapsedMs = duration_cast
<milliseconds>(end-start).count();
int newSleep = exeMs - elapsedMs;
if(newSleep <= 0){
cout << "Cant keep up! "<< (-newSleep) <<"ms late!\n";
}else{
this_thread::sleep_for(milliseconds(newSleep));
}
}
return 0;
}
\ No newline at end of file
#pragma once
#include "${compName}.h"
#include
<thread>
#include
<chrono>
#include "IAdapter_${compName}.h"
class DummyAdapter_${compName}: public IAdapter_${compName}{
${compName}* component;
public:
DummyAdapter_${compName}(){
}
void tick(){
cout << "Dummy publish data: component.out1 = "<< component->out1 << endl;
}
void init(${compName}* comp){
this->component = comp;
while(1){
std::this_thread::sleep_for(std::chrono::seconds(1));
component->in2 += 1000;
}
}
};
cmake_minimum_required(VERSION 3.5)
project (DummyAdapter_${compName})
add_library(DummyAdapter_${compName} DummyAdapter_${compName}.h)
set_target_properties(DummyAdapter_${compName} PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(DummyAdapter_${compName} ${compName})
target_include_directories(DummyAdapter_${compName} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
export(TARGETS DummyAdapter_${compName} FILE DummyAdapter_${compName}.cmake)
cmake_minimum_required(VERSION 3.5)
project (struct_msgs)
find_package(genmsg REQUIRED)
FILE(GLOB MSG_FILES_RAW RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ../*/roscpp/struct_msgs/*.msg)
#generate struct_msgs iff .msg files where found
if(MSG_FILES_RAW)
#filter: add each struct msg only once (distinct by filename without path)
foreach(CUR_MSG_FILE ${MSG_FILES_RAW})
get_filename_component(TMP_MSG_NAME ${CUR_MSG_FILE} NAME)
IF(NOT MSG_DEFINED_${TMP_MSG})
LIST(APPEND MSG_FILES ${CUR_MSG_FILE})
SET(MSG_DEFINED_${TMP_MSG} TRUE)
ENDIF()
endforeach(CUR_MSG_FILE)
#generate messages
add_message_files(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} FILES ${MSG_FILES})
generate_messages()
#export the include_dirs, so that other subprojects can use it
set(struct_msgs_INCLUDE_DIRS ${struct_msgs_INCLUDE_DIRS} PARENT_SCOPE)
endif()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment