31 #include <boost/format.hpp>
33 #include <SimoxUtility/algorithm/string/string_tools.h>
48 Ice::StringSeq groups;
50 for (std::filesystem::recursive_directory_iterator end, dir(statechartsPath); dir != end; ++dir)
53 if (dir->path().extension() ==
".scgxml" &&
54 dir->path().string().find(
"deprecated") == std::string::npos)
56 groups.push_back(dir->path().string());
65 const std::string& statePath,
66 const std::string& packagePath,
67 const std::optional<std::string>& packageIncludePath)
70 reader->readXml(std::filesystem::path(statechartGroupXmlFilePath));
74 << reader->getPackageName() <<
" at " << packagePath;
75 std::filesystem::path buildDir = finder.
getBuildDir();
80 std::filesystem::path boostStatePath(statePath);
84 reader->getPackageName(),
85 reader->getGroupName(),
87 reader->contextGenerationEnabled(),
90 packageIncludePath.value_or(reader->getPackageName()));
97 return simox::alg::join(splits,
"/");
103 std::filesystem::path buildDir,
104 const std::string& packageName,
105 const std::string& groupName,
106 const std::vector<std::string>& proxies,
107 bool contextGenerationEnabled,
110 const std::optional<std::string>& packageIncludePath)
112 std::filesystem::path outputPath = buildDir /
"source" /
113 packageIncludePath.value_or(packageName) /
"statecharts" /
114 groupName / (stateName +
".generated.h");
116 std::filesystem::path dir = outputPath;
117 dir.remove_filename();
118 std::filesystem::create_directories(dir);
121 std::vector<std::string> namespaces({
"armarx", groupName});
123 namespaces, reader, proxies, contextGenerationEnabled, groupName, variantInfo);
129 timeinfo = localtime(&rawtime);
130 strftime(buffer, 80,
"%Y-%m-%d %H:%M:%S%n", timeinfo);
153 const std::string& statechartGroupXmlFilePath,
154 const std::string& packagePath,
155 const std::optional<std::string>& packageIncludePath)
158 reader->readXml(std::filesystem::path(statechartGroupXmlFilePath));
160 if (!reader->contextGenerationEnabled())
162 throw LocalException(
"Will not generate context for ")
163 << statechartGroupXmlFilePath <<
". Context generation is not enabled for this group.";
171 << reader->getPackageName() <<
" at " << packagePath;
172 std::filesystem::path buildDir = finder.
getBuildDir();
175 reader->getPackageName(),
176 reader->getGroupName(),
177 reader->getProxies(),
179 getVariantTypesOfStatesWithNoCpp(reader, variantInfo),
186 std::filesystem::path buildDir,
187 const std::string& packageName,
188 const std::string& groupName,
189 const std::vector<std::string>& proxies,
191 const std::set<std::string>& usedVariantTypes,
193 const std::optional<std::string>& packageIncludePath)
195 std::filesystem::path outputPath =
196 buildDir /
"source" / packageIncludePath.value_or(packageName) /
"statecharts" / groupName;
197 std::filesystem::path baseClassPath =
198 outputPath / (groupName +
"StatechartContextBase.generated.h");
199 outputPath /= (groupName +
"StatechartContext.generated.h");
201 std::filesystem::path dir = outputPath;
203 dir.remove_filename();
204 std::filesystem::create_directories(dir);
207 std::vector<std::string> namespaces({
"armarx", groupName});
208 std::string
cpp, cppBase;
210 namespaces, proxies, groupName, variantInfo, usedVariantTypes);
216 timeinfo = localtime(&rawtime);
217 strftime(buffer, 80,
"%Y-%m-%d %H:%M:%S%n", timeinfo);
248 const std::filesystem::path& buildDir,
251 const std::optional<std::string>& packageIncludePath,
252 const bool nextGenBehavior)
254 ARMARX_DEBUG <<
"Generating cmake file for " << reader->getGroupName();
257 auto groupName = reader->getGroupName();
259 auto packageName = reader->getPackageName();
261 std::filesystem::path outputPath =
262 buildDir /
"source" / packageIncludePath.value_or(packageName) /
"statecharts" / groupName;
263 std::filesystem::path generatedFileName = outputPath / (groupName +
"Files.generated.cmake");
264 std::filesystem::path dir = outputPath;
265 dir.remove_filename();
266 std::filesystem::create_directories(dir);
269 Ice::StringSeq xmlFiles, headerFiles, sourceFiles;
270 xmlFiles = reader->getStateFilepaths();
275 libs.push_back(
"ArmarXCore");
276 libs.push_back(
"ArmarXCoreStatechart");
277 libs.push_back(
"ArmarXCoreObservers");
279 for (std::string& xmlFile : xmlFiles)
283 stateNode->getRoot(
"State"), variantInfo);
286 for (std::string& lib :
287 variantInfo->findLibNames(Ice::StringSeq(types.begin(), types.end())))
292 libs.push_back(libName);
297 auto proxies = reader->getProxies();
301 auto libName = lib->getName();
304 std::string proxyMemberName = proxy->getMemberName();
306 std::string proxyId =
boost::str(boost::format(
"%s.%s") % libName % proxyMemberName);
307 if (std::find(proxies.begin(), proxies.end(), proxyId) != proxies.end())
311 libs.push_back(libName);
314 for (
auto& additionalLibName : proxy->getLibraries())
316 if (!
Contains(libs, additionalLibName))
318 libs.push_back(additionalLibName);
328 std::filesystem::path groupFilePath(reader->getGroupDefinitionFilePath());
329 std::filesystem::path groupDir = groupFilePath.parent_path();
331 for (std::string& xmlFile : xmlFiles)
334 auto headerFilePath = std::filesystem::path(xmlFile).replace_extension(
"h");
336 if (std::filesystem::exists(headerFilePath))
338 headerFiles.push_back(
341 auto sourceFilePath = std::filesystem::path(xmlFile).replace_extension(
"cpp");
342 if (std::filesystem::exists(sourceFilePath))
344 sourceFiles.push_back(
350 const std::string cmakeFileContent = [&]() -> std::string
355 groupName, xmlFiles, sourceFiles, headerFiles, libs);
359 groupName, xmlFiles, sourceFiles, headerFiles, libs);
366 timeinfo = localtime(&rawtime);
367 strftime(buffer, 80,
"%Y-%m-%d %H:%M:%S%n", timeinfo);
374 if (std::string(buffer).
empty())
393 const std::string& statechartGroupXmlFilePath,
394 const std::filesystem::path& buildDir,
396 const std::optional<std::string>& packageIncludePath,
397 const bool nextGenBehavior)
401 reader->readXml(std::filesystem::path(statechartGroupXmlFilePath));
406 reader, buildDir, variantInfo, forceRewrite, packageIncludePath, nextGenBehavior);
411 const std::string& packageName,
412 const std::string& statechartsDir,
413 const std::filesystem::path& buildDir,
415 const std::string& dataDir,
416 const std::map<std::string, std::string>& dependencies,
417 const std::optional<std::string>& packageIncludePath,
418 const bool nextGenBehavior)
420 bool written =
false;
422 readVariantInfoWithPaths(packageName, buildDir.string(), dataDir, dependencies);
424 for (
auto& group : groupFiles)
427 reader->readXml(std::filesystem::path(group));
430 reader, buildDir, variantInfo, forceRewrite, packageIncludePath, nextGenBehavior);
436 StatechartGroupGenerator::readVariantInfoWithPaths(
437 const std::string& packageName,
438 const std::string& buildDir,
439 const std::string& dataDir,
440 const std::map<std::string, std::string>& dependencies)
443 std::filesystem::path variantInfoFile(dataDir);
444 variantInfoFile /= packageName;
445 variantInfoFile /=
"VariantInfo-" + packageName +
".xml";
447 if (!variantInfo->isPackageLoaded(packageName) && std::filesystem::exists(variantInfoFile))
450 variantInfo->readVariantInfo(xmlReader, buildDir, packageName);
453 for (
auto& dep : dependencies)
463 const std::string& packageName,
464 const std::string& statechartGroupXmlFilePath,
465 const std::filesystem::path& buildDir,
467 const std::string& dataDir,
468 const std::map<std::string, std::string>& dependencies,
469 const std::optional<std::string>& packageIncludePath,
470 const bool nextGenBehavior)
473 readVariantInfoWithPaths(packageName, buildDir.string(), dataDir, dependencies);
476 reader->readXml(std::filesystem::path(statechartGroupXmlFilePath));
479 reader, buildDir, variantInfo, forceRewrite, packageIncludePath, nextGenBehavior);
484 const std::string& contents)
486 bool exists = std::filesystem::exists(std::filesystem::path(path));
488 if (exists && oldContent == contents)
504 std::filesystem::create_directories(std::filesystem::path(path).parent_path());
506 file.open(path.c_str());
519 std::set<std::string>
523 std::set<std::string> variantTypes;
524 std::set<std::string> alreadyLinkedTypes;
525 for (
auto& statefile : groupReader->getStateFilepaths())
527 std::set<std::string>* currentTypeSet = &variantTypes;
529 auto headerFilePath = std::filesystem::path(statefile);
530 headerFilePath.replace_extension(std::filesystem::path(
"h"));
531 if (std::filesystem::exists(headerFilePath))
533 currentTypeSet = &alreadyLinkedTypes;
536 std::set<std::string> types =
538 currentTypeSet->insert(types.begin(), types.end());
540 std::set<std::string> results;
541 std::set_difference(variantTypes.begin(),
543 alreadyLinkedTypes.begin(),
544 alreadyLinkedTypes.end(),
545 std::inserter(results, results.end()));
549 std::set<std::string>
553 std::set<std::string> variantTypes;
555 for (
auto& statefile : groupReader->getStateFilepaths())
558 ARMARX_INFO <<
"Getting Variant types for " << statefile;
560 std::set<std::string> types =
562 ARMARX_INFO <<
"Found variant types: " << Ice::StringSeq(types.begin(), types.end());
563 variantTypes.insert(types.begin(), types.end());