30 #include <boost/format.hpp>
31 #include <SimoxUtility/algorithm/string/string_tools.h>
47 Ice::StringSeq groups;
49 for (std::filesystem::recursive_directory_iterator end, dir(statechartsPath); dir != end; ++dir)
52 if (dir->path().extension() ==
".scgxml" && dir->path().string().find(
"deprecated") == std::string::npos)
54 groups.push_back(dir->path().string());
64 reader->readXml(std::filesystem::path(statechartGroupXmlFilePath));
68 std::filesystem::path buildDir = finder.
getBuildDir();
72 std::filesystem::path boostStatePath(statePath);
76 reader->getPackageName(),
77 reader->getGroupName(),
79 reader->contextGenerationEnabled(),
82 packageIncludePath.value_or(reader->getPackageName()));
88 return simox::alg::join(splits,
"/");
91 bool StatechartGroupGenerator::generateStateFile(
const std::string& stateName,
RapidXmlReaderPtr reader, std::filesystem::path buildDir,
const std::string& packageName,
const std::string& groupName,
const std::vector<std::string>& proxies,
bool contextGenerationEnabled,
const VariantInfoPtr& variantInfo,
bool forceRewrite,
const std::optional<std::string>& packageIncludePath)
93 std::filesystem::path outputPath = buildDir /
"source" / packageIncludePath.value_or(packageName) /
"statecharts" / groupName / (stateName +
".generated.h");
95 std::filesystem::path dir = outputPath;
96 dir.remove_filename();
97 std::filesystem::create_directories(dir);
100 std::vector<std::string> namespaces({
"armarx", groupName});
104 contextGenerationEnabled,
112 timeinfo = localtime(&rawtime);
113 strftime(buffer, 80,
"%Y-%m-%d %H:%M:%S%n", timeinfo);
137 reader->readXml(std::filesystem::path(statechartGroupXmlFilePath));
139 if (!reader->contextGenerationEnabled())
141 throw LocalException(
"Will not generate context for ") << statechartGroupXmlFilePath <<
". Context generation is not enabled for this group.";
148 std::filesystem::path buildDir = finder.
getBuildDir();
151 reader->getPackageName(),
152 reader->getGroupName(),
153 reader->getProxies(),
155 getVariantTypesOfStatesWithNoCpp(reader, variantInfo),
164 std::filesystem::path outputPath = buildDir /
"source" / packageIncludePath.value_or(packageName) /
"statecharts" / groupName;
165 std::filesystem::path baseClassPath = outputPath / (groupName +
"StatechartContextBase.generated.h");
166 outputPath /= (groupName +
"StatechartContext.generated.h");
168 std::filesystem::path dir = outputPath;
170 dir.remove_filename();
171 std::filesystem::create_directories(dir);
174 std::vector<std::string> namespaces({
"armarx", groupName});
175 std::string
cpp, cppBase;
186 timeinfo = localtime(&rawtime);
187 strftime(buffer, 80,
"%Y-%m-%d %H:%M:%S%n", timeinfo);
217 ARMARX_DEBUG <<
"Generating cmake file for " << reader->getGroupName();
220 auto groupName = reader->getGroupName();
222 auto packageName = reader->getPackageName();
224 std::filesystem::path outputPath = buildDir /
"source" / packageIncludePath.value_or(packageName) /
"statecharts" / groupName;
225 std::filesystem::path generatedFileName = outputPath / (groupName +
"Files.generated.cmake");
226 std::filesystem::path dir = outputPath;
227 dir.remove_filename();
228 std::filesystem::create_directories(dir);
231 Ice::StringSeq xmlFiles, headerFiles, sourceFiles;
232 xmlFiles = reader->getStateFilepaths();
237 libs.push_back(
"ArmarXCore");
238 libs.push_back(
"ArmarXCoreStatechart");
239 libs.push_back(
"ArmarXCoreObservers");
241 for (std::string& xmlFile : xmlFiles)
247 for (std::string& lib : variantInfo->findLibNames(Ice::StringSeq(types.begin(), types.end())))
252 libs.push_back(libName);
257 auto proxies = reader->getProxies();
261 auto libName = lib->getName();
264 std::string proxyMemberName = proxy->getMemberName();
266 std::string proxyId =
boost::str(boost::format(
"%s.%s") % libName % proxyMemberName);
267 if (std::find(proxies.begin(), proxies.end(), proxyId) != proxies.end())
271 libs.push_back(libName);
274 for (
auto& additionalLibName : proxy->getLibraries())
276 if (!
Contains(libs, additionalLibName))
278 libs.push_back(additionalLibName);
288 std::filesystem::path groupFilePath(reader->getGroupDefinitionFilePath());
289 std::filesystem::path groupDir = groupFilePath.parent_path();
291 for (std::string& xmlFile : xmlFiles)
294 auto headerFilePath = std::filesystem::path(xmlFile).replace_extension(
"h");
296 if (std::filesystem::exists(headerFilePath))
300 auto sourceFilePath = std::filesystem::path(xmlFile).replace_extension(
"cpp");
301 if (std::filesystem::exists(sourceFilePath))
308 const std::string cmakeFileContent = [&]() -> std::string {
321 timeinfo = localtime(&rawtime);
322 strftime(buffer, 80,
"%Y-%m-%d %H:%M:%S%n", timeinfo);
329 if(std::string(buffer).
empty())
350 reader->readXml(std::filesystem::path(statechartGroupXmlFilePath));
356 bool StatechartGroupGenerator::generateStatechartGroupCMakeSourceListFiles(
const std::string& packageName,
const std::string& statechartsDir,
const std::filesystem::path& buildDir,
bool forceRewrite,
const std::string& dataDir,
const std::map<std::string, std::string>& dependencies,
const std::optional<std::string>& packageIncludePath,
const bool nextGenBehavior)
358 bool written =
false;
359 VariantInfoPtr variantInfo = readVariantInfoWithPaths(packageName, buildDir.string(), dataDir, dependencies);
361 for (
auto& group : groupFiles)
364 reader->readXml(std::filesystem::path(group));
372 VariantInfoPtr StatechartGroupGenerator::readVariantInfoWithPaths(
const std::string& packageName,
const std::string& buildDir,
const std::string& dataDir,
const std::map<std::string, std::string>& dependencies)
375 std::filesystem::path variantInfoFile(dataDir);
376 variantInfoFile /= packageName;
377 variantInfoFile /=
"VariantInfo-" + packageName +
".xml";
379 if (!variantInfo->isPackageLoaded(packageName) && std::filesystem::exists(variantInfoFile))
382 variantInfo->readVariantInfo(xmlReader, buildDir, packageName);
385 for (
auto& dep : dependencies)
392 bool StatechartGroupGenerator::generateStatechartGroupCMakeSourceListFile(
const std::string& packageName,
const std::string& statechartGroupXmlFilePath,
const std::filesystem::path& buildDir,
bool forceRewrite,
const std::string& dataDir,
const std::map<std::string, std::string>& dependencies,
const std::optional<std::string>& packageIncludePath,
const bool nextGenBehavior)
394 auto variantInfo = readVariantInfoWithPaths(packageName, buildDir.string(), dataDir, dependencies);
397 reader->readXml(std::filesystem::path(statechartGroupXmlFilePath));
404 bool exists = std::filesystem::exists(std::filesystem::path(path));
406 if (exists && oldContent == contents)
421 std::filesystem::create_directories(std::filesystem::path(path).parent_path());
423 file.open(path.c_str());
438 std::set<std::string> variantTypes;
439 std::set<std::string> alreadyLinkedTypes;
440 for (
auto& statefile : groupReader->getStateFilepaths())
442 std::set<std::string>* currentTypeSet = &variantTypes;
444 auto headerFilePath = std::filesystem::path(statefile);
445 headerFilePath.replace_extension(std::filesystem::path(
"h"));
446 if (std::filesystem::exists(headerFilePath))
448 currentTypeSet = &alreadyLinkedTypes;
452 currentTypeSet->insert(types.begin(), types.end());
454 std::set<std::string> results;
455 std::set_difference(variantTypes.begin(), variantTypes.end(),
456 alreadyLinkedTypes.begin(), alreadyLinkedTypes.end(),
457 std::inserter(results, results.end()));
463 std::set<std::string> variantTypes;
465 for (
auto& statefile : groupReader->getStateFilepaths())
468 ARMARX_INFO <<
"Getting Variant types for " << statefile;
471 ARMARX_INFO <<
"Found variant types: " << Ice::StringSeq(types.begin(), types.end());
472 variantTypes.insert(types.begin(), types.end());