2025-04-28 12:25:20 +08:00
|
|
|
#pragma once
|
|
|
|
#include "XNBaseFrameObject.h"
|
2025-05-20 15:39:40 +08:00
|
|
|
#include "XNBaseFrameObject_p.h"
|
2025-04-28 12:25:20 +08:00
|
|
|
|
|
|
|
struct PublisherInfo {
|
|
|
|
FAST_DDS_MACRO::Publisher *publisher;
|
|
|
|
FAST_DDS_MACRO::DataWriter *dataWriter;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SubscriberInfo {
|
|
|
|
FAST_DDS_MACRO::Subscriber *subscriber;
|
|
|
|
FAST_DDS_MACRO::DataReader *dataReader;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TopicInfo {
|
|
|
|
FAST_DDS_MACRO::Topic *topic;
|
2025-05-20 15:39:40 +08:00
|
|
|
std::map<uint32_t, PublisherInfo> publishers_;
|
|
|
|
std::map<uint32_t, SubscriberInfo> subscribers_;
|
2025-04-28 12:25:20 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
class DataReaderListenerImpl : public FAST_DDS_MACRO::DataReaderListener
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
DataReaderListenerImpl(std::function<void(const T &)> callback) : callback_(callback) {}
|
|
|
|
|
|
|
|
void on_data_available(FAST_DDS_MACRO::DataReader *reader) override
|
|
|
|
{
|
|
|
|
FAST_DDS_MACRO::SampleInfo info;
|
|
|
|
if (reader->take_next_sample(&data_, &info) == FAST_DDS_MACRO::RETCODE_OK
|
|
|
|
&& info.valid_data) {
|
|
|
|
callback_(data_);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
T data_;
|
|
|
|
std::function<void(const T &)> callback_;
|
|
|
|
};
|
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
struct XNDDSManagerPrivate : public XNBaseFrameObjectPrivate {
|
|
|
|
FAST_DDS_MACRO::DomainParticipant *participant_;
|
|
|
|
std::map<std::string, TopicInfo> topics_;
|
|
|
|
std::mutex mutex_;
|
|
|
|
};
|
2025-04-28 12:25:20 +08:00
|
|
|
|
|
|
|
class XNDDSManager : public XNBaseFrameObject
|
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
XN_METATYPE(XNDDSManager, XNBaseFrameObject)
|
|
|
|
XN_DECLARE_PRIVATE(XNDDSManager)
|
2025-04-28 12:25:20 +08:00
|
|
|
public:
|
2025-05-20 15:39:40 +08:00
|
|
|
XNDDSManager();
|
2025-04-28 12:25:20 +08:00
|
|
|
~XNDDSManager();
|
|
|
|
|
|
|
|
protected:
|
2025-05-20 15:39:40 +08:00
|
|
|
XNDDSManager(PrivateType *p);
|
2025-04-28 12:25:20 +08:00
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
public:
|
|
|
|
virtual bool Initialize() override;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
virtual bool PrepareForExecute() override;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
void SetDomainID(uint32_t domainID);
|
2025-04-28 12:25:20 +08:00
|
|
|
|
|
|
|
public:
|
|
|
|
template <typename T>
|
2025-05-20 15:39:40 +08:00
|
|
|
FAST_DDS_MACRO::DataWriter *RegisterPublisher(const std::string &topicName,
|
|
|
|
uint32_t publisherID)
|
2025-04-28 12:25:20 +08:00
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
|
|
|
std::lock_guard<std::mutex> lock(d->mutex_);
|
|
|
|
if (d->topics_.find(topicName) == d->topics_.end()) {
|
|
|
|
d->topics_[topicName] = TopicInfo();
|
|
|
|
TopicInfo &tmp = d->topics_[topicName];
|
2025-04-28 12:25:20 +08:00
|
|
|
FAST_DDS_MACRO::TypeSupport typeSupport(new T());
|
2025-05-20 15:39:40 +08:00
|
|
|
typeSupport.register_type(d->participant_);
|
|
|
|
tmp.topic = d->participant_->create_topic(topicName, typeSupport.get_type_name(),
|
|
|
|
FAST_DDS_MACRO::TOPIC_QOS_DEFAULT);
|
2025-04-28 12:25:20 +08:00
|
|
|
if (tmp.topic == nullptr) {
|
|
|
|
LOG_ERROR("0x2130 Create Topic %1 Failed!", topicName);
|
2025-05-20 15:39:40 +08:00
|
|
|
d->topics_.erase(topicName);
|
2025-04-28 12:25:20 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
2025-05-20 15:39:40 +08:00
|
|
|
TopicInfo &tmp = d->topics_[topicName];
|
2025-04-28 12:25:20 +08:00
|
|
|
tmp.publishers_[publisherID] = PublisherInfo();
|
|
|
|
tmp.publishers_[publisherID].publisher =
|
2025-05-20 15:39:40 +08:00
|
|
|
d->participant_->create_publisher(FAST_DDS_MACRO::PUBLISHER_QOS_DEFAULT, nullptr);
|
2025-04-28 12:25:20 +08:00
|
|
|
if (tmp.publishers_[publisherID].publisher == nullptr) {
|
|
|
|
LOG_ERROR("0x2131 Create Publisher %1 for Topic %2 Failed!", publisherID, topicName);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置数据写入器QoS策略
|
|
|
|
FAST_DDS_MACRO::DataWriterQos dataWriterQos;
|
|
|
|
// 设置数据写入器的历史记录策略, 只保留最新的一个数据
|
|
|
|
// dataWriterQos.history().kind = FAST_DDS_MACRO::KEEP_LAST_HISTORY_QOS;
|
|
|
|
// dataWriterQos.history().depth = 1;
|
|
|
|
// 设置数据写入器的可靠性策略, 使用最佳努力可靠性
|
|
|
|
// dataWriterQos.reliability().kind = FAST_DDS_MACRO::BEST_EFFORT_RELIABILITY_QOS;
|
|
|
|
// 设置数据写入器的持久性策略, 使用瞬态本地持久性
|
|
|
|
dataWriterQos.durability().kind = FAST_DDS_MACRO::VOLATILE_DURABILITY_QOS;
|
|
|
|
// 设置数据写入器的生命周期策略, 设置为5秒
|
|
|
|
dataWriterQos.lifespan().duration = FAST_DDS_MACRO::Duration_t(5, 0);
|
|
|
|
|
|
|
|
tmp.publishers_[publisherID].dataWriter =
|
|
|
|
tmp.publishers_[publisherID].publisher->create_datawriter(tmp.topic, dataWriterQos,
|
|
|
|
nullptr);
|
|
|
|
if (tmp.publishers_[publisherID].dataWriter == nullptr) {
|
|
|
|
LOG_ERROR("0x2132 Create DataWriter %1 for Topic %2 Failed!", publisherID, topicName);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
LOG_INFO("0x2133 Create Publisher %1 for Topic %2 Success!", publisherID, topicName);
|
|
|
|
return tmp.publishers_[publisherID].dataWriter;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2025-05-20 15:39:40 +08:00
|
|
|
void RegisterSubscriber(const std::string &topicName, uint32_t subscriberID,
|
2025-04-28 12:25:20 +08:00
|
|
|
std::function<void(const typename T::type &)> fun)
|
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
T_D();
|
|
|
|
std::lock_guard<std::mutex> lock(d->mutex_);
|
|
|
|
if (d->topics_.find(topicName) == d->topics_.end()) {
|
|
|
|
d->topics_[topicName] = TopicInfo();
|
|
|
|
TopicInfo &tmp = d->topics_[topicName];
|
2025-04-28 12:25:20 +08:00
|
|
|
FAST_DDS_MACRO::TypeSupport typeSupport(new T());
|
2025-05-20 15:39:40 +08:00
|
|
|
typeSupport.register_type(d->participant_);
|
|
|
|
tmp.topic = d->participant_->create_topic(topicName, typeSupport.get_type_name(),
|
|
|
|
FAST_DDS_MACRO::TOPIC_QOS_DEFAULT);
|
2025-04-28 12:25:20 +08:00
|
|
|
if (tmp.topic == nullptr) {
|
|
|
|
LOG_ERROR("0x2130 Create Topic %1 Failed!", topicName);
|
2025-05-20 15:39:40 +08:00
|
|
|
d->topics_.erase(topicName);
|
2025-04-28 12:25:20 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2025-05-20 15:39:40 +08:00
|
|
|
TopicInfo &tmp = d->topics_[topicName];
|
2025-04-28 12:25:20 +08:00
|
|
|
tmp.subscribers_[subscriberID] = SubscriberInfo();
|
|
|
|
tmp.subscribers_[subscriberID].subscriber =
|
2025-05-20 15:39:40 +08:00
|
|
|
d->participant_->create_subscriber(FAST_DDS_MACRO::SUBSCRIBER_QOS_DEFAULT, nullptr);
|
2025-04-28 12:25:20 +08:00
|
|
|
if (tmp.subscribers_[subscriberID].subscriber == nullptr) {
|
|
|
|
LOG_ERROR("0x2135 Create Subscriber %1 for Topic %2 Failed!", subscriberID, topicName);
|
|
|
|
}
|
|
|
|
FAST_DDS_MACRO::DataReaderQos dataReaderQos;
|
|
|
|
dataReaderQos.durability().kind = FAST_DDS_MACRO::VOLATILE_DURABILITY_QOS;
|
|
|
|
FAST_DDS_MACRO::DataReaderListener *listener =
|
|
|
|
new DataReaderListenerImpl<typename T::type>(fun);
|
|
|
|
tmp.subscribers_[subscriberID].dataReader =
|
|
|
|
tmp.subscribers_[subscriberID].subscriber->create_datareader(tmp.topic, dataReaderQos,
|
|
|
|
listener);
|
|
|
|
if (tmp.subscribers_[subscriberID].dataReader == nullptr) {
|
|
|
|
LOG_ERROR("0x2136 Create DataReader %1 for Topic %2 Failed!", subscriberID, topicName);
|
|
|
|
}
|
|
|
|
LOG_INFO("0x2137 Create Subscriber %1 for Topic %2 Success!", subscriberID, topicName);
|
|
|
|
}
|
|
|
|
};
|