Adapted API conversions, incomplete
This commit is contained in:
parent
dd9197c9d5
commit
271a8377a6
2 changed files with 53 additions and 41 deletions
|
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue