OpenDDS - Create multiple topics from single IDL structure

1.3k views Asked by At

In my exercise with OpenDDS I would like to create multiple topics from a single IDL structure, is that possible? otherwise please let me know how to do it.

I do it as below, please correct me if it is not the right way to do it. The sample I use is available at OpenDDS-3.12/examples/DCPS/IntroductionToOpenDDS

The IDL is as follows,

StockQuoter.idl
---------------
module StockQuoter
{
#pragma DCPS_DATA_TYPE "StockQuoter::Quote"
#pragma DCPS_DATA_KEY "StockQuoter::Quote ticker"

  struct Quote {
    string ticker;
    string exchange;
    string full_name;
    double value;
    string data;
    TimeBase::TimeT timestamp;
  };
}

publisher.cpp


  // Create TOPICS and TYPES Vector
  std::stringstream ss;
  for(unsigned int idx = 0; idx < 100; ++idx)
  {
      ss << (idx+1);
      TOPICS.push_back("TOPIC" + std::string(ss.str()));
      TYPES.push_back("TYPE" + std::string(ss.str()));
      ss.clear();
      ss.str(std::string());
  }

     // Register
    for( unsigned int idx = 0; idx < 100; ++idx )
    {
        vec_quote_servent.push_back(new StockQuoter::QuoteTypeSupportImpl());
        if (DDS::RETCODE_OK != vec_quote_servent[idx]->register_type(participant.in (), TYPES[idx].c_str()))
        {
          cerr << "register_type for " << TYPES[idx] << " failed." << endl;
          ACE_OS::exit(1);
        }
    }

    // Create a topics
    for( unsigned int idx = 0; idx < 100; ++idx )
    {
         vec_quote_topic.push_back(   participant->create_topic (TOPICS[idx].c_str(),
                                      TYPES[idx].c_str(),
                                      default_topic_qos,
                                      DDS::TopicListener::_nil(),
                                      ::OpenDDS::DCPS::DEFAULT_STATUS_MASK));

         if (CORBA::is_nil (vec_quote_topic[idx].in ())) {
             cerr << "create_topic for " << TOPICS[idx] << " failed." << endl;
             ACE_OS::exit(1);
        }
     }

    // Create DataWriters
    for( unsigned int idx = 0; idx < 100; ++idx )
    {
         vec_quote_base_dw.push_back( pub->create_datawriter(vec_quote_topic[idx].in (),
                                      dw_default_qos,
                                      DDS::DataWriterListener::_nil(),
                                      ::OpenDDS::DCPS::DEFAULT_STATUS_MASK) );

        if (CORBA::is_nil (vec_quote_base_dw[idx].in ())) {
           cerr << "create_datawriter for " << TOPICS[idx] << " failed." << endl;
           ACE_OS::exit(1);
        }

        vec_quote_dw.push_back( StockQuoter::QuoteDataWriter::_narrow(vec_quote_base_dw[idx].in()) );
        if (CORBA::is_nil (vec_quote_dw[idx].in ())) {
          cerr << TOPICS[idx] << " could not be narrowed"<< endl;
          ACE_OS::exit(1);
        }
    }

    // Create handle
    for( unsigned int idx = 0; idx < 100 ; ++idx )
    {
        {
            StockQuoter::Quote topic2;
            topic2.ticker = CORBA::string_dup(TOPICS[idx].c_str());
            vec_topic_handle.push_back(vec_quote_dw[idx]->register_instance(topic2));
        }
    }

      // Publish data
      StockQuoter::Quote vec_quote;
      vec_quote.exchange = STOCK_EXCHANGE_NAME;
      vec_quote.ticker = CORBA::string_dup("VEC_TOPIC");
      vec_quote.full_name = CORBA::string_dup("TOPIC Receipts");
      vec_quote.value = 1600.0 + 10.0*i;
      vec_quote.timestamp = get_timestamp();

      for(unsigned int idx = 0; idx < 100; ++idx )
      {
          vec_quote.value += idx + 10;
          cout << "Publishing " << TOPICS[idx] << " : " << vec_quote.value <<endl;
          ret = vec_quote_dw[idx]->write(vec_quote, vec_topic_handle[idx]);
          if (ret != DDS::RETCODE_OK) {
             ACE_ERROR ((LM_ERROR, ACE_TEXT("(%P|%t) ERROR: TOPIC2 write returned %d.\n"), ret));
          }
      }
2

There are 2 answers

1
Pete On BEST ANSWER

you can create as many topics as you wish from a single IDL file. you are already doing it with this line:

participant->create_topic (TOPICS[idx].c_str(),
                           TYPES[idx].c_str(),
                           default_topic_qos,
                           DDS::TopicListener::_nil(),
                           ::OpenDDS::DCPS::DEFAULT_STATUS_MASK);

however, each topic you created has the same type. you can also create different types for topics if you have to.

0
Pete On

a, now I get the point you wanted to ask. you can define different topic types either in one file per topic, or all in one file. If you define more than one topic type in an IDL file, type support is generated for each file. Let me describe this more precisely with the same example you used. The IDL file for the IntroductionToOpenDDS example looks as follows:

#include "orbsvcs/TimeBase.idl"

module StockQuoter
{
#pragma DCPS_DATA_TYPE "StockQuoter::Quote"
#pragma DCPS_DATA_KEY "StockQuoter::Quote ticker"

struct Quote {
    string ticker;
    string exchange;
    string full_name;
    double value;
    TimeBase::TimeT timestamp;
};

#pragma DCPS_DATA_TYPE "StockQuoter::ExchangeEvent"
#pragma DCPS_DATA_KEY "StockQuoter::ExchangeEvent exchange"

enum ExchangeEventType { TRADING_OPENED,
                       TRADING_CLOSED,
                       TRADING_SUSPENDED,
                       TRADING_RESUMED };
struct ExchangeEvent {
    string exchange;
    ExchangeEventType event;
    TimeBase::TimeT timestamp;
};
};

As you can see, two types are defined: Quote and ExchangeEvent. When this IDL file gets compiled, type support for both Quote and ExchangeEvent is generated. You already used the type support for using this line (QuoteTypeSupportImpl):

    vec_quote_servent.push_back(new StockQuoter::QuoteTypeSupportImpl());

The same type support is generated for ExchangeEvent, you will find a type support called StockQuoter::ExchangeEvent with a StockQuoter::ExchangeEventTypeSupportImpl() method. Simply use this to create a topic of type ExchangeEvent.

I hope this helps. If more details are needed, feel free to ask.