Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component ball_observeradapter
[Package ball]

Provide a helper for implementing the ball::Observer protocol. More...

Namespaces

namespace  ball

Detailed Description

Outline
Purpose:
Provide a helper for implementing the ball::Observer protocol.
Classes:
ball::ObserverAdapter a helper for implementing ball::Observer
See also:
Component ball_observer, Component ball_record, Component ball_context
Description:
This component provides a single class ball::ObserverAdapter that aids in the implementation of the ball::Observer protocol by allowing clients to implement that protocol by implementing a single method signature: publish(const ball::Record&, const ball::Context&). A primary goal of this component is to simplify the transition for older implementations of the ball::Observer protocol (that accept const-references to ball::Record objects) to the updated protocol (that accepts shared-pointers to ball::Record objects). ball::ObserverAdapter inherits from ball::Observer, and implements the (newer) overload of the publish method in (accepting a shared-pointer to a record) by calling the overload of the publish method (accepting a reference to a record).
Usage:
This section illustrates intended use of this component.
Example 1: Concrete Observer Derived From ball::ObserverAdapter:
The following code fragments illustrate the essentials of defining and using a concrete observer inherited from ball::ObserverAdapter.
First define a concrete observer MyOstreamObserver derived from ball::ObserverAdapter that declares a single publish method accepting a const-reference to a ball::Record object:
  class MyOstreamObserver : public ball::ObserverAdapter {
    bsl::ostream  *d_stream;

  public:
    explicit MyOstreamObserver(bsl::ostream *stream) : d_stream(stream) { }
    virtual ~MyOstreamObserver();
    virtual void publish(const ball::Record&  record,
                         const ball::Context& context);
  };
Then, we implement the public methods of MyOstreamObserver, including the publish method. This implementation of publish simply prints out the content of the record it receives to the stream supplied at construction.
  MyOstreamObserver::~MyOstreamObserver()
  {
  }

  void MyOstreamObserver::publish(const ball::Record&  record,
                                  const ball::Context&)
  {
      const ball::RecordAttributes& fixedFields = record.fixedFields();

      *d_stream << fixedFields.timestamp()               << ' '
                << fixedFields.processID()               << ' '
                << fixedFields.threadID()                << ' '
                << fixedFields.fileName()                << ' '
                << fixedFields.lineNumber()              << ' '
                << fixedFields.category()                << ' '
                << fixedFields.message()                 << ' ';

      const ball::UserFields& customFields = record.customFields();
      const int numCustomFields = customFields.length();
      for (int i = 0; i < numCustomFields; ++i) {
          *d_stream << customFields[i] << ' ';
      }

      *d_stream << '\n' << bsl::flush;
  }
Now, we defined a function main in which we create a MyOstreamObserver object and assign the address of this object to a ball::ObserverAdapter pointer:
  int main(bool verbose)
  {
      bsl::ostringstream     out;
      MyOstreamObserver      myObserver(&out);
      ball::ObserverAdapter *adapter = &myObserver;
Finally, publish three messages by calling publish method accepting a shared-pointer, provided by ball::ObserverAdapter, that in turn will call the publish method defined in MyOstreamObserver:
      bdlt::Datetime         now;
      ball::RecordAttributes fixedFields;
      ball::UserFields       customFields;

      const int NUM_MESSAGES = 3;
      for (int n = 0; n < NUM_MESSAGES; ++n) {
          fixedFields.setTimestamp(bdlt::CurrentTime::utc());

          bsl::shared_ptr<const ball::Record> handle;
          handle.createInplace(bslma::Default::allocator(),
                               fixedFields,
                               customFields);
          adapter->publish(handle,
                           ball::Context(ball::Transmission::e_TRIGGER,
                                         n,
                                         NUM_MESSAGES));
      }
      if (verbose) {
          bsl::cout << out.str() << bsl::endl;
      }
      return 0;
  }
The above code fragments print to stdout like this:
  Publish a sequence of three messages.
  22FEB2012_00:12:12.000 201 31  0
  22FEB2012_00:12:12.000 202 32  0
  22FEB2012_00:12:12.000 203 33  0