File builtin_readers.hpp
File List > astutedds > dcps > builtin_readers.hpp
Go to the documentation of this file
//
// Copyright (c) 2026, Astute Systems PTY LTD
//
// This file is part of the Astute DDS developed by Astute Systems.
//
// See the commercial LICENSE file in the project root for full license details.
//
// @file builtin_readers.hpp
// @brief Typed DDS built-in-topic DataReaders (DDS 1.4 §2.2.5, §A.12)
//
// Exposes the four DDS built-in DataReaders reachable through
// DomainParticipant::get_builtin_subscriber() — one per built-in topic:
//
// Topic name PSM type Source
// ------------- --------------------------------- -------------------------
// DCPSParticipant ParticipantBuiltinTopicData SPDP participant cache
// DCPSTopic TopicBuiltinTopicData SEDP DCPSTopic cache (§8.5.4.2)
// DCPSPublication PublicationBuiltinTopicData SEDP DCPSPublication cache
// DCPSSubscription SubscriptionBuiltinTopicData SEDP DCPSSubscription cache
//
// Each reader is a lightweight snapshot view over the local participant's
// discovery cache. read() returns everything currently discovered.
// take() marks records as consumed (by BuiltinTopicKey_t) so subsequent
// take() calls only surface newly-arrived entries. A background timer
// or WaitSet integration is intentionally NOT wired into this phase — the
// spec permits polling semantics and every accessor is thread-safe.
//
// Not exposed by these readers in this phase:
// - History/QoS filtering — the built-in reader QoS is fixed (KEEP_LAST 1,
// RELIABLE, TRANSIENT_LOCAL) but only the semantics matter here.
// - StatusCondition / on_data_available. Follow-up work.
//
// See DDS 1.4 §2.2.5 (Built-in Topics) and §A.12 (mandatory feature).
//
#ifndef ASTUTEDDS_DCPS_BUILTIN_READERS_HPP
#define ASTUTEDDS_DCPS_BUILTIN_READERS_HPP
#include <astutedds/dcps/builtin_topic_data.hpp>
#include <astutedds/dcps/dds_psm_types.hpp>
#include <cstdint>
#include <set>
#include <string>
#include <vector>
#include <algorithm>
namespace astutedds::dcps
{
class DomainParticipant;
struct SampleInfo;
struct BuiltinTopicKeyLess
{
bool operator()(const BuiltinTopicKey_t& a, const BuiltinTopicKey_t& b) const noexcept
{
return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
}
};
class BuiltinReaderBase
{
public:
explicit BuiltinReaderBase(DomainParticipant* participant) noexcept
: participant_(participant) {}
DomainParticipant* participant() const noexcept { return participant_; }
void reset() noexcept { taken_.clear(); }
protected:
DomainParticipant* participant_{nullptr};
std::set<BuiltinTopicKey_t, BuiltinTopicKeyLess> taken_;
};
class ParticipantBuiltinReader final : public BuiltinReaderBase
{
public:
using BuiltinReaderBase::BuiltinReaderBase;
ReturnCode_t read(std::vector<ParticipantBuiltinTopicData>& data,
std::vector<SampleInfo>& infos) const;
ReturnCode_t take(std::vector<ParticipantBuiltinTopicData>& data,
std::vector<SampleInfo>& infos);
};
class TopicBuiltinReader final : public BuiltinReaderBase
{
public:
using BuiltinReaderBase::BuiltinReaderBase;
ReturnCode_t read(std::vector<TopicBuiltinTopicData>& data,
std::vector<SampleInfo>& infos) const;
ReturnCode_t take(std::vector<TopicBuiltinTopicData>& data,
std::vector<SampleInfo>& infos);
};
class PublicationBuiltinReader final : public BuiltinReaderBase
{
public:
using BuiltinReaderBase::BuiltinReaderBase;
ReturnCode_t read(std::vector<PublicationBuiltinTopicData>& data,
std::vector<SampleInfo>& infos) const;
ReturnCode_t take(std::vector<PublicationBuiltinTopicData>& data,
std::vector<SampleInfo>& infos);
};
class SubscriptionBuiltinReader final : public BuiltinReaderBase
{
public:
using BuiltinReaderBase::BuiltinReaderBase;
ReturnCode_t read(std::vector<SubscriptionBuiltinTopicData>& data,
std::vector<SampleInfo>& infos) const;
ReturnCode_t take(std::vector<SubscriptionBuiltinTopicData>& data,
std::vector<SampleInfo>& infos);
};
class BuiltinSubscriber
{
public:
explicit BuiltinSubscriber(DomainParticipant* participant)
: participant_reader_(participant),
topic_reader_(participant),
publication_reader_(participant),
subscription_reader_(participant) {}
ParticipantBuiltinReader& participant_reader() noexcept { return participant_reader_; }
TopicBuiltinReader& topic_reader() noexcept { return topic_reader_; }
PublicationBuiltinReader& publication_reader() noexcept { return publication_reader_; }
SubscriptionBuiltinReader& subscription_reader() noexcept { return subscription_reader_; }
void* lookup_datareader(const std::string& topic_name) noexcept
{
if (topic_name == "DCPSParticipant") return &participant_reader_;
if (topic_name == "DCPSTopic") return &topic_reader_;
if (topic_name == "DCPSPublication") return &publication_reader_;
if (topic_name == "DCPSSubscription") return &subscription_reader_;
return nullptr;
}
private:
ParticipantBuiltinReader participant_reader_;
TopicBuiltinReader topic_reader_;
PublicationBuiltinReader publication_reader_;
SubscriptionBuiltinReader subscription_reader_;
};
} // namespace astutedds::dcps
#endif // ASTUTEDDS_DCPS_BUILTIN_READERS_HPP