27#ifndef SDBUS_CPP_CONVENIENCEAPICLASSES_INL_
28#define SDBUS_CPP_CONVENIENCEAPICLASSES_INL_
50 inline VTableAdder::VTableAdder(
IObject&
object, std::vector<VTableItem> vtable)
52 , vtable_(std::move(vtable))
56 inline void VTableAdder::forInterface(InterfaceName interfaceName)
58 object_.addVTable(std::move(interfaceName), std::move(vtable_));
61 inline void VTableAdder::forInterface(std::string interfaceName)
63 forInterface(InterfaceName{std::move(interfaceName)});
66 [[nodiscard]]
inline Slot VTableAdder::forInterface(InterfaceName interfaceName, return_slot_t)
68 return object_.addVTable(std::move(interfaceName), std::move(vtable_), return_slot);
71 [[nodiscard]]
inline Slot VTableAdder::forInterface(std::string interfaceName, return_slot_t)
73 return forInterface(InterfaceName{std::move(interfaceName)}, return_slot);
80 inline SignalEmitter::SignalEmitter(IObject&
object,
const SignalName& signalName)
81 : SignalEmitter(object, signalName.c_str())
85 inline SignalEmitter::SignalEmitter(IObject&
object,
const char* signalName)
87 , signalName_(signalName)
88 , exceptions_(std::uncaught_exceptions())
92 inline SignalEmitter::~SignalEmitter() noexcept(false)
95 if (std::uncaught_exceptions() != exceptions_)
107 object_.emitSignal(signal_);
110 inline SignalEmitter& SignalEmitter::onInterface(
const InterfaceName& interfaceName)
112 return onInterface(interfaceName.c_str());
115 inline SignalEmitter& SignalEmitter::onInterface(
const std::string& interfaceName)
117 return onInterface(interfaceName.c_str());
120 inline SignalEmitter& SignalEmitter::onInterface(
const char* interfaceName)
122 signal_ = object_.createSignal(interfaceName, signalName_);
127 template <
typename... _Args>
128 inline void SignalEmitter::withArguments(_Args&&... args)
130 assert(signal_.isValid());
132 detail::serialize_pack(signal_, std::forward<_Args>(args)...);
139 inline MethodInvoker::MethodInvoker(IProxy& proxy,
const MethodName& methodName)
140 : MethodInvoker(proxy, methodName.c_str())
144 inline MethodInvoker::MethodInvoker(IProxy& proxy,
const char* methodName)
146 , methodName_(methodName)
147 , exceptions_(std::uncaught_exceptions())
151 inline MethodInvoker::~MethodInvoker() noexcept(false)
155 if (methodCalled_ || std::uncaught_exceptions() != exceptions_)
167 proxy_.callMethod(method_, timeout_);
170 inline MethodInvoker& MethodInvoker::onInterface(
const InterfaceName& interfaceName)
172 return onInterface(interfaceName.c_str());
175 inline MethodInvoker& MethodInvoker::onInterface(
const std::string& interfaceName)
177 return onInterface(interfaceName.c_str());
180 inline MethodInvoker& MethodInvoker::onInterface(
const char* interfaceName)
182 method_ = proxy_.createMethodCall(interfaceName, methodName_);
187 inline MethodInvoker& MethodInvoker::withTimeout(uint64_t usec)
194 template <
typename _Rep,
typename _Period>
195 inline MethodInvoker& MethodInvoker::withTimeout(
const std::chrono::duration<_Rep, _Period>& timeout)
197 auto microsecs = std::chrono::duration_cast<std::chrono::microseconds>(timeout);
198 return withTimeout(microsecs.count());
201 template <
typename... _Args>
202 inline MethodInvoker& MethodInvoker::withArguments(_Args&&... args)
204 assert(method_.isValid());
206 detail::serialize_pack(method_, std::forward<_Args>(args)...);
211 template <
typename... _Args>
212 inline void MethodInvoker::storeResultsTo(_Args&... args)
214 assert(method_.isValid());
216 auto reply = proxy_.callMethod(method_, timeout_);
217 methodCalled_ =
true;
219 detail::deserialize_pack(reply, args...);
222 inline void MethodInvoker::dontExpectReply()
224 assert(method_.isValid());
226 method_.dontExpectReply();
233 inline AsyncMethodInvoker::AsyncMethodInvoker(IProxy& proxy,
const MethodName& methodName)
234 : AsyncMethodInvoker(proxy, methodName.c_str())
238 inline AsyncMethodInvoker::AsyncMethodInvoker(IProxy& proxy,
const char* methodName)
240 , methodName_(methodName)
244 inline AsyncMethodInvoker& AsyncMethodInvoker::onInterface(
const InterfaceName& interfaceName)
246 return onInterface(interfaceName.c_str());
249 inline AsyncMethodInvoker& AsyncMethodInvoker::onInterface(
const std::string& interfaceName)
251 return onInterface(interfaceName.c_str());
254 inline AsyncMethodInvoker& AsyncMethodInvoker::onInterface(
const char* interfaceName)
256 method_ = proxy_.createMethodCall(interfaceName, methodName_);
261 inline AsyncMethodInvoker& AsyncMethodInvoker::withTimeout(uint64_t usec)
268 template <
typename _Rep,
typename _Period>
269 inline AsyncMethodInvoker& AsyncMethodInvoker::withTimeout(
const std::chrono::duration<_Rep, _Period>& timeout)
271 auto microsecs = std::chrono::duration_cast<std::chrono::microseconds>(timeout);
272 return withTimeout(microsecs.count());
275 template <
typename... _Args>
276 inline AsyncMethodInvoker& AsyncMethodInvoker::withArguments(_Args&&... args)
278 assert(method_.isValid());
280 detail::serialize_pack(method_, std::forward<_Args>(args)...);
285 template <
typename _Function>
286 PendingAsyncCall AsyncMethodInvoker::uponReplyInvoke(_Function&& callback)
288 assert(method_.isValid());
290 return proxy_.callMethodAsync(method_, makeAsyncReplyHandler(std::forward<_Function>(callback)), timeout_);
293 template <
typename _Function>
294 [[nodiscard]] Slot AsyncMethodInvoker::uponReplyInvoke(_Function&& callback, return_slot_t)
296 assert(method_.isValid());
298 return proxy_.callMethodAsync( method_
299 , makeAsyncReplyHandler(std::forward<_Function>(callback))
304 template <
typename _Function>
305 inline async_reply_handler AsyncMethodInvoker::makeAsyncReplyHandler(_Function&& callback)
307 return [callback = std::forward<_Function>(callback)](MethodReply reply, std::optional<Error> error)
311 tuple_of_function_input_arg_types_t<_Function> args;
320 catch (
const Error& e)
324 sdbus::apply(callback, e, args);
330 sdbus::apply(callback, std::move(error), args);
334 template <
typename... _Args>
335 std::future<future_return_t<_Args...>> AsyncMethodInvoker::getResultAsFuture()
337 auto promise = std::make_shared<std::promise<future_return_t<_Args...>>>();
338 auto future = promise->get_future();
340 uponReplyInvoke([promise = std::move(promise)](std::optional<Error> error, _Args... args)
343 if constexpr (!std::is_void_v<future_return_t<_Args...>>)
344 promise->set_value({std::move(args)...});
346 promise->set_value();
348 promise->set_exception(std::make_exception_ptr(*std::move(error)));
361 inline SignalSubscriber::SignalSubscriber(IProxy& proxy,
const SignalName& signalName)
362 : SignalSubscriber(proxy, signalName.c_str())
366 inline SignalSubscriber::SignalSubscriber(IProxy& proxy,
const char* signalName)
368 , signalName_(signalName)
372 inline SignalSubscriber& SignalSubscriber::onInterface(
const InterfaceName& interfaceName)
374 return onInterface(interfaceName.c_str());
377 inline SignalSubscriber& SignalSubscriber::onInterface(
const std::string& interfaceName)
379 return onInterface(interfaceName.c_str());
382 inline SignalSubscriber& SignalSubscriber::onInterface(
const char* interfaceName)
384 interfaceName_ = std::move(interfaceName);
389 template <
typename _Function>
390 inline void SignalSubscriber::call(_Function&& callback)
392 assert(interfaceName_ !=
nullptr);
394 proxy_.registerSignalHandler( interfaceName_
396 , makeSignalHandler(std::forward<_Function>(callback)) );
399 template <
typename _Function>
400 [[nodiscard]]
inline Slot SignalSubscriber::call(_Function&& callback, return_slot_t)
402 assert(interfaceName_ !=
nullptr);
404 return proxy_.registerSignalHandler( interfaceName_
406 , makeSignalHandler(std::forward<_Function>(callback))
410 template <
typename _Function>
411 inline signal_handler SignalSubscriber::makeSignalHandler(_Function&& callback)
413 return [callback = std::forward<_Function>(callback)](Signal signal)
417 tuple_of_function_input_arg_types_t<_Function> signalArgs;
423 if constexpr (has_error_param_v<_Function>)
428 signal >> signalArgs;
434 sdbus::apply(callback, e, signalArgs);
439 sdbus::apply(callback, {}, signalArgs);
444 signal >> signalArgs;
447 sdbus::apply(callback, signalArgs);
456 inline PropertyGetter::PropertyGetter(IProxy& proxy, std::string_view propertyName)
458 , propertyName_(std::move(propertyName))
462 inline Variant PropertyGetter::onInterface(std::string_view interfaceName)
465 proxy_.callMethod(
"Get")
466 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
467 .withArguments(interfaceName, propertyName_)
468 .storeResultsTo(var);
476 inline AsyncPropertyGetter::AsyncPropertyGetter(IProxy& proxy, std::string_view propertyName)
478 , propertyName_(std::move(propertyName))
482 inline AsyncPropertyGetter& AsyncPropertyGetter::onInterface(std::string_view interfaceName)
484 interfaceName_ = std::move(interfaceName);
489 template <
typename _Function>
490 PendingAsyncCall AsyncPropertyGetter::uponReplyInvoke(_Function&& callback)
492 static_assert( std::is_invocable_r_v<void, _Function, std::optional<Error>, Variant>
493 ,
"Property get callback function must accept std::optional<Error> and property value as Variant" );
495 assert(!interfaceName_.empty());
497 return proxy_.callMethodAsync(
"Get")
498 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
499 .withArguments(interfaceName_, propertyName_)
500 .uponReplyInvoke(std::forward<_Function>(callback));
503 template <
typename _Function>
504 [[nodiscard]] Slot AsyncPropertyGetter::uponReplyInvoke(_Function&& callback, return_slot_t)
506 static_assert( std::is_invocable_r_v<void, _Function, std::optional<Error>, Variant>
507 ,
"Property get callback function must accept std::optional<Error> and property value as Variant" );
509 assert(!interfaceName_.empty());
511 return proxy_.callMethodAsync(
"Get")
512 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
513 .withArguments(interfaceName_, propertyName_)
514 .uponReplyInvoke(std::forward<_Function>(callback), return_slot);
517 inline std::future<Variant> AsyncPropertyGetter::getResultAsFuture()
519 assert(!interfaceName_.empty());
521 return proxy_.callMethodAsync(
"Get")
522 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
523 .withArguments(interfaceName_, propertyName_)
524 .getResultAsFuture<Variant>();
531 inline PropertySetter::PropertySetter(IProxy& proxy, std::string_view propertyName)
533 , propertyName_(std::move(propertyName))
537 inline PropertySetter& PropertySetter::onInterface(std::string_view interfaceName)
539 interfaceName_ = std::move(interfaceName);
544 template <
typename _Value>
545 inline void PropertySetter::toValue(
const _Value& value)
547 PropertySetter::toValue(Variant{value});
550 template <
typename _Value>
551 inline void PropertySetter::toValue(
const _Value& value, dont_expect_reply_t)
553 PropertySetter::toValue(Variant{value}, dont_expect_reply);
556 inline void PropertySetter::toValue(
const Variant& value)
558 assert(!interfaceName_.empty());
560 proxy_.callMethod(
"Set")
561 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
562 .withArguments(interfaceName_, propertyName_, value);
565 inline void PropertySetter::toValue(
const Variant& value, dont_expect_reply_t)
567 assert(!interfaceName_.empty());
569 proxy_.callMethod(
"Set")
570 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
571 .withArguments(interfaceName_, propertyName_, value)
579 inline AsyncPropertySetter::AsyncPropertySetter(IProxy& proxy, std::string_view propertyName)
581 , propertyName_(propertyName)
585 inline AsyncPropertySetter& AsyncPropertySetter::onInterface(std::string_view interfaceName)
587 interfaceName_ = std::move(interfaceName);
592 template <
typename _Value>
593 inline AsyncPropertySetter& AsyncPropertySetter::toValue(_Value&& value)
595 return AsyncPropertySetter::toValue(Variant{std::forward<_Value>(value)});
598 inline AsyncPropertySetter& AsyncPropertySetter::toValue(Variant value)
600 value_ = std::move(value);
605 template <
typename _Function>
606 PendingAsyncCall AsyncPropertySetter::uponReplyInvoke(_Function&& callback)
608 static_assert( std::is_invocable_r_v<void, _Function, std::optional<Error>>
609 ,
"Property set callback function must accept std::optional<Error> only" );
611 assert(!interfaceName_.empty());
613 return proxy_.callMethodAsync(
"Set")
614 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
615 .withArguments(interfaceName_, propertyName_, std::move(value_))
616 .uponReplyInvoke(std::forward<_Function>(callback));
619 template <
typename _Function>
620 [[nodiscard]] Slot AsyncPropertySetter::uponReplyInvoke(_Function&& callback, return_slot_t)
622 static_assert( std::is_invocable_r_v<void, _Function, std::optional<Error>>
623 ,
"Property set callback function must accept std::optional<Error> only" );
625 assert(!interfaceName_.empty());
627 return proxy_.callMethodAsync(
"Set")
628 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
629 .withArguments(interfaceName_, propertyName_, std::move(value_))
630 .uponReplyInvoke(std::forward<_Function>(callback), return_slot);
633 inline std::future<void> AsyncPropertySetter::getResultAsFuture()
635 assert(!interfaceName_.empty());
637 return proxy_.callMethodAsync(
"Set")
638 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
639 .withArguments(interfaceName_, propertyName_, std::move(value_))
640 .getResultAsFuture<>();
647 inline AllPropertiesGetter::AllPropertiesGetter(IProxy& proxy)
652 inline std::map<PropertyName, Variant> AllPropertiesGetter::onInterface(std::string_view interfaceName)
654 std::map<PropertyName, Variant> props;
655 proxy_.callMethod(
"GetAll")
656 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
657 .withArguments(std::move(interfaceName))
658 .storeResultsTo(props);
666 inline AsyncAllPropertiesGetter::AsyncAllPropertiesGetter(IProxy& proxy)
671 inline AsyncAllPropertiesGetter& AsyncAllPropertiesGetter::onInterface(std::string_view interfaceName)
673 interfaceName_ = std::move(interfaceName);
678 template <
typename _Function>
679 PendingAsyncCall AsyncAllPropertiesGetter::uponReplyInvoke(_Function&& callback)
681 static_assert( std::is_invocable_r_v<void, _Function, std::optional<Error>, std::map<PropertyName, Variant>>
682 ,
"All properties get callback function must accept std::optional<Error> and a map of property names to their values" );
684 assert(!interfaceName_.empty());
686 return proxy_.callMethodAsync(
"GetAll")
687 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
688 .withArguments(interfaceName_)
689 .uponReplyInvoke(std::forward<_Function>(callback));
692 template <
typename _Function>
693 [[nodiscard]] Slot AsyncAllPropertiesGetter::uponReplyInvoke(_Function&& callback, return_slot_t)
695 static_assert( std::is_invocable_r_v<void, _Function, std::optional<Error>, std::map<PropertyName, Variant>>
696 ,
"All properties get callback function must accept std::optional<Error> and a map of property names to their values" );
698 assert(!interfaceName_.empty());
700 return proxy_.callMethodAsync(
"GetAll")
701 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
702 .withArguments(interfaceName_)
703 .uponReplyInvoke(std::forward<_Function>(callback), return_slot);
706 inline std::future<std::map<PropertyName, Variant>> AsyncAllPropertiesGetter::getResultAsFuture()
708 assert(!interfaceName_.empty());
710 return proxy_.callMethodAsync(
"GetAll")
711 .onInterface(DBUS_PROPERTIES_INTERFACE_NAME)
712 .withArguments(interfaceName_)
713 .getResultAsFuture<std::map<PropertyName, Variant>>();