/* * Copyright 2019 by its authors. See AUTHORS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ELDBUS_PROXY_CALL_HH #define ELDBUS_PROXY_CALL_HH #include #include #include #include #include #include #include #include #include #include namespace efl { namespace eldbus { namespace _detail { template struct tag {}; template void _on_call_impl(void* data, Eldbus_Message const* message, Eldbus_Pending* pending) { std::unique_ptr callback(static_cast(data)); const char* errname, *errmsg; if (eldbus_message_error_get(message, &errname, &errmsg)) { Seq tuple_; ::eldbus_message_ref(const_cast(message)); eldbus::const_message msg(message); eina::error_code ec (eldbus::call_error_code(), eina::eina_error_category()); eina::call_tuple_unwrap_prefix (*callback, tuple_, eina::make_index_sequence::value>() , ec, msg, pending); } typename raw_tuple::type tuple; if(std::tuple_size::value) { if(!_detail::_init_raw_tuple<0u, Seq> (eldbus_message_iter_get(message) , tuple, std::integral_constant::value == 0)>())) { Seq tuple_; ::eldbus_message_ref(const_cast(message)); eldbus::const_message msg(message); eina::error_code ec(eldbus::signature_mismatch_error_code(), eina::eina_error_category()); eina::call_tuple_unwrap_prefix (*callback, tuple_, eina::make_index_sequence::value>() , ec, msg, pending); } } eina::error_code ec; ::eldbus_message_ref(const_cast(message)); eldbus::const_message msg(message); eina::call_tuple_unwrap_prefix (*callback, tuple, eina::make_index_sequence::value>() , ec, msg, pending); } template void _on_call(void* data, Eldbus_Message const* message, Eldbus_Pending* pending) { _detail::_on_call_impl(data, message, pending); } template void proxy_call_impl2(Eldbus_Proxy* proxy, const char* method, double timeout , Callback&& callback, Args const&... args) { typedef std::tuple tuple_args; char signature[signature_size::value +1]; _detail::init_signature_array (signature, eina::make_index_sequence::value +1>()); Callback* c = new Callback(std::forward(callback)); eldbus_proxy_call(proxy, method, &_on_call, c, timeout, signature , _detail::to_raw(args)...); } template void proxy_call_impl(tag, Eldbus_Proxy* proxy, const char* method, double timeout , Callback&& callback, Args const&... args) { typedef std::tuple reply_tuple; _detail::proxy_call_impl2(proxy, method, timeout, std::forward(callback), args...); } template void proxy_call_impl(tag >, Eldbus_Proxy* proxy, const char* method, double timeout , Callback&& callback, Args const&... args) { typedef std::tuple reply_tuple; _detail::proxy_call_impl2(proxy, method, timeout, std::forward(callback), args...); } template void proxy_call_impl(tag, Eldbus_Proxy* proxy, const char* method, double timeout , Callback&& callback, Args const&... args) { typedef std::tuple<> reply_tuple; _detail::proxy_call_impl2(proxy, method, timeout, std::forward(callback), args...); } template void proxy_call(Eldbus_Proxy* proxy, const char* method, double timeout , Callback&& callback, Args const&... args) { return proxy_call_impl(tag(), proxy, method, timeout, std::forward(callback), args...); } } } } #endif