Files
2026-10-23 16:13:31 +00:00

141 lines
4.2 KiB
C++

#pragma once
#include "ddkit/access/DdsWrap.hpp"
#include "ddkit/access/ITopic.hpp"
#include "ddkit/access/Participant.hpp"
#include "ddkit/access/Listener.hpp"
#include "ddkit/utils/Logger.hpp"
namespace ddkit {
namespace access {
template <typename T>
class Reader;
template <typename T>
using ReaderPtr = std::shared_ptr<Reader<T>>;
template <typename T>
class Writer;
template <typename T>
using WriterPtr = std::shared_ptr<Writer<T>>;
template <typename T>
class Topic final : public ITopic {
public:
dds::domain::DomainParticipant& domainParticipant() { return m_domainParticipant; }
dds::topic::Topic<T> ddsTopic() { return m_ddsTopic; }
std::string typeName() { return dds::topic::topic_type_name<T>::value(); }
std::string topicNameModule() { return m_topicNameModule; }
std::string topicNameTopic() { return m_topicNameTopic; }
// ITopic
std::string topicName() override { return m_topicName; }
bool hasReader() override {
std::unique_lock<std::recursive_mutex> lock(m_mutex);
return m_reader != nullptr;
}
void unloadReader() override {
std::unique_lock<std::recursive_mutex> lock(m_mutex);
DDKIT_LOG_TRACE << typeName();
if (hasReader()) {
m_reader->unload();
}
}
void closeReader() override {
std::unique_lock<std::recursive_mutex> lock(m_mutex);
ddkit::log::debug() << "closeReader (" << typeName() << ")";
if (hasReader()) {
m_reader = nullptr;
}
}
bool hasWriter() override {
std::unique_lock<std::recursive_mutex> lock(m_mutex);
return m_writer != nullptr;
}
void closeWriter() override {
std::unique_lock<std::recursive_mutex> lock(m_mutex);
ddkit::log::debug() << "closeWriter (" << typeName() << ")";
if (hasWriter()) {
m_writer = nullptr;
}
}
Topic(
dds::domain::DomainParticipant& domainParticipant,
const std::string& topicName,
const std::string& topicNameModule,
const std::string& topicNameTopic,
dds::topic::qos::TopicQos topicQos) try
: m_domainParticipant(domainParticipant)
, m_topicName(topicName)
, m_topicNameModule(topicNameModule)
, m_topicNameTopic(topicNameTopic)
, m_listener(std::make_shared<ListenerTopic<T> >())
, m_ddsTopic(dds::core::null)
, m_reader(nullptr)
, m_writer(nullptr) {
#if defined(DDS_VENDOR_CONNEXT)
m_ddsTopic = dds::topic::find<dds::topic::Topic<T>>(domainParticipant, topicName);
#endif
if (m_ddsTopic == dds::core::null) {
m_ddsTopic = dds::topic::Topic<T>(
m_domainParticipant,
m_topicName,
topicQos,
m_listener.get(), // has to be set in constructor of topic
dds::core::status::StatusMask::all()
);
}
ddkit::log::info() << "Created topic: " << m_topicName;
} catch (dds::core::Exception& e) {
// happens once in a while on connext (if the same topic is ctored twice in same participant)
ddkit::log::fatal() << "construction Topic " << topicName << " failed: " << e.what();
throw std::runtime_error(e.what());
}
void setReader(ReaderPtr<T> reader) {
std::unique_lock<std::recursive_mutex> lock(m_mutex);
m_reader = reader;
}
std::shared_ptr<Writer<T>> writer() {
std::unique_lock<std::recursive_mutex> lock(m_mutex);
return m_writer;
}
void setWriter(WriterPtr<T> writer) {
std::unique_lock<std::recursive_mutex> lock(m_mutex);
m_writer = writer;
}
private:
bool m_isRead;
dds::domain::DomainParticipant& m_domainParticipant;
std::string m_topicName;
std::string m_topicNameModule;
std::string m_topicNameTopic;
std::shared_ptr<ListenerTopic<T>> m_listener;
dds::topic::Topic<T> m_ddsTopic;
std::recursive_mutex m_mutex;
std::shared_ptr<Reader<T>> m_reader;
std::shared_ptr<Writer<T>> m_writer;
// no copying
Topic(Topic const&) = delete;
Topic(Topic&&) = delete;
void operator=(Topic const&) = delete;
};
} // namespace access
} // namespace ddkit