Message Service component

Seal Project | Project Portal

$Date: 2004/06/28 11:58:13 $

Current Design

Class Diagram

Class Description

Example

// MessageSvc implementation, taken from testing code
class MessageSvc : public IMessageSvc, public Service {
  public:
  MessageSvc();
  virtual ~MessageSvc();

  /// Query interface call
  virtual Status queryInterface(const InterfaceID& riid, void** ppvIface)
  {   return Service::queryInterface(riid, ppvIface);                   }
// Mandatory (redundant) implementation of IInterface methods
  /// Increment the reference count of the  Interface instance.
  virtual unsigned long addRef()    {      return Service::addRef();    }
  /// Decrement reference count and release Interface instance when reference count=0.
  virtual unsigned long release()   {      return Service::release();   }
// IMessageSvc specific interface
  
  /// Report a message by specifying the source, severity level and text. 
  virtual void reportMessage( const std::string& source, int type, const std::string& message = "" );  
  /// Retrieve the current output level threshold for a given message source
  virtual int outputLevel( const std::string& source ) const;
  /// Set new output level threshold for a given message source
  virtual void setOutputLevel( const std::string& source, int new_level);
};
 
// Client code 

seal::MessageSvc msg("MessageSvc",0);
seal::MsgStream log(&msg, "Hello");
log << seal::MSG::ALWAYS;
log << line << line << line << seal::endmsg
    << "This is a " << seal::endmsg
    << "message, which " << seal::endmsg
    << "spans over several lines." << seal::endmsg;

Problems

New Design

Requirements

Class Diagram


Legend: green - standard C++ classes, pink - SEAL classes, bisque - user classes

Class Description

Example

Reporter Function Object

// Default MessageSvc Reporter implementation
template < class OutStream > class Reporter {
public:
  Reporter( const OutStream& os ) : m_os( os ) { }
  virtual ~Reporter() { }
  void operator() (const std::string& source, int type, const std::string& message = "") { os << "Reporting...\n"; }
protected:
  const OutStream& m_os;
};

Reporter Function Object - specialization for std::ostream

// Default MessageSvc Reporter specialization
template <> class Reporter< std::ostream > {
public:
  Reporter( std::ostream& os = std::cout ) { }
  virtual ~Reporter() { }
  void operator() (const std::string& source, int type, const std::string& message = "") { std::cout << "Reporting to cout..." << std::endl; }
};

Default MessageSvc implementation

// Default MessageSvc implementation
template < class OutStream, class MsgReporter = seal::Reporter< OutStream > >
class MessageSvcImpl : public IMessageSvc, public Service {
public:
  typedef OutStream   Stream;
  typedef MsgReporter Reporter;

public:
  MessageSvcImpl( Stream& os, Reporter* reporter = 0 )
  : m_os( os ), m_reporter( reporter ) {
    if( !reporter ) { m_reporter = new Reporter(); }
  }
  virtual ~MessageSvcImpl() { delete m_reporter; }

  /// Report a message by specifying the source, severity level and text. 
  virtual void reportMessage( const std::string& source, int type, const std::string& message = "" )
  {
    (*m_reporter)( source, type, message );
  }
  /// Retrieve the current output level threshold for a given message source
  virtual int outputLevel( const std::string& source ) const;
  /// Set new output level threshold for a given message source
  virtual void setOutputLevel( const std::string& source, int new_level);

private:
  MessageSvcImpl();

protected:
  Stream& m_os;
  Reporter*  m_reporter;
};
  
/// The resulting types for user consuption
typedef MessageSvcImpl< std::ostream > MessageSvc;
typedef MessageSvc::Stream             MessageStream;
typedef MessageSvc::Reporter           MessageReporter;

Client Code

// Client code using default implementation
seal::MessageSvc msg( std::cout );
seal::MsgStream log(&msg, "Hello");
log << seal::MSG::ALWAYS;
log << line << line << line << seal::endmsg
    << "This is a " << seal::endmsg
    << "message, which " << seal::endmsg
    << "spans over several lines." << seal::endmsg;

// Client code using default implementation with his/her own Reporter
class MyReporter : seal::MessageReporter {
public:
  MyReporter() {}
  virtual ~MyReporter() {}
  void operator() (const std::string& source, int type, const std::string& message = "") {
    // My fancy reporter
    m_os << "=============== Fancy header ==================" << std::endl;
    m_os << message << std::endl;
  }
};

seal::MessageSvc msg( std::cout, new MyReporter() );
seal::MsgStream log(&msg, "Hello");
log << seal::MSG::ALWAYS;
log << line << line << line << seal::endmsg
    << "This is a " << seal::endmsg
    << "message, which " << seal::endmsg
    << "spans over several lines." << seal::endmsg;


Contact: Radovan Chytracek