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

100 lines
3.5 KiB
C++

#pragma once
#include "ddkit/access/ITopic.hpp"
#include "ddkit/access/IQosStrategy.hpp"
#include "ddkit/access/TopicStrategy.hpp"
#include "ddkit/access/Topic.hpp"
// Topic is included and only forward declares Reader,Writer - for writing-only-users we additionaly need the read-side
// for template-instantiiation ... so include everything just in case ...
#include "ddkit/access/Reader.hpp"
#include "ddkit/access/Writer.hpp"
#include "ddkit/utils/string.hpp"
namespace ddkit {
namespace access {
// TopicPool very well could be the (abstract) base-class for TopicPoolRead and TopicPoolWrite again
class TopicPool final {
public:
TopicPool(
dds::domain::DomainParticipant& domainParticipant,
const IQosStrategyPtr& qosStrategy,
const ITopicStrategyPtr& topicStrategy);
template <typename T>
std::string getTopicName() {
DDKIT_LOG_TRACE;
std::string className = dds::topic::topic_type_name<T>::value();
ddkit::log::trace() << DDKIT_LOG_VAR_VALUE(className);
std::string topicName = m_topicStrategy->get(className);
ddkit::log::trace() << DDKIT_LOG_VAR_VALUE(topicName);
TopicStrategyMapChars topicStrategyMapChars;
std::string topicNameSafe = topicStrategyMapChars.get(topicName);
ddkit::log::trace() << DDKIT_LOG_VAR_VALUE(topicNameSafe);
return topicNameSafe;
}
/// @brief create or get
template <typename T>
std::shared_ptr<Topic<T>> topic() {
DDKIT_LOG_TRACE;
std::string topicName = getTopicName<T>();
if (!hasTopic(topicName)) {
std::string className = dds::topic::topic_type_name<T>::value();
ddkit::utils::string::removePrefixIf(className, "VendorData::");
std::string::size_type pos = className.rfind("::");
std::string partFirst = (pos == std::string::npos) ? "no-module" : className.substr(0, pos);
std::string partLast = (pos == std::string::npos) ? className : className.substr(pos + 2);
std::string topicNameModule = partFirst;
std::string topicNameTopic = partLast;
m_name2topic.insert(std::make_pair(topicName, std::make_shared<Topic<T>>(
m_domainParticipant,
topicName,
topicNameModule,
topicNameTopic,
m_qosStrategy->selectQosPattern(className).qosTopic()
)));
}
return std::dynamic_pointer_cast<Topic<T>>(getTopic(topicName));
}
QosPattern qosPattern(const std::string& typeName) { return m_qosStrategy->selectQosPattern(typeName); }
template <typename T> // probably not needed with template-param
QosPattern qosPattern() {
std::string typeName = dds::topic::topic_type_name<T>::value();
return qosPattern(typeName);
}
bool hasTopic(const std::string& topicName);
std::shared_ptr<ITopic> getTopic(const std::string& topicName);
bool hasReaders();
void closeReaders();
void closeWriters();
void unloadReaders();
private:
dds::domain::DomainParticipant& m_domainParticipant;
IQosStrategyPtr m_qosStrategy;
ITopicStrategyPtr m_topicStrategy;
std::recursive_mutex m_mutex;
std::map<std::string, std::shared_ptr<ITopic>> m_name2topic;
// no copying
TopicPool(TopicPool const&) = delete;
TopicPool(TopicPool&&) = delete;
void operator=(TopicPool const&) = delete;
};
typedef std::shared_ptr<TopicPool> TopicPoolPtr;
} // namespace access
} // namespace ddkit