From 271a8377a6903c9346a09c5d0cd0a97444622923 Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Mon, 12 Mar 2018 22:50:59 +0100 Subject: [PATCH] Adapted API conversions, incomplete --- include/fc/rpc/api_connection.hpp | 84 +++++++++++++++++-------------- tests/api.cpp | 10 ++-- 2 files changed, 53 insertions(+), 41 deletions(-) diff --git a/include/fc/rpc/api_connection.hpp b/include/fc/rpc/api_connection.hpp index 05f93ca..0c10ee5 100644 --- a/include/fc/rpc/api_connection.hpp +++ b/include/fc/rpc/api_connection.hpp @@ -36,31 +36,31 @@ namespace fc { return [=]( Args... args ) { return f( a0, args... ); }; } template - R call_generic( const std::function& f, variants::const_iterator a0, variants::const_iterator e ) + R call_generic( const std::function& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth = 1 ) { return f(); } template - R call_generic( const std::function& f, variants::const_iterator a0, variants::const_iterator e ) + R call_generic( const std::function& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth ) { FC_ASSERT( a0 != e ); - return call_generic( bind_first_arg( f, a0->as< typename std::decay::type >() ), a0+1, e ); + return call_generic( bind_first_arg( f, a0->as< typename std::decay::type >( max_depth - 1 ) ), a0+1, e, max_depth - 1 ); } template - std::function to_generic( const std::function& f ) + std::function to_generic( const std::function& f ) { - return [=]( const variants& args ) { - return variant( call_generic( f, args.begin(), args.end() ) ); + return [=]( const variants& args, uint32_t max_depth ) { + return variant( call_generic( f, args.begin(), args.end(), max_depth - 1 ), max_depth - 1 ); }; } template - std::function to_generic( const std::function& f ) + std::function to_generic( const std::function& f ) { - return [=]( const variants& args ) { - call_generic( f, args.begin(), args.end() ); + return [=]( const variants& args, uint32_t max_depth ) { + call_generic( f, args.begin(), args.end(), max_depth - 1 ); return variant(); }; } @@ -138,31 +138,31 @@ namespace fc { } template - R call_generic( const std::function& f, variants::const_iterator a0, variants::const_iterator e )const + R call_generic( const std::function& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth = 1 )const { return f(); } template - R call_generic( const std::function,Args...)>& f, variants::const_iterator a0, variants::const_iterator e ) + R call_generic( const std::function,Args...)>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth ) { FC_ASSERT( a0 != e, "too few arguments passed to method" ); detail::callback_functor arg0( get_connection(), a0->as(1) ); - return call_generic( this->bind_first_arg,Args...>( f, std::function(arg0) ), a0+1, e ); + return call_generic( this->bind_first_arg,Args...>( f, std::function(arg0) ), a0+1, e, max_depth - 1 ); } template - R call_generic( const std::function&,Args...)>& f, variants::const_iterator a0, variants::const_iterator e ) + R call_generic( const std::function&,Args...)>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth ) { FC_ASSERT( a0 != e, "too few arguments passed to method" ); detail::callback_functor arg0( get_connection(), a0->as(1) ); - return call_generic( this->bind_first_arg&,Args...>( f, arg0 ), a0+1, e ); + return call_generic( this->bind_first_arg&,Args...>( f, arg0 ), a0+1, e, max_depth - 1 ); } template - R call_generic( const std::function& f, variants::const_iterator a0, variants::const_iterator e ) + R call_generic( const std::function& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth ) { FC_ASSERT( a0 != e, "too few arguments passed to method" ); - return call_generic( this->bind_first_arg( f, a0->as< typename std::decay::type >() ), a0+1, e ); + return call_generic( this->bind_first_arg( f, a0->as< typename std::decay::type >( max_depth - 1 ) ), a0+1, e, max_depth - 1 ); } struct api_visitor @@ -231,12 +231,12 @@ namespace fc { variant receive_callback( uint64_t callback_id, const variants& args = variants() )const { FC_ASSERT( _local_callbacks.size() > callback_id ); - return _local_callbacks[callback_id]( args ); + return _local_callbacks[callback_id]( args, _max_conversion_depth ); } void receive_notice( uint64_t callback_id, const variants& args = variants() )const { FC_ASSERT( _local_callbacks.size() > callback_id ); - _local_callbacks[callback_id]( args ); + _local_callbacks[callback_id]( args, _max_conversion_depth ); } template @@ -261,12 +261,11 @@ namespace fc { std::vector get_method_names( api_id_type local_api_id = 0 )const { return _local_apis[local_api_id]->get_method_names(); } fc::signal closed; - protected: - const uint32_t _max_conversion_depth = 200; // for nested structures, json, variant etc. + const uint32_t _max_conversion_depth; // for nested structures, json, variant etc. private: - std::vector< std::unique_ptr > _local_apis; - std::map< uint64_t, api_id_type > _handle_to_id; - std::vector< std::function > _local_callbacks; + std::vector< std::unique_ptr > _local_apis; + std::map< uint64_t, api_id_type > _handle_to_id; + std::vector< std::function > _local_callbacks; struct api_visitor @@ -282,15 +281,16 @@ namespace fc { api_visitor() = delete; template - static Result from_variant( const variant& v, Result*, const std::shared_ptr& ) + static Result from_variant( const variant& v, Result*, const std::shared_ptr&, uint32_t max_depth ) { - return v.as(); + return v.as( max_depth ); } template static fc::api from_variant( const variant& v, fc::api* /*used for template deduction*/, - const std::shared_ptr& con + const std::shared_ptr& con, + uint32_t max_depth = 1 ) { return con->get_remote_api( v.as_uint64() ); @@ -299,7 +299,8 @@ namespace fc { static fc::api_ptr from_variant( const variant& v, fc::api_ptr* /* used for template deduction */, - const std::shared_ptr& con + const std::shared_ptr& con, + uint32_t max_depth = 1 ) { if( v.is_null() ) @@ -308,9 +309,9 @@ namespace fc { } template - static fc::variant convert_callbacks( const std::shared_ptr&, const T& v ) + static fc::variant convert_callbacks( const std::shared_ptr& con, const T& v ) { - return fc::variant(v); + return fc::variant( v, con->_max_conversion_depth ); } template @@ -326,7 +327,7 @@ namespace fc { auto api_id = _api_id; memb = [con,api_id,name]( Args... args ) { auto var_result = con->send_call( api_id, name, { convert_callbacks(con,args)...} ); - return from_variant( var_result, (Result*)nullptr, con ); + return from_variant( var_result, (Result*)nullptr, con, con->_max_conversion_depth ); }; } template @@ -344,6 +345,9 @@ namespace fc { class local_api_connection : public api_connection { public: + local_api_connection( uint32_t max_depth ) : api_connection(max_depth){} + ~local_api_connection(){} + /** makes calls to the remote server */ virtual variant send_call( api_id_type api_id, string method_name, variants args = variants() ) override { @@ -390,7 +394,7 @@ namespace fc { auto con = api_con.lock(); FC_ASSERT( con, "not connected" ); - auto api_result = gapi->call_generic( f, args.begin(), args.end() ); + auto api_result = gapi->call_generic( f, args.begin(), args.end(), con->_max_conversion_depth ); return con->register_api( api_result ); }; } @@ -404,7 +408,7 @@ namespace fc { auto con = api_con.lock(); FC_ASSERT( con, "not connected" ); - auto api_result = gapi->call_generic( f, args.begin(), args.end() ); + auto api_result = gapi->call_generic( f, args.begin(), args.end(), con->_max_conversion_depth ); if( api_result ) return con->register_api( *api_result ); return variant(); @@ -421,7 +425,7 @@ namespace fc { auto con = api_con.lock(); FC_ASSERT( con, "not connected" ); - auto api_result = gapi->call_generic( f, args.begin(), args.end() ); + auto api_result = gapi->call_generic( f, args.begin(), args.end(), con->_max_conversion_depth ); if( !api_result ) return variant(); return api_result->register_api( *con ); @@ -431,18 +435,24 @@ namespace fc { template std::function generic_api::api_visitor::to_generic( const std::function& f )const { + auto con = _api_con.lock(); + FC_ASSERT( con, "not connected" ); + uint32_t max_depth = con->_max_conversion_depth; generic_api* gapi = &_api; - return [f,gapi]( const variants& args ) { - return variant( gapi->call_generic( f, args.begin(), args.end() ) ); + return [f,gapi,max_depth]( const variants& args ) { + return variant( gapi->call_generic( f, args.begin(), args.end(), max_depth ), max_depth ); }; } template std::function generic_api::api_visitor::to_generic( const std::function& f )const { + auto con = _api_con.lock(); + FC_ASSERT( con, "not connected" ); + uint32_t max_depth = con->_max_conversion_depth; generic_api* gapi = &_api; - return [f,gapi]( const variants& args ) { - gapi->call_generic( f, args.begin(), args.end() ); + return [f,gapi,max_depth]( const variants& args ) { + gapi->call_generic( f, args.begin(), args.end(), max_depth ); return variant(); }; } diff --git a/tests/api.cpp b/tests/api.cpp index 4fcd8b5..e0514c3 100644 --- a/tests/api.cpp +++ b/tests/api.cpp @@ -52,6 +52,8 @@ class variant_calculator using namespace fc::http; using namespace fc::rpc; +#define MAX_DEPTH 10 + int main( int argc, char** argv ) { try { @@ -59,7 +61,7 @@ int main( int argc, char** argv ) fc::http::websocket_server server; server.on_connection([&]( const websocket_connection_ptr& c ){ - auto wsc = std::make_shared(*c); + auto wsc = std::make_shared(*c, MAX_DEPTH); auto login = std::make_shared(); login->calc = calc_api; wsc->register_api(fc::api(login)); @@ -74,7 +76,7 @@ int main( int argc, char** argv ) try { fc::http::websocket_client client; auto con = client.connect( "ws://localhost:8090" ); - auto apic = std::make_shared(*con); + auto apic = std::make_shared(*con, MAX_DEPTH); auto remote_login_api = apic->get_remote_api(); auto remote_calc = remote_login_api->get_calc(); remote_calc->on_result( []( uint32_t r ) { elog( "callback result ${r}", ("r",r) ); } ); @@ -167,8 +169,8 @@ int main( int argc, char** argv ) fc::api napi(&napi_impl); - auto client_side = std::make_shared(); - auto server_side = std::make_shared(); + auto client_side = std::make_shared(MAX_DEPTH); + auto server_side = std::make_shared(MAX_DEPTH); server_side->set_remote_connection( client_side ); client_side->set_remote_connection( server_side );