diff --git a/src/templates/message_parser.cpp.j2 b/src/templates/message_parser.cpp.j2 index ef01dc5..b43f115 100644 --- a/src/templates/message_parser.cpp.j2 +++ b/src/templates/message_parser.cpp.j2 @@ -32,9 +32,9 @@ void MessageParser::setMessageParse(Topic topic, parse_t parse, void* argument) } void MessageParser::parseMessage(const Variables& variables, const std::string& topic, const std::string& payload) { - auto node = this->findNode(this->tree, topic, variables); + auto nodes = this->findNodesVariables(this->tree, topic, variables); - if(node != nullptr) { + for(auto& node : nodes) { (*node->parse)(payload, node->argument); } } @@ -83,33 +83,46 @@ MessageParser::TopicNode* MessageParser::findNode(TopicNode& node, const std::st } } -MessageParser::TopicNode* MessageParser::findNode(TopicNode& node, const std::string& topic, const Variables& variables) { - auto slash = std::find(topic.begin(), topic.end(), '/'); +std::vector MessageParser::findNodesVariables(TopicNode& node, const std::string& topic, const Variables& variables) { + std::vector ret; + findNodesVariablesRec(node, topic, variables, false, ret); + + return ret; +} +void MessageParser::findNodesVariablesRec(TopicNode& node, const std::string& topic, const Variables& variables, bool hashtag, std::vector& ret) { + auto slash = std::find(topic.begin(), topic.end(), '/'); std::string subTopic = std::string(topic.begin(), slash); - auto iter = node.adjacent.find(subTopic); - if(iter == node.adjacent.end()) { - iter = std::find_if(node.adjacent.begin(), node.adjacent.end(), [&subTopic, &variables](auto& next) { - {% for variable in variables -%} - if(next.first == "<{{ variable }}>" && subTopic == variables.{{ variable }}) { - return true; - } - {%- if not loop.last %} else {% endif -%} - {%- endfor %} else { - return false; - } - }); + if(subTopic == "#") { + hashtag = true; } - if(iter == node.adjacent.end()) { - return nullptr; - } - - if(slash == topic.end()) { - return &(iter->second); + if(hashtag) { + for(auto& next : node.adjacent) { + ret.push_back(&(next.second)); + findNodesVariablesRec(next.second, "", variables, hashtag, ret); + } } else { - return findNode(iter->second, std::string(slash + 1, topic.end()), variables); + for(auto& next : node.adjacent) { + bool match = false; + + if(subTopic == "+" || subTopic == next.first) { + match = true; + } + {%- for variable in variables %} else if(next.first == "<{{ variable }}>" && subTopic == variables.{{ variable }}) { + match = true; + } + {%- endfor %} + + if(match) { + if(slash == topic.end()) { + ret.push_back(&(next.second)); + } else { + findNodesVariablesRec(next.second, std::string(slash + 1, topic.end()), variables, hashtag, ret); + } + } + } } } } \ No newline at end of file diff --git a/src/templates/message_parser.h.j2 b/src/templates/message_parser.h.j2 index 9232f5f..034b83b 100644 --- a/src/templates/message_parser.h.j2 +++ b/src/templates/message_parser.h.j2 @@ -49,7 +49,8 @@ private: void buildTree(); void addTopic(TopicNode& node, const std::string& topic); static TopicNode* findNode(TopicNode& node, const std::string& topic); - static TopicNode* findNode(TopicNode& node, const std::string& topic, const Variables& variables); + static std::vector findNodesVariables(TopicNode& node, const std::string& topic, const Variables& variables); + static void findNodesVariablesRec(TopicNode& node, const std::string& topic, const Variables& variables, bool hashtag, std::vector& ret); MessageParser::TopicNode tree; };