Added sequence diagram option participants_order

This commit is contained in:
Bartek Kryza
2022-12-17 00:42:15 +01:00
parent 6454604595
commit 5d4dfbb4b1
7 changed files with 132 additions and 94 deletions

View File

@@ -252,23 +252,17 @@ The following C++ code:
namespace clanguml {
namespace t20029 {
using encoder_function_t = std::function<std::string(std::string &&)>;
std::string encode_b64(std::string &&content) { return std::move(content); }
template <typename T> class Encoder : public T {
public:
bool send(std::string &&msg)
{
auto encoded = encode(std::move(msg));
return T::send(std::move(encoded));
return T::send(std::move(encode(std::move(msg))));
}
protected:
std::string encode(std::string &&msg) { return encode_b64(std::move(msg)); }
private:
encoder_function_t f_;
};
template <typename T> class Retrier : public T {

View File

@@ -594,6 +594,7 @@ template <> struct convert<sequence_diagram> {
get_option(node, rhs.start_from);
get_option(node, rhs.combine_free_functions_into_file_participants);
get_option(node, rhs.relative_to);
get_option(node, rhs.participants_order);
rhs.initialize_type_aliases();

View File

@@ -144,6 +144,7 @@ struct inheritable_diagram_options {
"comment_parser", comment_parser_t::plain};
option<bool> combine_free_functions_into_file_participants{
"combine_free_functions_into_file_participants", false};
option<std::vector<std::string>> participants_order{"participants_order"};
void inherit(const inheritable_diagram_options &parent);

View File

@@ -79,7 +79,7 @@ void generate_diagram(const std::string &od, const std::string &name,
/// Find translation units for diagrams.
///
/// For each diagram to be generated, this function selects translation units
/// to be used for this diagram. The diagrams are selected as an intersection
/// to be used for this diagram. The files are selected as an intersection
/// between all translation units found in the compilation database and the
/// `glob` patterns specified for each diagram in the configuration file.
///

View File

@@ -220,93 +220,119 @@ void generator::generate_activity(const activity &a, std::ostream &ostr,
}
}
void generator::generate_participant(std::ostream &ostr, common::id_t id) const
void generator::generate_participant(
std::ostream &ostr, const std::string &name) const
{
for (const auto participant_id : m_model.active_participants()) {
if (participant_id != id)
continue;
if (is_participant_generated(participant_id))
return;
const auto &participant =
m_model.get_participant<model::participant>(participant_id).value();
if (participant.type_name() == "method") {
const auto class_id =
m_model.get_participant<model::method>(participant_id)
.value()
.class_id();
if (is_participant_generated(class_id))
return;
const auto &class_participant =
m_model.get_participant<model::participant>(class_id).value();
ostr << "participant \""
<< render_name(m_config.using_namespace().relative(
class_participant.full_name(false)))
<< "\" as " << class_participant.alias();
if (m_config.generate_links) {
common_generator<diagram_config, diagram_model>::generate_link(
ostr, class_participant);
}
ostr << '\n';
generated_participants_.emplace(class_id);
}
else if ((participant.type_name() == "function" ||
participant.type_name() == "function_template") &&
m_config.combine_free_functions_into_file_participants()) {
// Create a single participant for all functions declared in a
// single file
const auto &file_path =
m_model.get_participant<model::function>(participant_id)
.value()
.file();
assert(!file_path.empty());
const auto file_id = common::to_id(file_path);
if (is_participant_generated(file_id))
return;
[[maybe_unused]] const auto &relative_to =
std::filesystem::canonical(m_config.relative_to());
auto participant_name = std::filesystem::relative(
std::filesystem::path{file_path}, relative_to)
.string();
ostr << "participant \"" << render_name(participant_name)
<< "\" as " << fmt::format("C_{:022}", file_id);
ostr << '\n';
generated_participants_.emplace(file_id);
}
else {
ostr << "participant \""
<< m_config.using_namespace().relative(
participant.full_name(false))
<< "\" as " << participant.alias();
if (m_config.generate_links) {
common_generator<diagram_config, diagram_model>::generate_link(
ostr, participant);
}
ostr << '\n';
generated_participants_.emplace(participant_id);
}
auto p = m_model.get(name);
if (!p.has_value()) {
LOG_WARN("Cannot find participant {} from `participants_order` option",
name);
return;
}
generate_participant(ostr, p.value().id(), true);
}
void generator::generate_participant(
std::ostream &ostr, common::id_t id, bool force) const
{
common::id_t participant_id{0};
if (!force) {
for (const auto pid : m_model.active_participants()) {
if (pid == id) {
participant_id = pid;
break;
}
}
}
else
participant_id = id;
if (participant_id == 0)
return;
if (is_participant_generated(participant_id))
return;
const auto &participant =
m_model.get_participant<model::participant>(participant_id).value();
if (participant.type_name() == "method") {
const auto class_id =
m_model.get_participant<model::method>(participant_id)
.value()
.class_id();
if (is_participant_generated(class_id))
return;
const auto &class_participant =
m_model.get_participant<model::participant>(class_id).value();
ostr << "participant \""
<< render_name(m_config.using_namespace().relative(
class_participant.full_name(false)))
<< "\" as " << class_participant.alias();
if (m_config.generate_links) {
common_generator<diagram_config, diagram_model>::generate_link(
ostr, class_participant);
}
ostr << '\n';
generated_participants_.emplace(class_id);
}
else if ((participant.type_name() == "function" ||
participant.type_name() == "function_template") &&
m_config.combine_free_functions_into_file_participants()) {
// Create a single participant for all functions declared in a
// single file
const auto &file_path =
m_model.get_participant<model::function>(participant_id)
.value()
.file();
assert(!file_path.empty());
const auto file_id = common::to_id(file_path);
if (is_participant_generated(file_id))
return;
[[maybe_unused]] const auto &relative_to =
std::filesystem::canonical(m_config.relative_to());
auto participant_name = std::filesystem::relative(
std::filesystem::path{file_path}, relative_to)
.string();
ostr << "participant \"" << render_name(participant_name) << "\" as "
<< fmt::format("C_{:022}", file_id);
ostr << '\n';
generated_participants_.emplace(file_id);
}
else {
ostr << "participant \""
<< m_config.using_namespace().relative(
participant.full_name(false))
<< "\" as " << participant.alias();
if (m_config.generate_links) {
common_generator<diagram_config, diagram_model>::generate_link(
ostr, participant);
}
ostr << '\n';
generated_participants_.emplace(participant_id);
}
return;
}
bool generator::is_participant_generated(common::id_t id) const
@@ -324,6 +350,13 @@ void generator::generate(std::ostream &ostr) const
generate_plantuml_directives(ostr, m_config.puml().before);
if (m_config.participants_order.has_value) {
for (const auto &p : m_config.participants_order()) {
LOG_DBG("Pregenerating participant {}", p);
generate_participant(ostr, p);
}
}
for (const auto &sf : m_config.start_from()) {
if (sf.location_type == source_location::location_t::function) {
common::model::diagram_element::id_t start_from;
@@ -404,5 +437,4 @@ std::string generator::generate_alias(
return participant.alias();
}
}

View File

@@ -52,7 +52,11 @@ public:
void generate_return(const clanguml::sequence_diagram::model::message &m,
std::ostream &ostr) const;
void generate_participant(std::ostream &ostr, common::id_t id) const;
void generate_participant(
std::ostream &ostr, common::id_t id, bool force = false) const;
void generate_participant(
std::ostream &ostr, const std::string &name) const;
void generate_activity(const clanguml::sequence_diagram::model::activity &a,
std::ostream &ostr,

View File

@@ -14,4 +14,10 @@ diagrams:
using_namespace:
- clanguml::t20029
start_from:
- function: "clanguml::t20029::tmain()"
- function: clanguml::t20029::tmain()
participants_order:
- clanguml::t20029::tmain()
- clanguml::t20029::Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>
- clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>
- clanguml::t20029::ConnectionPool
- clanguml::t20029::encode_b64(std::string &&)