//
// Copyright (c) 2009-2010 Ronald Kluth
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

/**
 * @file Consumer.h
 * @author Ronald Kluth
 * @date created at 2009/02/08
 * @brief Declaration and Implementation of interface Consumer
 * @since 0.1
 */

#ifndef LOG_CONSUMER_INCLUDED
#define LOG_CONSUMER_INCLUDED

#include "ChannelId.h"

namespace Log {

// forward declaration
class Record;

/**
 * @interface Consumer
 * @brief Interface for classes that can consume records from log channels.
 * @tparam RecordT Type of the records received from channels, the default
 * is @c Record
 *
 * All log consumer classes must be derived from this class in order to be
 * compatible with log channels (which store pointers to registered consumers).
 * In addition, the channel and consumers must be templated on the same record
 * type. The derived classes must override the method @c consume that defines 
 * how to handle records.
 *
 * Usage:
 * @code
 * class ConsoleWriter: public Log::Consumer< std::string > {
 * public:
 *     virtual void consume( Log::ChannelId const channelId, std::string const& record ) {
 *         std::cout << record << std::flush;
 *     }
 * };
 * Log::Channel< std::string > channel;
 * channel.addConsumer( std::tr1::shared_ptr< ConsoleWriter >( new ConsoleWriter() ) );
 * @endcode
 *
 * @see Channel, Log::operator<<
 * @ref Example_Channel_Consumer.cpp
 */
template < typename RecordT = Record >
class Consumer
{
public:
	/// Type of the log records to consume
	typedef RecordT RecordType;

	// Compiler-generated ctor, assignment o.k.

protected:
	/// Destruction
	virtual ~Consumer() {}

public:
	/**
	 * @brief Pure virtual method for consuming records
	 * @param id A numerical value to identify which channel forwarded the record
	 * @param record The currently forwarded record
	 *
	 * Whenever a record is sent through a channel, the channel forwards
	 * it to all registered consumers by calling this method on them.
	 * Usually, consumers then transform this record into readable information
	 * and/or store it for later access.
	 *
	 * @note The record that is passed as reference to const most likely is a
	 * a temporary object. In order to store its data for later use, the
	 * consumer must copy it, for example by storing it in an STL container.
	 *
	 * @note Special care must be taken to ensure that stored records do not
	 * reference deleted objects, and end up accessing dangling pointers.
	 */
	virtual void consume( ChannelId const id, RecordType const& record ) = 0;
};

} // namespace Log

#endif /* LOG_CONSUMER_INCLUDED */
