Program Listing for File QtToDdsPriv.hpp

Return to documentation for file (src/sinspekto/QtToDdsPriv.hpp)

#pragma once

#include <exception>
#include <functional>
#include <iostream>
#include <string>
#include <map>

#include "sinspekto/FkinDds.hpp"
#include "sinspekto/RatatoskDds.hpp"
#include "sinspekto/QtToDds.hpp"
#include "sinspekto/sinspekto.hpp"

struct QtToDds::Dds {

  Dds(uint32_t id) :
    domainParticipant(id),
    subscriber(domainParticipant),
    publisher(domainParticipant)
  { }

  ~Dds() = default;
  dds::domain::DomainParticipant domainParticipant;
  dds::sub::Subscriber subscriber;
  dds::pub::Publisher publisher;
};


namespace sinspekto {

  template <typename T>
  class DdsReaderListener :
    public dds::sub::NoOpDataReaderListener<T>
  {
  public:
    DdsReaderListener(std::function<void()> QtSignalFcn = nullptr)
    {
      m_qtEventSignal = std::move(QtSignalFcn);
    }

    virtual void on_data_available(dds::sub::DataReader<T>&)
    {
      if(m_qtEventSignal)
         emit m_qtEventSignal();
    }

  private:
    std::function<void()> m_qtEventSignal;
};

  template <typename T>
  struct Writer
  {
    Writer<T>(QtToDds * const dds, const QString &topic, bool transient_local=false) :
      writer(dds::pub::DataWriter<T>(dds::core::null))
    {
      if(dds->dds == nullptr)
      {
        std::cerr
          << "Topic: " << topic.toStdString()
            << ". QtToDds participant was not initialized first"
            << std::endl;
        throw std::runtime_error(std::string(
            "QtToDds::init must be called before writers: ")
               + std::string(__FUNCTION__));
      }

      auto signalTopic = dds::topic::Topic<T>(
          dds->dds->domainParticipant,
          topic.toStdString());

      auto signalWriterQos = dds->dds->publisher.default_datawriter_qos();
      if(transient_local){
        signalWriterQos << dds::core::policy::Durability::TransientLocal();
      }

      writer = dds::pub::DataWriter<T>(
          dds->dds->publisher,
          signalTopic,
          signalWriterQos);
    }
    dds::pub::DataWriter<T> writer;
    T sample;
  };

  template <typename T>
  struct Reader
  {
    Reader<T>(QtToDds * const dds, const QString &topic, bool transient_local=false) :
      reader(dds::sub::DataReader<T>(dds::core::null))
    {
      if(dds->dds == nullptr)
      {
        std::cerr
         << "Topic: " << topic.toStdString()
         << ". QtToDds participant was not initialized first"
         << std::endl;
        throw std::runtime_error(std::string(
             "QtToDds::init must be called before readers: ")
         + std::string(__FUNCTION__));
      }

      auto signalTopic = dds::topic::Topic<T>(
          dds->dds->domainParticipant,
          topic.toStdString());

      auto signalReaderQos = dds->dds->subscriber.default_datareader_qos();
      if(transient_local){
        signalReaderQos
         << dds::core::policy::Durability::TransientLocal()
         << dds::core::policy::Reliability::Reliable();
      }
      reader = dds::sub::DataReader<T>(
          dds->dds->subscriber,
          signalTopic,
          signalReaderQos);
    }
    dds::sub::DataReader<T> reader;
    T sample;
    dds::core::Time timepoint;
    sinspekto::DdsReaderListener<T> listener;

    ~Reader<T>()
    {
      reader.listener(nullptr, dds::core::status::StatusMask::none());
    }

  };
}