#ifndef BOOST_STATECHART_FIFO_SCHEDULER_HPP_INCLUDED
#define BOOST_STATECHART_FIFO_SCHEDULER_HPP_INCLUDED
//////////////////////////////////////////////////////////////////////////////
// Copyright 2002-2006 Andreas Huber Doenni
// Distributed under the Boost Software License, Version 1.0. (See accompany-
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//////////////////////////////////////////////////////////////////////////////



#include <boost/statechart/event_base.hpp>
#include <boost/statechart/fifo_worker.hpp>
#include <boost/statechart/processor_container.hpp>

#include <boost/intrusive_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <boost/config.hpp> // BOOST_HAS_THREADS



namespace boost
{
namespace statechart
{



//////////////////////////////////////////////////////////////////////////////
template<
  class FifoWorker = fifo_worker<>,
  class Allocator = std::allocator< void > >
class fifo_scheduler : noncopyable
{
  typedef processor_container<
    fifo_scheduler, typename FifoWorker::work_item, Allocator > container;
  public:
    //////////////////////////////////////////////////////////////////////////
    #ifdef BOOST_HAS_THREADS
    fifo_scheduler( bool waitOnEmptyQueue = false ) :
      worker_( waitOnEmptyQueue )
    {
    }
    #endif

    typedef typename container::processor_handle processor_handle;
    typedef typename container::processor_context processor_context;

    template< class Processor >
    processor_handle create_processor()
    {
      processor_handle result;
      work_item item =
        container_.template create_processor< Processor >( result, *this );
      worker_.queue_work_item( item );
      return result;
    }

    template< class Processor, typename Arg1 >
    processor_handle create_processor( Arg1 arg1 )
    {
      processor_handle result;
      work_item item = container_.template create_processor< Processor >(
        result, *this, arg1 );
      worker_.queue_work_item( item );
      return result;
    }

    template< class Processor, typename Arg1, typename Arg2 >
    processor_handle create_processor( Arg1 arg1, Arg2 arg2 )
    {
      processor_handle result;
      work_item item = container_.template create_processor< Processor >(
        result, *this, arg1, arg2 );
      worker_.queue_work_item( item );
      return result;
    }

    template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
    processor_handle create_processor( Arg1 arg1, Arg2 arg2, Arg3 arg3 )
    {
      processor_handle result;
      work_item item = container_.template create_processor< Processor >(
        result, *this, arg1, arg2, arg3 );
      worker_.queue_work_item( item );
      return result;
    }

    template<
      class Processor, typename Arg1, typename Arg2,
      typename Arg3, typename Arg4 >
    processor_handle create_processor(
      Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
    {
      processor_handle result;
      work_item item = container_.template create_processor< Processor >(
        result, *this, arg1, arg2, arg3, arg4 );
      worker_.queue_work_item( item );
      return result;
    }

    template<
      class Processor, typename Arg1, typename Arg2,
      typename Arg3, typename Arg4, typename Arg5 >
    processor_handle create_processor(
      Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
    {
      processor_handle result;
      work_item item = container_.template create_processor< Processor >(
        result, *this, arg1, arg2, arg3, arg4, arg5 );
      worker_.queue_work_item( item );
      return result;
    }

    template<
      class Processor, typename Arg1, typename Arg2,
      typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
    processor_handle create_processor(
      Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
    {
      processor_handle result;
      work_item item = container_.template create_processor< Processor >(
        result, *this, arg1, arg2, arg3, arg4, arg5, arg6 );
      worker_.queue_work_item( item );
      return result;
    }

    void destroy_processor( const processor_handle & processor )
    {
      work_item item = container_.destroy_processor( processor );
      worker_.queue_work_item( item );
    }

    void initiate_processor( const processor_handle & processor )
    {
      work_item item = container_.initiate_processor( processor );
      worker_.queue_work_item( item );
    }

    void terminate_processor( const processor_handle & processor )
    {
      work_item item = container_.terminate_processor( processor );
      worker_.queue_work_item( item );
    }

    typedef intrusive_ptr< const event_base > event_ptr_type;

    void queue_event(
      const processor_handle & processor, const event_ptr_type & pEvent )
    {
      work_item item = container_.queue_event( processor, pEvent );
      worker_.queue_work_item( item );
    }

    typedef typename FifoWorker::work_item work_item;

    // We take a non-const reference so that we can move (i.e. swap) the item
    // into the queue, what avoids copying the (possibly heap-allocated)
    // implementation object inside work_item.
    void queue_work_item( work_item & item )
    {
      worker_.queue_work_item( item );
    }

    // Convenience overload so that temporary objects can be passed directly
    // instead of having to create a work_item object first. Under most
    // circumstances, this will lead to one unnecessary copy of the
    // function implementation object.
    void queue_work_item( const work_item & item )
    {
      worker_.queue_work_item( item );
    }

    void terminate()
    {
      worker_.terminate();
    }

    // Is not mutex-protected! Must only be called from the thread that also
    // calls operator().
    bool terminated() const
    {
      return worker_.terminated();
    }

    unsigned long operator()( unsigned long maxEventCount = 0 )
    {
      return worker_( maxEventCount );
    }

  private:
    //////////////////////////////////////////////////////////////////////////
    container container_;
    FifoWorker worker_;
};



} // namespace statechart
} // namespace boost



#endif
