MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/rpc/include/mace/rpc/detail/pending_result.hpp
00001 #ifndef _MACE_RPC_DETAIL_PENDING_RESULT_HPP_
00002 #define _MACE_RPC_DETAIL_PENDING_RESULT_HPP_
00003 #include <mace/cmt/future.hpp>
00004 #include <mace/rpc/filter.hpp>
00005 
00006 namespace mace { namespace rpc { 
00007 
00008   typedef std::vector<char> datavec;
00009 
00010   namespace detail {
00011     class pending_result : public boost::enable_shared_from_this<pending_result> {
00012       public:
00013         typedef boost::shared_ptr<pending_result> ptr;
00014         virtual ~pending_result(){}
00015         virtual void handle_value( datavec&& d ) = 0;
00016         virtual void handle_error( int32_t code, datavec&& d ) = 0;
00017     };
00018     
00019     class raw_pending_result : public pending_result {
00020       public:
00021         raw_pending_result( const mace::cmt::promise<datavec >::ptr& p )
00022         :prom(p){}
00023         
00024         virtual void handle_value( datavec&& d ) {
00025           if( prom->retain_count() > 1 ) 
00026               prom->set_value( std::forward<datavec >(d) );
00027         }
00028         virtual void handle_error( int32_t code, datavec&& d ) {
00030           //prom->
00031         }
00032       private:
00033         mace::cmt::promise<datavec >::ptr prom; 
00034     };
00035     
00036     template<typename R, typename Connection, typename IODelegate>
00037     class pending_result_impl : public pending_result {
00038       public:
00039         pending_result_impl( Connection& c, const typename mace::cmt::promise<R>::ptr p )
00040         :prom(p),con(c){}
00041     
00042         virtual void handle_value( datavec&& d ) {
00043           if( prom->retain_count() > 1 ) {
00044               try {
00045                  R result;
00046                  function_filter<Connection> f(con);
00047                  result = IODelegate::template unpack<R,BOOST_TYPEOF(f)>( f, d );
00048                  prom->set_value( std::move( result ) );
00049               } catch ( ... ) {
00050                  prom->set_exception( boost::current_exception() );
00051               }
00052           } 
00053         }
00054         virtual void handle_error( int32_t code, datavec&& d ) {
00056           //prom->
00057         }
00058     
00059         typename mace::cmt::promise<R>::ptr prom;
00060         Connection&                         con;
00061     };
00062 
00063   } // namespace detail
00064 
00065 } } 
00066 
00067 #endif