53 ostr <<
"sequenceDiagram\n";
63 bool comment_generated_from_note_decorators{
false};
65 auto note = std::dynamic_pointer_cast<decorators::note>(decorator);
66 if (note && note->applies_to_diagram(
config().name)) {
67 comment_generated_from_note_decorators =
true;
73 note->text,
config().message_comment_width());
76 ostr << formatted_message <<
'\n';
80 if (comment_generated_from_note_decorators)
83 if (
const auto &cmt = m.
comment();
config().generate_message_comments() &&
91 cmt.value().at(
"comment"),
config().message_comment_width());
95 ostr << formatted_message <<
'\n';
105 LOG_DBG(
"Skipping empty call from '{}' to '{}'", m.
from(), m.
to());
117 if (to.value().
type_name() ==
"method") {
118 const auto &f =
dynamic_cast<const model::method &
>(to.value());
121 else if (
config().combine_free_functions_into_file_participants()) {
122 if (to.value().
type_name() ==
"function") {
127 if (f.is_cuda_kernel())
129 else if (f.is_cuda_device())
132 else if (to.value().
type_name() ==
"function_template") {
136 if (f.is_cuda_kernel())
138 else if (f.is_cuda_device())
152 ostr << indent(1) << from_alias <<
" "
180 if ((m.
from() != m.
to()) && !to.value().is_void()) {
185 ostr << indent(1) << to_alias <<
" "
187 <<
" " << from_alias <<
" : ";
189 if (
config().generate_return_types()) {
198 const activity &a, std::ostream &ostr, std::vector<eid_t> &visited)
const
200 for (
const auto &m : a.
messages()) {
201 if (m.in_static_declaration_context()) {
208 if (m.type() == message_t::kCall) {
212 visited.push_back(m.from());
214 LOG_DBG(
"Generating message [{}] --> [{}]", m.from(), m.to());
220 ostr << indent(1) <<
"activate " << to_alias <<
'\n';
222 if (
model().sequences().find(m.to()) !=
model().sequences().end()) {
223 if (std::find(visited.begin(), visited.end(), m.to()) ==
226 LOG_DBG(
"Creating activity {} --> {} - missing sequence {}",
227 m.from(), m.to(), m.to());
229 model().get_activity(m.to()), ostr, visited);
233 LOG_DBG(
"Skipping activity {} --> {} - missing sequence {}",
234 m.from(), m.to(), m.to());
238 ostr << indent(1) <<
"deactivate " << to_alias <<
'\n';
242 else if (m.type() == message_t::kIf) {
245 ostr << indent(1) <<
"alt";
246 if (
const auto &text = m.condition_text(); text.has_value())
250 else if (m.type() == message_t::kElseIf) {
252 ostr << indent(1) <<
"else";
253 if (
const auto &text = m.condition_text(); text.has_value())
257 else if (m.type() == message_t::kElse) {
259 ostr << indent(1) <<
"else\n";
261 else if (m.type() == message_t::kIfEnd) {
262 ostr << indent(1) <<
"end\n";
264 else if (m.type() == message_t::kWhile) {
267 ostr << indent(1) <<
"loop";
268 if (
const auto &text = m.condition_text(); text.has_value())
272 else if (m.type() == message_t::kWhileEnd) {
273 ostr << indent(1) <<
"end\n";
275 else if (m.type() == message_t::kFor) {
278 ostr << indent(1) <<
"loop";
279 if (
const auto &text = m.condition_text(); text.has_value())
283 else if (m.type() == message_t::kForEnd) {
286 else if (m.type() == message_t::kDo) {
289 ostr << indent(1) <<
"loop";
290 if (
const auto &text = m.condition_text(); text.has_value())
294 else if (m.type() == message_t::kDoEnd) {
295 ostr << indent(1) <<
"end\n";
297 else if (m.type() == message_t::kTry) {
300 ostr << indent(1) <<
"critical\n";
302 else if (m.type() == message_t::kCatch) {
304 ostr << indent(1) <<
"option "
307 else if (m.type() == message_t::kTryEnd) {
309 ostr << indent(1) <<
"end\n";
311 else if (m.type() == message_t::kSwitch) {
314 ostr << indent(1) <<
"alt\n";
316 else if (m.type() == message_t::kCase) {
318 ostr << indent(1) <<
"else "
321 else if (m.type() == message_t::kSwitchEnd) {
322 ostr << indent(1) <<
"end\n";
324 else if (m.type() == message_t::kConditional) {
327 ostr << indent(1) <<
"alt";
328 if (
const auto &text = m.condition_text(); text.has_value())
332 else if (m.type() == message_t::kConditionalElse) {
334 ostr << indent(1) <<
"else\n";
336 else if (m.type() == message_t::kConditionalEnd) {
337 ostr << indent(1) <<
"end\n";
343 std::ostream &ostr,
const std::string &name)
const
345 auto p =
model().get(name);
347 if (!p.has_value()) {
348 LOG_WARN(
"Cannot find participant {} from `participants_order` option",
357 std::ostream &ostr,
eid_t id,
bool force)
const
359 eid_t participant_id{};
362 for (
const auto pid :
model().active_participants()) {
364 participant_id = pid;
372 if (participant_id == 0)
378 const auto &participant =
381 if (participant.type_name() ==
"method") {
382 const auto class_id =
391 const auto &class_participant =
396 auto participant_name =
397 config().using_namespace().relative(
config().simplify_template_type(
398 class_participant.full_name(
false)));
401 ostr << indent(1) <<
"participant " << class_participant.alias()
408 else if ((participant.type_name() ==
"function" ||
409 participant.type_name() ==
"function_template") &&
410 config().combine_free_functions_into_file_participants()) {
416 const auto &file_path = f.file();
418 assert(!file_path.empty());
426 std::filesystem::path{file_path},
config().root_directory())
429 ostr << indent(1) <<
"participant "
430 << fmt::format(
"C_{:022}", file_id.value()) <<
" as "
439 auto participant_name =
config().using_namespace().relative(
440 config().simplify_template_type(participant.full_name(
false)));
443 ostr << indent(1) <<
"participant " << participant.alias() <<
" as ";
445 if (participant.type_name() ==
"function" ||
446 participant.type_name() ==
"function_template") {
452 if (f.is_cuda_kernel())
453 ostr <<
"<< CUDA Kernel >><br>";
454 else if (f.is_cuda_device())
455 ostr <<
"<< CUDA Device >><br>";
475 if ((participant.
type_name() ==
"function" ||
476 participant.
type_name() ==
"function_template") &&
477 config().combine_free_functions_into_file_participants()) {
480 return fmt::format(
"C_{:022}", file_id.value());
483 return participant.
alias();
490 if (
config().participants_order.has_value) {
491 for (
const auto &p :
config().participants_order()) {
492 LOG_DBG(
"Pregenerating participant {}", p);
497 bool star_participant_generated{
false};
499 for (
const auto &ft :
config().from_to()) {
502 assert(ft.size() == 2);
504 const auto &from_location = ft.front();
505 const auto &to_location = ft.back();
507 auto from_activity_id =
model().get_from_activity_id(from_location);
508 auto to_activity_id =
model().get_to_activity_id(to_location);
510 if (!from_activity_id || !to_activity_id)
513 if (
model().participants().count(*from_activity_id) == 0)
516 if (
model().participants().count(*to_activity_id) == 0)
519 auto message_chains_unique =
model().get_all_from_to_message_chains(
520 *from_activity_id, *to_activity_id);
522 for (
const auto &mc : message_chains_unique) {
526 if (from.value().type_name() ==
"method" ||
527 config().combine_free_functions_into_file_participants()) {
528 if (!star_participant_generated) {
529 ostr << indent(1) <<
"participant *\n";
530 star_participant_generated =
true;
533 ostr << indent(1) <<
"* "
537 << from.value().message_name(
542 for (
const auto &m : mc) {
548 for (
const auto &to_location :
config().to()) {
549 auto to_activity_id =
model().get_to_activity_id(to_location);
554 auto message_chains_unique =
555 model().get_all_from_to_message_chains(
eid_t{}, *to_activity_id);
557 for (
const auto &mc : message_chains_unique) {
558 const auto from_activity_id = mc.front().from();
560 if (
model().participants().count(from_activity_id) == 0)
566 if (from.value().type_name() ==
"method" ||
567 config().combine_free_functions_into_file_participants()) {
569 ostr << indent(1) <<
"* "
573 << from.value().message_name(
578 for (
const auto &m : mc) {
584 for (
const auto &sf :
config().from()) {
585 if (sf.location_type == location_t::function) {
587 for (
const auto &[k, v] :
model().sequences()) {
588 if (
model().participants().count(v.from()) == 0)
591 const auto &caller = *
model().participants().at(v.from());
592 std::string vfrom = caller.full_name(
false);
593 if (vfrom == sf.location) {
594 LOG_DBG(
"Found sequence diagram start point: {}", k);
600 if (start_from == 0) {
601 LOG_WARN(
"Failed to find participant with {} for start_from "
608 std::vector<eid_t> visited_participants;
610 if (
model().participants().count(start_from) == 0)
616 if (!from.has_value()) {
617 LOG_WARN(
"Failed to find participant {} for start_from "
634 if (from.value().type_name() ==
"method" ||
635 config().combine_free_functions_into_file_participants()) {
636 ostr << indent(1) <<
"* "
639 <<
" " << from_alias <<
" : "
640 << from.value().message_name(render_mode) <<
'\n';
643 ostr << indent(1) <<
"activate " << from_alias <<
'\n';
646 model().get_activity(start_from), ostr, visited_participants);
648 if (from.value().type_name() ==
"method" ||
649 config().combine_free_functions_into_file_participants()) {
651 if (!from.value().is_void()) {
652 ostr << indent(1) << from_alias <<
" "
658 if (
config().generate_return_types())
659 ostr << from.value().return_type();
665 ostr << indent(1) <<
"deactivate " << from_alias <<
'\n';
677 if (
config().generate_method_arguments() ==