#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 class Reader; template using ReaderPtr = std::shared_ptr>; template class Writer; template using WriterPtr = std::shared_ptr>; template class Topic final : public ITopic { public: dds::domain::DomainParticipant& domainParticipant() { return m_domainParticipant; } dds::topic::Topic ddsTopic() { return m_ddsTopic; } std::string typeName() { return dds::topic::topic_type_name::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 lock(m_mutex); return m_reader != nullptr; } void unloadReader() override { std::unique_lock lock(m_mutex); DDKIT_LOG_TRACE << typeName(); if (hasReader()) { m_reader->unload(); } } void closeReader() override { std::unique_lock lock(m_mutex); ddkit::log::debug() << "closeReader (" << typeName() << ")"; if (hasReader()) { m_reader = nullptr; } } bool hasWriter() override { std::unique_lock lock(m_mutex); return m_writer != nullptr; } void closeWriter() override { std::unique_lock 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 >()) , m_ddsTopic(dds::core::null) , m_reader(nullptr) , m_writer(nullptr) { #if defined(DDS_VENDOR_CONNEXT) m_ddsTopic = dds::topic::find>(domainParticipant, topicName); #endif if (m_ddsTopic == dds::core::null) { m_ddsTopic = dds::topic::Topic( 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 reader) { std::unique_lock lock(m_mutex); m_reader = reader; } std::shared_ptr> writer() { std::unique_lock lock(m_mutex); return m_writer; } void setWriter(WriterPtr writer) { std::unique_lock 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> m_listener; dds::topic::Topic m_ddsTopic; std::recursive_mutex m_mutex; std::shared_ptr> m_reader; std::shared_ptr> m_writer; // no copying Topic(Topic const&) = delete; Topic(Topic&&) = delete; void operator=(Topic const&) = delete; }; } // namespace access } // namespace ddkit