Adapted API conversions, incomplete

This commit is contained in:
Peter Conrad 2018-03-12 22:50:59 +01:00
parent dd9197c9d5
commit 271a8377a6
2 changed files with 53 additions and 41 deletions

View file

@ -36,31 +36,31 @@ namespace fc {
return [=]( Args... args ) { return f( a0, args... ); };
}
template<typename R>
R call_generic( const std::function<R()>& f, variants::const_iterator a0, variants::const_iterator e )
R call_generic( const std::function<R()>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth = 1 )
{
return f();
}
template<typename R, typename Arg0, typename ... Args>
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0, variants::const_iterator e )
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth )
{
FC_ASSERT( a0 != e );
return call_generic<R,Args...>( bind_first_arg<R,Arg0,Args...>( f, a0->as< typename std::decay<Arg0>::type >() ), a0+1, e );
return call_generic<R,Args...>( bind_first_arg<R,Arg0,Args...>( f, a0->as< typename std::decay<Arg0>::type >( max_depth - 1 ) ), a0+1, e, max_depth - 1 );
}
template<typename R, typename ... Args>
std::function<variant(const fc::variants&)> to_generic( const std::function<R(Args...)>& f )
std::function<variant(const fc::variants&, uint32_t)> to_generic( const std::function<R(Args...)>& 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<typename ... Args>
std::function<variant(const fc::variants&)> to_generic( const std::function<void(Args...)>& f )
std::function<variant(const fc::variants&, uint32_t)> to_generic( const std::function<void(Args...)>& 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<typename R>
R call_generic( const std::function<R()>& f, variants::const_iterator a0, variants::const_iterator e )const
R call_generic( const std::function<R()>& f, variants::const_iterator a0, variants::const_iterator e, uint32_t max_depth = 1 )const
{
return f();
}
template<typename R, typename Signature, typename ... Args>
R call_generic( const std::function<R(std::function<Signature>,Args...)>& f, variants::const_iterator a0, variants::const_iterator e )
R call_generic( const std::function<R(std::function<Signature>,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<Signature> arg0( get_connection(), a0->as<uint64_t>(1) );
return call_generic<R,Args...>( this->bind_first_arg<R,std::function<Signature>,Args...>( f, std::function<Signature>(arg0) ), a0+1, e );
return call_generic<R,Args...>( this->bind_first_arg<R,std::function<Signature>,Args...>( f, std::function<Signature>(arg0) ), a0+1, e, max_depth - 1 );
}
template<typename R, typename Signature, typename ... Args>
R call_generic( const std::function<R(const std::function<Signature>&,Args...)>& f, variants::const_iterator a0, variants::const_iterator e )
R call_generic( const std::function<R(const std::function<Signature>&,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<Signature> arg0( get_connection(), a0->as<uint64_t>(1) );
return call_generic<R,Args...>( this->bind_first_arg<R,const std::function<Signature>&,Args...>( f, arg0 ), a0+1, e );
return call_generic<R,Args...>( this->bind_first_arg<R,const std::function<Signature>&,Args...>( f, arg0 ), a0+1, e, max_depth - 1 );
}
template<typename R, typename Arg0, typename ... Args>
R call_generic( const std::function<R(Arg0,Args...)>& f, variants::const_iterator a0, variants::const_iterator e )
R call_generic( const std::function<R(Arg0,Args...)>& 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<R,Args...>( this->bind_first_arg<R,Arg0,Args...>( f, a0->as< typename std::decay<Arg0>::type >() ), a0+1, e );
return call_generic<R,Args...>( this->bind_first_arg<R,Arg0,Args...>( f, a0->as< typename std::decay<Arg0>::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<typename Interface>
@ -261,12 +261,11 @@ namespace fc {
std::vector<std::string> get_method_names( api_id_type local_api_id = 0 )const { return _local_apis[local_api_id]->get_method_names(); }
fc::signal<void()> 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<generic_api> > _local_apis;
std::map< uint64_t, api_id_type > _handle_to_id;
std::vector< std::function<variant(const variants&)> > _local_callbacks;
std::vector< std::unique_ptr<generic_api> > _local_apis;
std::map< uint64_t, api_id_type > _handle_to_id;
std::vector< std::function<variant(const variants&, uint32_t)> > _local_callbacks;
struct api_visitor
@ -282,15 +281,16 @@ namespace fc {
api_visitor() = delete;
template<typename Result>
static Result from_variant( const variant& v, Result*, const std::shared_ptr<fc::api_connection>& )
static Result from_variant( const variant& v, Result*, const std::shared_ptr<fc::api_connection>&, uint32_t max_depth )
{
return v.as<Result>();
return v.as<Result>( max_depth );
}
template<typename ResultInterface>
static fc::api<ResultInterface> from_variant( const variant& v,
fc::api<ResultInterface>* /*used for template deduction*/,
const std::shared_ptr<fc::api_connection>& con
const std::shared_ptr<fc::api_connection>& con,
uint32_t max_depth = 1
)
{
return con->get_remote_api<ResultInterface>( 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<fc::api_connection>& con
const std::shared_ptr<fc::api_connection>& con,
uint32_t max_depth = 1
)
{
if( v.is_null() )
@ -308,9 +309,9 @@ namespace fc {
}
template<typename T>
static fc::variant convert_callbacks( const std::shared_ptr<fc::api_connection>&, const T& v )
static fc::variant convert_callbacks( const std::shared_ptr<fc::api_connection>& con, const T& v )
{
return fc::variant(v);
return fc::variant( v, con->_max_conversion_depth );
}
template<typename Signature>
@ -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<typename... Args>
@ -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<typename R, typename ... Args>
std::function<variant(const fc::variants&)> generic_api::api_visitor::to_generic( const std::function<R(Args...)>& 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<typename ... Args>
std::function<variant(const fc::variants&)> generic_api::api_visitor::to_generic( const std::function<void(Args...)>& 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();
};
}

View file

@ -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<websocket_api_connection>(*c);
auto wsc = std::make_shared<websocket_api_connection>(*c, MAX_DEPTH);
auto login = std::make_shared<login_api>();
login->calc = calc_api;
wsc->register_api(fc::api<login_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<websocket_api_connection>(*con);
auto apic = std::make_shared<websocket_api_connection>(*con, MAX_DEPTH);
auto remote_login_api = apic->get_remote_api<login_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<login_api> napi(&napi_impl);
auto client_side = std::make_shared<local_api_connection>();
auto server_side = std::make_shared<local_api_connection>();
auto client_side = std::make_shared<local_api_connection>(MAX_DEPTH);
auto server_side = std::make_shared<local_api_connection>(MAX_DEPTH);
server_side->set_remote_connection( client_side );
client_side->set_remote_connection( server_side );