#pragma once #include #include #include namespace fc { namespace json { namespace detail { struct pending_result : virtual public promise_base { typedef shared_ptr ptr; virtual void handle_result( const fc::value& ) = 0; void handle_error( const fc::string& ); int64_t id; pending_result::ptr next; protected: ~pending_result(){} }; template struct pending_result_impl : virtual public promise, virtual public pending_result { virtual void handle_result( const fc::value& s ) { this->set_value( value_cast(s) ); } protected: ~pending_result_impl(){} }; template<> struct pending_result_impl : virtual public promise, virtual public pending_result { virtual void handle_result( const fc::value& ) { set_value(); } protected: ~pending_result_impl(){} }; struct server_method : public fc::retainable { typedef fc::shared_ptr ptr; virtual value call( const value& param ) = 0; }; template struct server_method_impl : public server_method { server_method_impl( const fc::function& a ):func(a){}; virtual value call( const value& param ) { return value( func( value_cast(param) ) ); } fc::function func; }; } // namespace detail /** * This is the base JSON RPC connection that handles the protocol * level issues. It does not implement a transport which should * be provided separately and use the handle_message and set_send_delegate * methods to manage the protocol. */ class rpc_connection : public fc::retainable { public: rpc_connection(); rpc_connection(const rpc_connection&); rpc_connection(rpc_connection&&); ~rpc_connection(); rpc_connection& operator=(const rpc_connection&); rpc_connection& operator=(rpc_connection&&); typedef fc::shared_ptr ptr; void cancel_pending_requests(); template future invoke( const fc::string& method, Args&& a = nullptr ){ auto r = new detail::pending_result_impl(); typename promise::ptr rtn( r, true ); invoke( detail::pending_result::ptr(r), method, value(fc::forward(a)) ); return rtn; } template void add_method( const fc::string& name, const fc::function& a ) { this->add_method( name, detail::server_method::ptr(new detail::server_method_impl(a) ) ); } protected: void handle_message( const value& m ); virtual void send_invoke( uint64_t id, const fc::string& m, value&& param ); virtual void send_error( uint64_t id, int64_t code, const fc::string& msg ); virtual void send_result( uint64_t id, value&& r ); private: void invoke( detail::pending_result::ptr&& p, const fc::string& m, value&& param ); void add_method( const fc::string& name, detail::server_method::ptr&& m ); class impl; fc::shared_ptr my; }; } } // fc::json