diff --git a/include/ki/protocol/dml/MessageModule.h b/include/ki/protocol/dml/MessageModule.h index b92c3b1..3b763c3 100644 --- a/include/ki/protocol/dml/MessageModule.h +++ b/include/ki/protocol/dml/MessageModule.h @@ -26,7 +26,8 @@ namespace dml std::string get_protocol_desription() const; void set_protocol_description(std::string protocol_description); - const MessageTemplate *add_message_template(std::string name, ki::dml::Record *record); + const MessageTemplate *add_message_template(std::string name, + ki::dml::Record *record, bool auto_sort = true); const MessageTemplate *get_message_template(uint8_t type) const; const MessageTemplate *get_message_template(std::string name) const; diff --git a/include/ki/protocol/dml/MessageTemplate.h b/include/ki/protocol/dml/MessageTemplate.h index 178c152..5cf3375 100644 --- a/include/ki/protocol/dml/MessageTemplate.h +++ b/include/ki/protocol/dml/MessageTemplate.h @@ -12,7 +12,8 @@ namespace dml class MessageTemplate { public: - MessageTemplate(std::string name, uint8_t type, ki::dml::Record *record); + MessageTemplate(std::string name, uint8_t type, + uint8_t service_id, ki::dml::Record *record); ~MessageTemplate(); std::string get_name() const; @@ -21,6 +22,9 @@ namespace dml uint8_t get_type() const; void set_type(uint8_t type); + uint8_t get_service_id() const; + void set_service_id(uint8_t service_id); + const ki::dml::Record &get_record() const; void set_record(ki::dml::Record *record); @@ -28,6 +32,7 @@ namespace dml private: std::string m_name; uint8_t m_type; + uint8_t m_service_id; ki::dml::Record *m_record; }; } diff --git a/src/protocol/dml/MessageManager.cpp b/src/protocol/dml/MessageManager.cpp index 3afc052..90903ae 100644 --- a/src/protocol/dml/MessageManager.cpp +++ b/src/protocol/dml/MessageManager.cpp @@ -56,8 +56,6 @@ namespace dml // It's safe to allocate the module we're working on now auto *message_module = new MessageModule(); - bool sort_required = true; - bool first_message = true; // Get the root node and iterate through children // Each child is a MessageTemplate @@ -90,16 +88,13 @@ namespace dml } else { - // Base sorting on whether the first message has the _MsgOrder field. - if (first_message) - { - sort_required = !record->has_field("_MsgOrder"); - first_message = false; - } + // Only do sorting after we've reached the final message + // This only affects modules that aren't ordered with _MsgOrder. + const bool auto_sort = node->next_sibling() == nullptr; // The template will use the record itself to figure out name and type; // we only give the XML data incase the record doesn't have it defined. - auto *message_template = message_module->add_message_template(message_name, record); + auto *message_template = message_module->add_message_template(message_name, record, auto_sort); if (!message_template) { delete[] data; @@ -114,10 +109,6 @@ namespace dml } } - // Sort the module's lookup if we need to - if (sort_required) - message_module->sort_lookup(); - // Make sure we aren't overwriting another module if (m_service_id_map.count(message_module->get_service_id()) == 1) { diff --git a/src/protocol/dml/MessageModule.cpp b/src/protocol/dml/MessageModule.cpp index c02739d..6345507 100644 --- a/src/protocol/dml/MessageModule.cpp +++ b/src/protocol/dml/MessageModule.cpp @@ -21,6 +21,7 @@ namespace dml for (auto it = m_templates.begin(); it != m_templates.end(); ++it) delete *it; + m_message_type_map.clear(); m_message_name_map.clear(); } @@ -54,7 +55,8 @@ namespace dml m_protocol_description = protocol_description; } - const MessageTemplate *MessageModule::add_message_template(std::string name, ki::dml::Record *record) + const MessageTemplate *MessageModule::add_message_template(std::string name, + ki::dml::Record *record, bool auto_sort) { if (!record) return nullptr; @@ -69,28 +71,33 @@ namespace dml return m_message_name_map.at(name); // Message type is based on the _MsgOrder field if it's present - // Otherwise it just goes in order of added templates - uint8_t message_type; + // Otherwise it's based on the alphabetical order of template names + uint8_t message_type = 0; auto *order_field = record->get_field("_MsgOrder"); if (order_field) + { message_type = order_field->get_value(); - else - message_type = m_last_message_type + 1; - // Don't allow message type to be zero - if (message_type == 0) - return nullptr; + // Don't allow message type to be 0 + if (message_type == 0) + return nullptr; - // Do we already have a message template with this type? - if (m_message_type_map.count(message_type) == 1) - return nullptr; + // Do we already have a template with this type? + if (m_message_type_map.count(message_type) == 1) + return nullptr; + } - // Create the template and add it to our maps - auto *message_template = new MessageTemplate(name, message_type, record); + // Create the message template and add it to our lookups + auto *message_template = new MessageTemplate(name, message_type, m_service_id, record); m_templates.push_back(message_template); - m_message_type_map.insert({ message_type, message_template }); m_message_name_map.insert({ name, message_template }); - m_last_message_type = message_type; + + // Is this module ordered? + if (message_type != 0) + m_message_type_map.insert({ message_type, message_template }); + else if (auto_sort) + sort_lookup(); + return message_template; } @@ -125,6 +132,10 @@ namespace dml message_template->set_type(message_type); m_message_type_map.insert({ message_type, message_template }); message_type++; + + // Make sure we haven't overflowed + if (message_type == 0) + throw value_error("Module has more than 254 messages."); } } @@ -139,8 +150,7 @@ namespace dml throw value_error(oss.str()); } - return message_template->build_message() - .set_service_id(m_service_id); + return message_template->build_message(); } MessageBuilder &MessageModule::build_message(std::string message_name) const @@ -154,8 +164,7 @@ namespace dml throw value_error(oss.str()); } - return message_template->build_message() - .set_service_id(m_service_id); + return message_template->build_message(); } } } diff --git a/src/protocol/dml/MessageTemplate.cpp b/src/protocol/dml/MessageTemplate.cpp index fdb3b26..e89db88 100644 --- a/src/protocol/dml/MessageTemplate.cpp +++ b/src/protocol/dml/MessageTemplate.cpp @@ -6,10 +6,12 @@ namespace protocol { namespace dml { - MessageTemplate::MessageTemplate(std::string name, uint8_t type, ki::dml::Record* record) + MessageTemplate::MessageTemplate(std::string name, uint8_t type, + uint8_t service_id, ki::dml::Record* record) { m_name = name; m_type = type; + m_service_id = service_id; m_record = record; } @@ -38,6 +40,16 @@ namespace dml m_type = type; } + uint8_t MessageTemplate::get_service_id() const + { + return m_service_id; + } + + void MessageTemplate::set_service_id(uint8_t service_id) + { + m_service_id = service_id; + } + const ki::dml::Record& MessageTemplate::get_record() const { return *m_record; @@ -52,6 +64,7 @@ namespace dml { return MessageBuilder() .set_message_type(m_type) + .set_service_id(m_service_id) .use_template_record(*m_record); } }