10#include <fc/signals.hpp>
13 class binary_api_connection;
16 template<
typename Signature>
20 typedef typename std::function<Signature>::result_type
result_type;
23 :_callback_id(
id),_binary_api_connection(con){}
25 template<
typename... Args>
30 std::weak_ptr< fc::binary_api_connection > _binary_api_connection;
33 template<
typename R,
typename Arg0,
typename ... Args>
34 std::function<
R(Args...)>
bind_first_arg(
const std::function<
R(Arg0,Args...)>&
f, Arg0 a0 )
36 return [=]( Args... args ) {
return f( a0, args... ); };
39 R call_generic(
const std::function<
R()>&
f, variants::const_iterator a0, variants::const_iterator e )
44 template<
typename R,
typename Arg0,
typename ... Args>
45 R call_generic(
const std::function<
R(Arg0,Args...)>&
f, variants::const_iterator a0, variants::const_iterator e )
51 template<
typename R,
typename ... Args>
55 return variant(
call_generic(
f, args.begin(), args.end() ) );
59 template<
typename ... Args>
100 template<
typename Api>
101 generic_api(
const Api&
a,
const std::shared_ptr<fc::binary_api_connection>& c );
107 auto itr = _by_name.find(
name);
108 FC_ASSERT( itr != _by_name.end(),
"no method with name '${name}'", (
"name",
name)(
"api",_by_name) );
109 return call( itr->second, args );
114 FC_ASSERT( method_id < _methods.size() );
115 return _methods[method_id](args);
120 return _binary_api_connection;
125 std::vector<std::string> result;
126 result.reserve( _by_name.size() );
127 for(
auto& m : _by_name ) result.push_back(m.first);
134 template<
typename R,
typename Arg0,
typename ... Args>
135 std::function<
R(Args...)> bind_first_arg(
const std::function<
R(Arg0,Args...)>&
f, Arg0 a0 )
const
137 return [=]( Args... args ) {
return f( a0, args... ); };
141 R call_generic(
const std::function<
R()>&
f, datastream<const char*>& ds )
const
146 template<
typename R,
typename Signature,
typename ... Args>
147 R call_generic(
const std::function<
R(std::function<Signature>,Args...)>&
f, datastream<const char*>& ds )
151 detail::callback_functor<Signature> arg0(
get_connection(), callback_id );
152 return call_generic<
R,Args...>( this->bind_first_arg<R,std::function<Signature>,Args...>(
f, std::function<Signature>(arg0) ),
ds );
154 template<
typename R,
typename Signature,
typename ... Args>
159 detail::callback_functor<Signature> arg0(
get_connection(), callback_id );
160 return call_generic<
R,Args...>( this->bind_first_arg<R,const std::function<Signature>&,Args...>(
f, arg0 ),
ds );
163 template<
typename R,
typename Arg0,
typename ... Args>
166 std::decay<Arg0>::type a0;
168 return call_generic<
R,Args...>( this->bind_first_arg<
R,Arg0,Args...>(
f, a0 ),
ds );
175 template<
typename Interface,
typename Adaptor,
typename ... Args>
176 std::function<variant(
const fc::variants&)> to_generic(
const std::function<api<Interface,Adaptor>(Args...)>&
f )
const;
178 template<
typename Interface,
typename Adaptor,
typename ... Args>
179 std::function<variant(
const fc::variants&)> to_generic(
const std::function<std::optional<api<Interface,Adaptor>>(Args...)>&
f )
const;
181 template<
typename ... Args>
184 template<
typename R,
typename ... Args>
185 std::function<variant(
const fc::variants&)> to_generic(
const std::function<
R(Args...)>&
f )
const;
187 template<
typename ... Args>
188 std::function<variant(
const fc::variants&)> to_generic(
const std::function<
void(Args...)>&
f )
const;
190 template<
typename Result,
typename... Args>
191 void operator()(
const char*
name, std::function<Result(Args...)>& memb )
const {
192 api._methods.emplace_back( to_generic( memb ) );
193 api._by_name[
name] = api._methods.size() - 1;
197 const std::weak_ptr<fc::binary_api_connection>& _api_con;
201 std::weak_ptr<fc::binary_api_connection> _binary_api_connection;
203 std::map< std::string, uint32_t > _by_name;
204 std::vector< std::function<vector<char>(
const vector<char>&)> > _methods;
223 result->visit( api_visitor( api_id, this->shared_from_this() ) );
234 FC_ASSERT( _local_apis.size() > api_id );
235 return _local_apis[api_id]->call( method_name, args );
239 FC_ASSERT( _local_callbacks.size() > callback_id );
240 return _local_callbacks[callback_id]( args );
244 FC_ASSERT( _local_callbacks.size() > callback_id );
245 _local_callbacks[callback_id]( args );
248 template<
typename Interface>
251 auto handle =
a.get_handle();
252 auto itr = _handle_to_id.find(handle);
253 if( itr != _handle_to_id.end() )
return itr->second;
255 _local_apis.push_back( std::unique_ptr<generic_api>(
new generic_api(
a, shared_from_this() ) ) );
256 _handle_to_id[handle] = _local_apis.size() - 1;
257 return _local_apis.size() - 1;
260 template<
typename Signature>
264 return _local_callbacks.size() - 1;
271 std::vector< std::unique_ptr<generic_api> > _local_apis;
272 std::map< uint64_t, api_id_type > _handle_to_id;
273 std::vector< std::function<
variant(
const variants&)> > _local_callbacks;
279 std::shared_ptr<fc::binary_api_connection> _connection;
281 api_visitor(
uint32_t api_id, std::shared_ptr<fc::binary_api_connection> con )
282 :_api_id(api_id),_connection(std::move(con))
286 api_visitor() =
delete;
288 template<
typename Result>
289 static Result from_vector(
const vector<char>& v, Result*,
const std::shared_ptr<fc::binary_api_connection>& )
294 template<
typename ResultInterface>
297 const std::shared_ptr<fc::binary_api_connection>& con
306 const std::shared_ptr<fc::binary_api_connection>& con
313 static result_type convert_callbacks(
const std::shared_ptr<fc::binary_api_connection>&,
const T& v )
318 template<
typename Signature>
319 static result_type convert_callbacks(
const std::shared_ptr<fc::binary_api_connection>& con,
const std::function<Signature>& v )
321 return con->register_callback( v );
324 template<
typename Result,
typename... Args>
325 void operator()(
const char*
name, std::function<Result(Args...)>& memb )
const
327 auto con = _connection;
328 auto api_id = _api_id;
329 memb = [con,api_id,
name]( Args... args ) {
330 auto var_result = con->send_call( api_id,
name, { convert_callbacks(con,args)...} );
331 return from_vector( var_result, (Result*)
nullptr, con );
334 template<
typename... Args>
335 void operator()(
const char*
name, std::function<
void(Args...)>& memb )
const
337 auto con = _connection;
338 auto api_id = _api_id;
339 memb = [con,api_id,
name]( Args... args ) {
340 con->send_call( api_id,
name, { convert_callbacks(con,args)...} );
378 template<
typename Api>
380 :_binary_api_connection(c),_api(
a)
382 boost::any_cast<const Api&>(
a)->visit(
api_visitor( *
this, c ) );
385 template<
typename Interface,
typename Adaptor,
typename ... Args>
386 std::function<result_type(
const params_type&)> generic_api::api_visitor::to_generic(
389 auto api_con = _api_con;
391 return [=](
const params_type& args ) {
392 auto con = api_con.lock();
395 fc::raw::datastream<const char*> ds( args.data(), args.size() );
396 auto api_result = gapi->call_generic(
f, args );
397 return con->register_api( api_result );
400 template<
typename Interface,
typename Adaptor,
typename ... Args>
401 std::function<result_type(
const params_type&)> generic_api::api_visitor::to_generic(
404 auto api_con = _api_con;
406 return [=](
const params_type& args )->
fc::variant {
407 auto con = api_con.lock();
410 fc::raw::datastream<const char*>
ds( args.data(), args.size() );
411 auto api_result = gapi->call_generic(
f, ds );
413 return con->register_api( *api_result );
414 return result_type();
418 template<
typename ... Args>
419 std::function<result_type(
const params_type&)> generic_api::api_visitor::to_generic(
422 auto api_con = _api_con;
425 auto con = api_con.lock();
428 fc::raw::datastream<const char*>
ds( args.data(), args.size() );
429 auto api_result = gapi->call_generic(
f, ds );
431 return result_type();
432 return api_result->register_api( *con );
436 template<
typename R,
typename ... Args>
437 std::function<result_type(
const params_type&)> generic_api::api_visitor::to_generic(
const std::function<
R(Args...)>&
f )
const
440 return [
f,gapi](
const params_type& args ) {
441 fc::raw::datastream<const char*>
ds( args.data(), args.size() );
446 template<
typename ... Args>
447 std::function<result_type(
const params_type&)> generic_api::api_visitor::to_generic(
const std::function<
void(Args...)>&
f )
const
450 return [
f,gapi](
const params_type& args ) {
451 fc::raw::datastream<const char*>
ds( args.data(), args.size() );
452 gapi->call_generic(
f, ds );
453 return result_type();
470 template<
typename Interface,
typename Transform >
473 return conn.register_api( *
this );
476 template<
typename T >
480 api<T>* maybe_requested_type =
dynamic_cast< api<T>*
>(
this);
481 if( maybe_requested_type !=
nullptr )
482 return *maybe_requested_type;
484 detail::any_api* maybe_any =
dynamic_cast< detail::any_api*
>(
this);
486 std::shared_ptr< binary_api_connection > api_conn = maybe_any->_binary_api_connection.lock();
488 return api_conn->get_remote_api<
T>( maybe_any->_api_id );
492 template<
typename Signature>
493 template<
typename... Args>
494 typename callback_functor<Signature>::result_type callback_functor<Signature>::operator()( Args... args )
const
496 std::shared_ptr< fc::binary_api_connection > locked = _binary_api_connection.lock();
499 throw fc::eof_exception();
502 locked->send_callback( _callback_id,
fc::raw::pack( args... ) ).template as< result_type >();
506 template<
typename... Args>
513 :_callback_id(
id),_binary_api_connection(con){}
517 std::shared_ptr< fc::binary_api_connection > locked = _binary_api_connection.lock();
520 throw fc::eof_exception();
521 locked->send_notice( _callback_id,
fc::variants{ args... } );
526 std::weak_ptr< fc::binary_api_connection > _binary_api_connection;
api< T, identity_member > as()
virtual api_id_type register_api(api_connection &conn) const override
result_type receive_call(api_id_type api_id, const string &method_name, const params_type &args=params_type()) const
std::vector< char > params_type
fc::signal< void()> closed
void receive_notice(uint64_t callback_id, const params_type &args=params_type()) const
virtual void send_notice(uint64_t callback_id, params_type args=params_type())=0
api_id_type register_api(const Interface &a)
std::vector< std::string > get_method_names(api_id_type local_api_id=0) const
virtual result_type send_callback(uint64_t callback_id, params_type args=params_type())=0
uint64_t register_callback(const std::function< Signature > &cb)
std::vector< char > result_type
result_type receive_callback(uint64_t callback_id, const params_type &args=params_type()) const
virtual ~binary_api_connection()
api< T > get_remote_api(api_id_type api_id=0)
virtual result_type send_call(api_id_type api_id, string method_name, params_type args=params_type())=0
virtual api_id_type register_api(binary_api_connection &conn) const override
std::weak_ptr< fc::binary_api_connection > _binary_api_connection
virtual uint64_t get_handle() const override
any_api(api_id_type api_id, const std::shared_ptr< fc::binary_api_connection > &con)
callback_functor(std::weak_ptr< fc::binary_api_connection > con, uint64_t id)
void operator()(Args... args) const
callback_functor(std::weak_ptr< fc::binary_api_connection > con, uint64_t id)
result_type operator()(Args... args) const
std::function< Signature >::result_type result_type
generic_api(const generic_api &cpy)=delete
std::vector< std::string > get_method_names() const
vector< char > call(const string &name, const vector< char > &args)
vector< char > call(uint32_t method_id, const vector< char > &args)
std::weak_ptr< fc::api_connection > get_connection()
friend struct api_visitor
variant call(const string &name, const variants &args)
std::weak_ptr< fc::binary_api_connection > get_connection()
generic_api(const Api &a, const std::shared_ptr< fc::api_connection > &c)
std::shared_ptr< fc::binary_api_connection > _remote_connection
virtual void send_notice(uint64_t callback_id, params_type args=params_type()) override
const std::shared_ptr< fc::binary_api_connection > & remote_connection() const
virtual result_type send_callback(uint64_t callback_id, params_type args=params_type()) override
virtual result_type send_call(api_id_type api_id, string method_name, params_type args=params_type()) override
void set_remote_connection(const std::shared_ptr< fc::binary_api_connection > &rc)
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
static const Segment ds(Segment::ds)
std::function< variant(const fc::variants &)> to_generic(const std::function< R(Args...)> &f)
R call_generic(const std::function< R()> &f, variants::const_iterator a0, variants::const_iterator e)
std::function< R(Args...)> bind_first_arg(const std::function< R(Arg0, Args...)> &f, Arg0 a0)
void unpack(Stream &s, std::deque< T > &value)
void pack(Stream &s, const std::deque< T > &value)
std::vector< fc::variant > variants
std::shared_ptr< api_base > api_ptr
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
#define T(meth, val, expected)
unsigned __int64 uint64_t