在了解TypedMessage后,我们就可以开始为每种数据类型创建这样的message类了。这里说的数据类型正是指代我们之前文章中的那些类,同时也与SimpleMessage协议中定义的枚举消息类型对应,回顾一下我们分析了哪些数据类型吧:
也就是说我们需要为每种数据类型从TypedMessage继承创建一个与之对应的message类,在这个类中封装该数据类型,并实现TypedMessage中定义的init接口,相当于扩展了以上原有类的功能。我们看一个例子:
RobotStatusMessage
namespace industrial
{
namespace robot_status_message
{
class RobotStatusMessage : public industrial::typed_message::TypedMessage
{
public:
RobotStatusMessage(void);
~RobotStatusMessage(void);
bool init(industrial::simple_message::SimpleMessage & msg);
void init(industrial::robot_status::RobotStatus & status);
void init();
// Overrides - SimpleSerialize
bool load(industrial::byte_array::ByteArray *buffer);
bool unload(industrial::byte_array::ByteArray *buffer);
unsigned int byteLength()
{
return this->status_.byteLength();
}
industrial::robot_status::RobotStatus status_;
};
}
}
上面的RobotStatusMessage类继承自TypedMessage,封装了RobotStatus对象,我们需要实现init方法(当然,由于TypedMessage继承自SimpleSerialize,RobotStatusMessage还要实现load和unload方法,在load和unload中又将会触发被wrap的数据结构(本例中是RobotStatus)的load和unload)
bool RobotStatusMessage::init(industrial::simple_message::SimpleMessage & msg)
{
bool rtn = false;
//获取msg中的data
ByteArray data = msg.getData();
this->init(); //设置消息类型,初始化封装的数据成员status_
//设置通信类型
this->setCommType(msg.getCommType());
//从data中卸载数据至数据成员status_
if (data.unload(this->status_))
{
rtn = true;
}
else
{
LOG_ERROR("Failed to unload robot status data");
}
return rtn;
}
void RobotStatusMessage::init(industrial::robot_status::RobotStatus & status)
{
this->init();
this->status_.copyFrom(status);
}
void RobotStatusMessage::init()
{
this->setMessageType(StandardMsgTypes::STATUS);
this->status_.init();
}
经过init调用后,就可以从已有的SimpleMessage对象解包,初始化了RobotStatusMessage。
那么如何生成SimpleMessage呢?我们再看一下接口中的如下三个方法:
virtual bool toRequest(industrial::simple_message::SimpleMessage & msg)
{
industrial::byte_array::ByteArray data;
data.load(*this);
return msg.init(this->getMessageType(),
industrial::simple_message::CommTypes::SERVICE_REQUEST,
industrial::simple_message::ReplyTypes::INVALID, data);
}
virtual bool toReply(industrial::simple_message::SimpleMessage & msg,
industrial::simple_message::ReplyType reply)
{
industrial::byte_array::ByteArray data;
data.load(*this);
return msg.init(this->getMessageType(),
industrial::simple_message::CommTypes::SERVICE_REPLY,
reply, data);
}
virtual bool toTopic(industrial::simple_message::SimpleMessage & msg)
{
industrial::byte_array::ByteArray data;
data.load(*this);
return msg.init(this->getMessageType(),
industrial::simple_message::CommTypes::TOPIC,
industrial::simple_message::ReplyTypes::INVALID, data);
}
以toRequest为例,该方法先将对象的数据加载至临时的ByteArray类型的data变量,而后调用SimpleMessage的init方法,将有效数据填充至msg。这样就完成了创建SimpleMessage的功能。
简而言之,TypedMessage作为SimpleMessage和可序列化的RobotStatus的中间层,实现了双向的数据转换。
TypedMessage
网友评论