mirror of https://github.com/SeanOMik/libki.git
protocol: Use an auto sorting system for message types
Rather than calling sort_lookup externally
This commit is contained in:
parent
9ef780ace1
commit
b5909878f8
|
@ -26,7 +26,8 @@ namespace dml
|
||||||
std::string get_protocol_desription() const;
|
std::string get_protocol_desription() const;
|
||||||
void set_protocol_description(std::string protocol_description);
|
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(uint8_t type) const;
|
||||||
const MessageTemplate *get_message_template(std::string name) const;
|
const MessageTemplate *get_message_template(std::string name) const;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,8 @@ namespace dml
|
||||||
class MessageTemplate
|
class MessageTemplate
|
||||||
{
|
{
|
||||||
public:
|
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();
|
~MessageTemplate();
|
||||||
|
|
||||||
std::string get_name() const;
|
std::string get_name() const;
|
||||||
|
@ -21,6 +22,9 @@ namespace dml
|
||||||
uint8_t get_type() const;
|
uint8_t get_type() const;
|
||||||
void set_type(uint8_t type);
|
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;
|
const ki::dml::Record &get_record() const;
|
||||||
void set_record(ki::dml::Record *record);
|
void set_record(ki::dml::Record *record);
|
||||||
|
|
||||||
|
@ -28,6 +32,7 @@ namespace dml
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
uint8_t m_type;
|
uint8_t m_type;
|
||||||
|
uint8_t m_service_id;
|
||||||
ki::dml::Record *m_record;
|
ki::dml::Record *m_record;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,6 @@ namespace dml
|
||||||
|
|
||||||
// It's safe to allocate the module we're working on now
|
// It's safe to allocate the module we're working on now
|
||||||
auto *message_module = new MessageModule();
|
auto *message_module = new MessageModule();
|
||||||
bool sort_required = true;
|
|
||||||
bool first_message = true;
|
|
||||||
|
|
||||||
// Get the root node and iterate through children
|
// Get the root node and iterate through children
|
||||||
// Each child is a MessageTemplate
|
// Each child is a MessageTemplate
|
||||||
|
@ -90,16 +88,13 @@ namespace dml
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Base sorting on whether the first message has the _MsgOrder field.
|
// Only do sorting after we've reached the final message
|
||||||
if (first_message)
|
// This only affects modules that aren't ordered with _MsgOrder.
|
||||||
{
|
const bool auto_sort = node->next_sibling() == nullptr;
|
||||||
sort_required = !record->has_field("_MsgOrder");
|
|
||||||
first_message = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The template will use the record itself to figure out name and type;
|
// 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.
|
// 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)
|
if (!message_template)
|
||||||
{
|
{
|
||||||
delete[] data;
|
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
|
// Make sure we aren't overwriting another module
|
||||||
if (m_service_id_map.count(message_module->get_service_id()) == 1)
|
if (m_service_id_map.count(message_module->get_service_id()) == 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace dml
|
||||||
for (auto it = m_templates.begin();
|
for (auto it = m_templates.begin();
|
||||||
it != m_templates.end(); ++it)
|
it != m_templates.end(); ++it)
|
||||||
delete *it;
|
delete *it;
|
||||||
|
m_message_type_map.clear();
|
||||||
m_message_name_map.clear();
|
m_message_name_map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +55,8 @@ namespace dml
|
||||||
m_protocol_description = protocol_description;
|
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)
|
if (!record)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -69,28 +71,33 @@ namespace dml
|
||||||
return m_message_name_map.at(name);
|
return m_message_name_map.at(name);
|
||||||
|
|
||||||
// Message type is based on the _MsgOrder field if it's present
|
// Message type is based on the _MsgOrder field if it's present
|
||||||
// Otherwise it just goes in order of added templates
|
// Otherwise it's based on the alphabetical order of template names
|
||||||
uint8_t message_type;
|
uint8_t message_type = 0;
|
||||||
auto *order_field = record->get_field<ki::dml::UBYT>("_MsgOrder");
|
auto *order_field = record->get_field<ki::dml::UBYT>("_MsgOrder");
|
||||||
if (order_field)
|
if (order_field)
|
||||||
|
{
|
||||||
message_type = order_field->get_value();
|
message_type = order_field->get_value();
|
||||||
else
|
|
||||||
message_type = m_last_message_type + 1;
|
|
||||||
|
|
||||||
// Don't allow message type to be zero
|
// Don't allow message type to be 0
|
||||||
if (message_type == 0)
|
if (message_type == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Do we already have a message template with this type?
|
// Do we already have a template with this type?
|
||||||
if (m_message_type_map.count(message_type) == 1)
|
if (m_message_type_map.count(message_type) == 1)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the template and add it to our maps
|
// Create the message template and add it to our lookups
|
||||||
auto *message_template = new MessageTemplate(name, message_type, record);
|
auto *message_template = new MessageTemplate(name, message_type, m_service_id, record);
|
||||||
m_templates.push_back(message_template);
|
m_templates.push_back(message_template);
|
||||||
m_message_type_map.insert({ message_type, message_template });
|
|
||||||
m_message_name_map.insert({ name, 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;
|
return message_template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +132,10 @@ namespace dml
|
||||||
message_template->set_type(message_type);
|
message_template->set_type(message_type);
|
||||||
m_message_type_map.insert({ message_type, message_template });
|
m_message_type_map.insert({ message_type, message_template });
|
||||||
message_type++;
|
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());
|
throw value_error(oss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return message_template->build_message()
|
return message_template->build_message();
|
||||||
.set_service_id(m_service_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageBuilder &MessageModule::build_message(std::string message_name) const
|
MessageBuilder &MessageModule::build_message(std::string message_name) const
|
||||||
|
@ -154,8 +164,7 @@ namespace dml
|
||||||
throw value_error(oss.str());
|
throw value_error(oss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return message_template->build_message()
|
return message_template->build_message();
|
||||||
.set_service_id(m_service_id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,12 @@ namespace protocol
|
||||||
{
|
{
|
||||||
namespace dml
|
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_name = name;
|
||||||
m_type = type;
|
m_type = type;
|
||||||
|
m_service_id = service_id;
|
||||||
m_record = record;
|
m_record = record;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +40,16 @@ namespace dml
|
||||||
m_type = type;
|
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
|
const ki::dml::Record& MessageTemplate::get_record() const
|
||||||
{
|
{
|
||||||
return *m_record;
|
return *m_record;
|
||||||
|
@ -52,6 +64,7 @@ namespace dml
|
||||||
{
|
{
|
||||||
return MessageBuilder()
|
return MessageBuilder()
|
||||||
.set_message_type(m_type)
|
.set_message_type(m_type)
|
||||||
|
.set_service_id(m_service_id)
|
||||||
.use_template_record(*m_record);
|
.use_template_record(*m_record);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue