37 #ifndef __PROTOBUF_COMM_MESSAGE_REGISTER_H_ 38 #define __PROTOBUF_COMM_MESSAGE_REGISTER_H_ 40 #include <protobuf_comm/frame_header.h> 42 #include <type_traits> 43 #include <google/protobuf/message.h> 44 #include <google/protobuf/descriptor.h> 45 #include <boost/utility.hpp> 46 #include <boost/thread/mutex.hpp> 76 void add_message_type(std::string msg_type);
85 typename std::enable_if<std::is_base_of<google::protobuf::Message, MT>::value,
void>::type
88 KeyType key(component_id, msg_type);
89 if (message_by_comp_type_.find(key) != message_by_comp_type_.end()) {
90 #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)) 91 std::string msg =
"Message type " + std::to_string((
long long)component_id) +
":" +
92 std::to_string((
long long)msg_type) +
" already registered";
94 std::string msg =
"Message type " + std::to_string(component_id) +
":" +
95 std::to_string(msg_type) +
" already registered";
97 throw std::runtime_error(msg);
100 message_by_comp_type_[key] = m;
101 message_by_typename_[m->GetDescriptor()->full_name()] = m;
109 typename std::enable_if<std::is_base_of<google::protobuf::Message, MT>::value,
void>::type
113 const google::protobuf::Descriptor *desc = m.GetDescriptor();
114 KeyType key = key_from_desc(desc);
115 if (message_by_comp_type_.find(key) != message_by_comp_type_.end()) {
116 #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)) 117 std::string msg =
"Message type " + std::to_string((
long long int)key.first) +
":" +
118 std::to_string((
long long int)key.second) +
" already registered";
120 std::string msg =
"Message type " + std::to_string(key.first) +
":" +
121 std::to_string(key.second) +
" already registered";
123 throw std::runtime_error(msg);
125 MT *new_m =
new MT();
126 message_by_comp_type_[key] = new_m;
127 message_by_typename_[new_m->GetTypeName()] = new_m;
130 void remove_message_type(uint16_t component_id, uint16_t msg_type);
132 std::shared_ptr<google::protobuf::Message>
133 new_message_for(uint16_t component_id, uint16_t msg_type);
135 std::shared_ptr<google::protobuf::Message>
136 new_message_for(std::string &full_name);
138 void serialize(uint16_t component_id, uint16_t msg_type,
139 google::protobuf::Message &msg,
143 std::shared_ptr<google::protobuf::Message>
157 {
return failed_to_load_types_; }
160 typedef std::pair<uint16_t, uint16_t> KeyType;
161 typedef std::map<KeyType, google::protobuf::Message *> TypeMap;
162 typedef std::map<std::string, google::protobuf::Message *> TypeNameMap;
164 KeyType key_from_desc(
const google::protobuf::Descriptor *desc);
165 google::protobuf::Message * create_msg(std::string &msg_type);
167 std::mutex maps_mutex_;
168 TypeMap message_by_comp_type_;
169 TypeNameMap message_by_typename_;
171 google::protobuf::compiler::DiskSourceTree *pb_srctree_;
172 google::protobuf::compiler::Importer *pb_importer_;
173 google::protobuf::MessageFactory *pb_factory_;
174 std::multimap<std::string, std::string> failed_to_load_types_;
std::enable_if< std::is_base_of< google::protobuf::Message, MT >::value, void >::type add_message_type(uint16_t component_id, uint16_t msg_type)
Add a new message type.
Register to map msg type numbers to Protobuf messages.
const LoadFailMap & load_failures() const
Get failure messages from loading.
std::multimap< std::string, std::string > LoadFailMap
Mapping from message type to load error message.
std::enable_if< std::is_base_of< google::protobuf::Message, MT >::value, void >::type add_message_type()
Add a new message type.