diff --git a/docs/using-sdbus-c++.md b/docs/using-sdbus-c++.md index 1cde2cf..0771d73 100644 --- a/docs/using-sdbus-c++.md +++ b/docs/using-sdbus-c++.md @@ -714,7 +714,7 @@ namespace sdbuscpp { class Concatenator_adaptor { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.Concatenator"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.Concatenator"; protected: Concatenator_adaptor(sdbus::IObject& object) @@ -773,7 +773,7 @@ namespace sdbuscpp { class Concatenator_proxy { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.Concatenator"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.Concatenator"; protected: Concatenator_proxy(sdbus::IProxy& proxy) diff --git a/examples/org.freedesktop.DBus.ObjectManager/examplemanager-planet1-client-glue.h b/examples/org.freedesktop.DBus.ObjectManager/examplemanager-planet1-client-glue.h index 4b6847e..b312656 100644 --- a/examples/org.freedesktop.DBus.ObjectManager/examplemanager-planet1-client-glue.h +++ b/examples/org.freedesktop.DBus.ObjectManager/examplemanager-planet1-client-glue.h @@ -17,7 +17,7 @@ namespace ExampleManager { class Planet1_proxy { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.ExampleManager.Planet1"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.ExampleManager.Planet1"; protected: Planet1_proxy(sdbus::IProxy& proxy) diff --git a/examples/org.freedesktop.DBus.ObjectManager/examplemanager-planet1-server-glue.h b/examples/org.freedesktop.DBus.ObjectManager/examplemanager-planet1-server-glue.h index 7acfac0..b2ca89c 100644 --- a/examples/org.freedesktop.DBus.ObjectManager/examplemanager-planet1-server-glue.h +++ b/examples/org.freedesktop.DBus.ObjectManager/examplemanager-planet1-server-glue.h @@ -17,7 +17,7 @@ namespace ExampleManager { class Planet1_adaptor { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.ExampleManager.Planet1"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.ExampleManager.Planet1"; protected: Planet1_adaptor(sdbus::IObject& object) diff --git a/examples/org.freedesktop.DBus.ObjectManager/obj-manager-client.cpp b/examples/org.freedesktop.DBus.ObjectManager/obj-manager-client.cpp index be6f1b2..fb2d8a3 100644 --- a/examples/org.freedesktop.DBus.ObjectManager/obj-manager-client.cpp +++ b/examples/org.freedesktop.DBus.ObjectManager/obj-manager-client.cpp @@ -64,7 +64,7 @@ private: std::cout << std::endl; // Parse and print some more info - auto planetInterface = interfacesAndProperties.find(org::sdbuscpp::ExampleManager::Planet1_proxy::INTERFACE_NAME); + auto planetInterface = interfacesAndProperties.find(sdbus::InterfaceName{org::sdbuscpp::ExampleManager::Planet1_proxy::INTERFACE_NAME}); if (planetInterface == interfacesAndProperties.end()) { return; } diff --git a/examples/org.freedesktop.DBus.ObjectManager/obj-manager-server.cpp b/examples/org.freedesktop.DBus.ObjectManager/obj-manager-server.cpp index 9d4ef7d..2086f9d 100644 --- a/examples/org.freedesktop.DBus.ObjectManager/obj-manager-server.cpp +++ b/examples/org.freedesktop.DBus.ObjectManager/obj-manager-server.cpp @@ -47,12 +47,12 @@ public: , m_population(population) { registerAdaptor(); - emitInterfacesAddedSignal({org::sdbuscpp::ExampleManager::Planet1_adaptor::INTERFACE_NAME}); + emitInterfacesAddedSignal({sdbus::InterfaceName{org::sdbuscpp::ExampleManager::Planet1_adaptor::INTERFACE_NAME}}); } ~PlanetAdaptor() { - emitInterfacesRemovedSignal({org::sdbuscpp::ExampleManager::Planet1_adaptor::INTERFACE_NAME}); + emitInterfacesRemovedSignal({sdbus::InterfaceName{org::sdbuscpp::ExampleManager::Planet1_adaptor::INTERFACE_NAME}}); unregisterAdaptor(); } diff --git a/include/sdbus-c++/ConvenienceApiClasses.h b/include/sdbus-c++/ConvenienceApiClasses.h index 2d9dcec..6a1d5c0 100644 --- a/include/sdbus-c++/ConvenienceApiClasses.h +++ b/include/sdbus-c++/ConvenienceApiClasses.h @@ -53,12 +53,15 @@ namespace sdbus { class VTableAdder { public: - VTableAdder(IObject& object, std::vector vtable); void forInterface(InterfaceName interfaceName); void forInterface(std::string interfaceName); [[nodiscard]] Slot forInterface(InterfaceName interfaceName, return_slot_t); [[nodiscard]] Slot forInterface(std::string interfaceName, return_slot_t); + private: + friend IObject; + VTableAdder(IObject& object, std::vector vtable); + private: IObject& object_; std::vector vtable_; @@ -67,16 +70,22 @@ namespace sdbus { class SignalEmitter { public: - SignalEmitter(IObject& object, const SignalName& signalName); - SignalEmitter(SignalEmitter&& other) = default; - ~SignalEmitter() noexcept(false); SignalEmitter& onInterface(const InterfaceName& interfaceName); SignalEmitter& onInterface(const std::string& interfaceName); + SignalEmitter& onInterface(const char* interfaceName); template void withArguments(_Args&&... args); + SignalEmitter(SignalEmitter&& other) = default; + ~SignalEmitter() noexcept(false); + + private: + friend IObject; + SignalEmitter(IObject& object, const SignalName& signalName); + SignalEmitter(IObject& object, const char* signalName); + private: IObject& object_; - const SignalName& signalName_; + const char* signalName_; Signal signal_; int exceptions_{}; // Number of active exceptions when SignalEmitter is constructed }; @@ -84,23 +93,27 @@ namespace sdbus { class MethodInvoker { public: - MethodInvoker(IProxy& proxy, const MethodName& methodName); - MethodInvoker(MethodInvoker&& other) = default; - ~MethodInvoker() noexcept(false); - MethodInvoker& onInterface(const InterfaceName& interfaceName); MethodInvoker& onInterface(const std::string& interfaceName); + MethodInvoker& onInterface(const char* interfaceName); MethodInvoker& withTimeout(uint64_t usec); template MethodInvoker& withTimeout(const std::chrono::duration<_Rep, _Period>& timeout); template MethodInvoker& withArguments(_Args&&... args); template void storeResultsTo(_Args&... args); - void dontExpectReply(); + MethodInvoker(MethodInvoker&& other) = default; + ~MethodInvoker() noexcept(false); + + private: + friend IProxy; + MethodInvoker(IProxy& proxy, const MethodName& methodName); + MethodInvoker(IProxy& proxy, const char* methodName); + private: IProxy& proxy_; - const MethodName& methodName_; + const char* methodName_; uint64_t timeout_{}; MethodCall method_; int exceptions_{}; // Number of active exceptions when MethodInvoker is constructed @@ -110,9 +123,9 @@ namespace sdbus { class AsyncMethodInvoker { public: - AsyncMethodInvoker(IProxy& proxy, const MethodName& methodName); AsyncMethodInvoker& onInterface(const InterfaceName& interfaceName); AsyncMethodInvoker& onInterface(const std::string& interfaceName); + AsyncMethodInvoker& onInterface(const char* interfaceName); AsyncMethodInvoker& withTimeout(uint64_t usec); template AsyncMethodInvoker& withTimeout(const std::chrono::duration<_Rep, _Period>& timeout); @@ -123,9 +136,14 @@ namespace sdbus { // or std::future> for multiple method return values template std::future> getResultAsFuture(); + private: + friend IProxy; + AsyncMethodInvoker(IProxy& proxy, const MethodName& methodName); + AsyncMethodInvoker(IProxy& proxy, const char* methodName); + private: IProxy& proxy_; - const MethodName& methodName_; + const char* methodName_; uint64_t timeout_{}; MethodCall method_; }; @@ -133,29 +151,34 @@ namespace sdbus { class SignalSubscriber { public: - SignalSubscriber(IProxy& proxy, const SignalName& signalName); - SignalSubscriber& onInterface(InterfaceName interfaceName); // TODO: This could be const char* - SignalSubscriber& onInterface(std::string interfaceName); // TODO: This could be const char* + SignalSubscriber& onInterface(const InterfaceName& interfaceName); + SignalSubscriber& onInterface(const std::string& interfaceName); + SignalSubscriber& onInterface(const char* interfaceName); template void call(_Function&& callback); template [[nodiscard]] Slot call(_Function&& callback, return_slot_t); private: + friend IProxy; + SignalSubscriber(IProxy& proxy, const SignalName& signalName); + SignalSubscriber(IProxy& proxy, const char* signalName); template signal_handler makeSignalHandler(_Function&& callback); private: IProxy& proxy_; - const SignalName& signalName_; - InterfaceName interfaceName_; + const char* signalName_; + const char* interfaceName_{}; }; class PropertyGetter { public: - PropertyGetter(IProxy& proxy, std::string_view propertyName); Variant onInterface(std::string_view interfaceName); private: - static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; + friend IProxy; + PropertyGetter(IProxy& proxy, std::string_view propertyName); + + static constexpr const char* DBUS_PROPERTIES_INTERFACE_NAME = "org.freedesktop.DBus.Properties"; private: IProxy& proxy_; @@ -165,13 +188,15 @@ namespace sdbus { class AsyncPropertyGetter { public: - AsyncPropertyGetter(IProxy& proxy, std::string_view propertyName); AsyncPropertyGetter& onInterface(std::string_view interfaceName); template PendingAsyncCall uponReplyInvoke(_Function&& callback); std::future getResultAsFuture(); private: - static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; + friend IProxy; + AsyncPropertyGetter(IProxy& proxy, std::string_view propertyName); + + static constexpr const char* DBUS_PROPERTIES_INTERFACE_NAME = "org.freedesktop.DBus.Properties"; private: IProxy& proxy_; @@ -182,7 +207,6 @@ namespace sdbus { class PropertySetter { public: - PropertySetter(IProxy& proxy, std::string_view propertyName); PropertySetter& onInterface(std::string_view interfaceName); template void toValue(const _Value& value); template void toValue(const _Value& value, dont_expect_reply_t); @@ -190,7 +214,10 @@ namespace sdbus { void toValue(const Variant& value, dont_expect_reply_t); private: - static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; + friend IProxy; + PropertySetter(IProxy& proxy, std::string_view propertyName); + + static constexpr const char* DBUS_PROPERTIES_INTERFACE_NAME = "org.freedesktop.DBus.Properties"; private: IProxy& proxy_; @@ -201,7 +228,6 @@ namespace sdbus { class AsyncPropertySetter { public: - AsyncPropertySetter(IProxy& proxy, std::string_view propertyName); AsyncPropertySetter& onInterface(std::string_view interfaceName); template AsyncPropertySetter& toValue(_Value&& value); AsyncPropertySetter& toValue(Variant value); @@ -209,7 +235,10 @@ namespace sdbus { std::future getResultAsFuture(); private: - static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; + friend IProxy; + AsyncPropertySetter(IProxy& proxy, std::string_view propertyName); + + static constexpr const char* DBUS_PROPERTIES_INTERFACE_NAME = "org.freedesktop.DBus.Properties"; private: IProxy& proxy_; @@ -221,11 +250,13 @@ namespace sdbus { class AllPropertiesGetter { public: - AllPropertiesGetter(IProxy& proxy); std::map onInterface(std::string_view interfaceName); private: - static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; + friend IProxy; + AllPropertiesGetter(IProxy& proxy); + + static constexpr const char* DBUS_PROPERTIES_INTERFACE_NAME = "org.freedesktop.DBus.Properties"; private: IProxy& proxy_; @@ -234,13 +265,15 @@ namespace sdbus { class AsyncAllPropertiesGetter { public: - AsyncAllPropertiesGetter(IProxy& proxy); AsyncAllPropertiesGetter& onInterface(std::string_view interfaceName); template PendingAsyncCall uponReplyInvoke(_Function&& callback); std::future> getResultAsFuture(); private: - static inline const InterfaceName DBUS_PROPERTIES_INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; // TODO: Couldn't this be const char*? + friend IProxy; + AsyncAllPropertiesGetter(IProxy& proxy); + + static constexpr const char* DBUS_PROPERTIES_INTERFACE_NAME = "org.freedesktop.DBus.Properties"; private: IProxy& proxy_; diff --git a/include/sdbus-c++/ConvenienceApiClasses.inl b/include/sdbus-c++/ConvenienceApiClasses.inl index fb67973..93ea4a1 100644 --- a/include/sdbus-c++/ConvenienceApiClasses.inl +++ b/include/sdbus-c++/ConvenienceApiClasses.inl @@ -78,6 +78,11 @@ namespace sdbus { /*** ------------- ***/ inline SignalEmitter::SignalEmitter(IObject& object, const SignalName& signalName) + : SignalEmitter(object, signalName.c_str()) + { + } + + inline SignalEmitter::SignalEmitter(IObject& object, const char* signalName) : object_(object) , signalName_(signalName) , exceptions_(std::uncaught_exceptions()) @@ -104,16 +109,19 @@ namespace sdbus { inline SignalEmitter& SignalEmitter::onInterface(const InterfaceName& interfaceName) { - signal_ = object_.createSignal(interfaceName, signalName_); - - return *this; + return onInterface(interfaceName.c_str()); } inline SignalEmitter& SignalEmitter::onInterface(const std::string& interfaceName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(interfaceName) == sizeof(InterfaceName)); - return onInterface(static_cast(interfaceName)); + return onInterface(interfaceName.c_str()); + } + + inline SignalEmitter& SignalEmitter::onInterface(const char* interfaceName) + { + signal_ = object_.createSignal(interfaceName, signalName_); + + return *this; } template @@ -129,6 +137,11 @@ namespace sdbus { /*** ------------- ***/ inline MethodInvoker::MethodInvoker(IProxy& proxy, const MethodName& methodName) + : MethodInvoker(proxy, methodName.c_str()) + { + } + + inline MethodInvoker::MethodInvoker(IProxy& proxy, const char* methodName) : proxy_(proxy) , methodName_(methodName) , exceptions_(std::uncaught_exceptions()) @@ -156,16 +169,19 @@ namespace sdbus { inline MethodInvoker& MethodInvoker::onInterface(const InterfaceName& interfaceName) { - method_ = proxy_.createMethodCall(interfaceName, methodName_); - - return *this; + return onInterface(interfaceName.c_str()); } inline MethodInvoker& MethodInvoker::onInterface(const std::string& interfaceName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(interfaceName) == sizeof(InterfaceName)); - return onInterface(static_cast(interfaceName)); + return onInterface(interfaceName.c_str()); + } + + inline MethodInvoker& MethodInvoker::onInterface(const char* interfaceName) + { + method_ = proxy_.createMethodCall(interfaceName, methodName_); + + return *this; } inline MethodInvoker& MethodInvoker::withTimeout(uint64_t usec) @@ -215,6 +231,11 @@ namespace sdbus { /*** ------------------ ***/ inline AsyncMethodInvoker::AsyncMethodInvoker(IProxy& proxy, const MethodName& methodName) + : AsyncMethodInvoker(proxy, methodName.c_str()) + { + } + + inline AsyncMethodInvoker::AsyncMethodInvoker(IProxy& proxy, const char* methodName) : proxy_(proxy) , methodName_(methodName) { @@ -222,16 +243,19 @@ namespace sdbus { inline AsyncMethodInvoker& AsyncMethodInvoker::onInterface(const InterfaceName& interfaceName) { - method_ = proxy_.createMethodCall(interfaceName, methodName_); - - return *this; + return onInterface(interfaceName.c_str()); } inline AsyncMethodInvoker& AsyncMethodInvoker::onInterface(const std::string& interfaceName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(interfaceName) == sizeof(InterfaceName)); - return onInterface(static_cast(interfaceName)); + return onInterface(interfaceName.c_str()); + } + + inline AsyncMethodInvoker& AsyncMethodInvoker::onInterface(const char* interfaceName) + { + method_ = proxy_.createMethodCall(interfaceName, methodName_); + + return *this; } inline AsyncMethodInvoker& AsyncMethodInvoker::withTimeout(uint64_t usec) @@ -320,17 +344,27 @@ namespace sdbus { /*** ---------------- ***/ inline SignalSubscriber::SignalSubscriber(IProxy& proxy, const SignalName& signalName) + : SignalSubscriber(proxy, signalName.c_str()) + { + } + + inline SignalSubscriber::SignalSubscriber(IProxy& proxy, const char* signalName) : proxy_(proxy) , signalName_(signalName) { } - inline SignalSubscriber& SignalSubscriber::onInterface(std::string interfaceName) + inline SignalSubscriber& SignalSubscriber::onInterface(const InterfaceName& interfaceName) { - return onInterface(InterfaceName{std::move(interfaceName)}); + return onInterface(interfaceName.c_str()); } - inline SignalSubscriber& SignalSubscriber::onInterface(InterfaceName interfaceName) + inline SignalSubscriber& SignalSubscriber::onInterface(const std::string& interfaceName) + { + return onInterface(interfaceName.c_str()); + } + + inline SignalSubscriber& SignalSubscriber::onInterface(const char* interfaceName) { interfaceName_ = std::move(interfaceName); @@ -340,7 +374,7 @@ namespace sdbus { template inline void SignalSubscriber::call(_Function&& callback) { - assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function + assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function proxy_.registerSignalHandler( interfaceName_ , signalName_ @@ -350,7 +384,7 @@ namespace sdbus { template [[nodiscard]] inline Slot SignalSubscriber::call(_Function&& callback, return_slot_t) { - assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function + assert(interfaceName_ != nullptr); // onInterface() must be placed/called prior to this function return proxy_.registerSignalHandler( interfaceName_ , signalName_ diff --git a/include/sdbus-c++/IObject.h b/include/sdbus-c++/IObject.h index 97b3147..2606c87 100644 --- a/include/sdbus-c++/IObject.h +++ b/include/sdbus-c++/IObject.h @@ -225,26 +225,15 @@ namespace sdbus { [[nodiscard]] SignalEmitter emitSignal(const SignalName& signalName); /*! - * @brief Emits signal on D-Bus - * - * @param[in] signalName Name of the signal - * @return A helper object for convenient emission of signals - * - * This is a high-level, convenience way of emitting D-Bus signals that abstracts - * from the D-Bus message concept. Signal arguments are automatically serialized - * in a message and D-Bus signatures automatically deduced from the provided native arguments. - * - * Example of use: - * @code - * int arg1 = ...; - * double arg2 = ...; - * object_.emitSignal("fooSignal").onInterface("com.kistler.foo").withArguments(arg1, arg2); - * @endcode - * - * @throws sdbus::Error in case of failure + * @copydoc IObject::emitSignal(const SignalName&) */ [[nodiscard]] SignalEmitter emitSignal(const std::string& signalName); + /*! + * @copydoc IObject::emitSignal(const SignalName&) + */ + [[nodiscard]] SignalEmitter emitSignal(const char* signalName); + /*! * @brief Emits PropertyChanged signal for specified properties under a given interface of this object path * @@ -255,6 +244,11 @@ namespace sdbus { */ virtual void emitPropertiesChangedSignal(const InterfaceName& interfaceName, const std::vector& propNames) = 0; + /*! + * @copydoc IObject::emitPropertiesChangedSignal(const InterfaceName&,const std::vector&) + */ + virtual void emitPropertiesChangedSignal(const char* interfaceName, const std::vector& propNames) = 0; + /*! * @brief Emits PropertyChanged signal for all properties on a given interface of this object path * @@ -264,6 +258,11 @@ namespace sdbus { */ virtual void emitPropertiesChangedSignal(const InterfaceName& interfaceName) = 0; + /*! + * @copydoc IObject::emitPropertiesChangedSignal(const InterfaceName&) + */ + virtual void emitPropertiesChangedSignal(const char* interfaceName) = 0; + /*! * @brief Emits InterfacesAdded signal on this object path * @@ -361,6 +360,11 @@ namespace sdbus { * @return Currently processed D-Bus message */ [[nodiscard]] virtual Message getCurrentlyProcessedMessage() const = 0; + + protected: + friend SignalEmitter; + + [[nodiscard]] virtual Signal createSignal(const char* interfaceName, const char* signalName) = 0; }; // Out-of-line member definitions @@ -372,9 +376,12 @@ namespace sdbus { inline SignalEmitter IObject::emitSignal(const std::string& signalName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(signalName) == sizeof(SignalName)); - return emitSignal(static_cast(signalName)); + return SignalEmitter(*this, signalName.c_str()); + } + + inline SignalEmitter IObject::emitSignal(const char* signalName) + { + return SignalEmitter(*this, signalName); } template diff --git a/include/sdbus-c++/IProxy.h b/include/sdbus-c++/IProxy.h index 46c7cbe..8f0d0bd 100644 --- a/include/sdbus-c++/IProxy.h +++ b/include/sdbus-c++/IProxy.h @@ -226,6 +226,11 @@ namespace sdbus { */ [[nodiscard]] MethodInvoker callMethod(const std::string& methodName); + /*! + * @copydoc IProxy::callMethod(const MethodName&) + */ + [[nodiscard]] MethodInvoker callMethod(const char* methodName); + /*! * @brief Calls method on the D-Bus object asynchronously * @@ -256,6 +261,11 @@ namespace sdbus { */ [[nodiscard]] AsyncMethodInvoker callMethodAsync(const std::string& methodName); + /*! + * @copydoc IProxy::callMethodAsync(const MethodName&) + */ + [[nodiscard]] AsyncMethodInvoker callMethodAsync(const char* methodName); + /*! * @brief Registers a handler for the desired signal emitted by the D-Bus object * @@ -323,6 +333,11 @@ namespace sdbus { */ [[nodiscard]] SignalSubscriber uponSignal(const std::string& signalName); + /*! + * @copydoc IProxy::uponSignal(const SignalName&) + */ + [[nodiscard]] SignalSubscriber uponSignal(const char* signalName); + /*! * @brief Unregisters proxy's signal handlers and stops receiving replies to pending async calls * @@ -384,7 +399,7 @@ namespace sdbus { /*! * @copydoc IProxy::getPropertyAsync(const PropertyName&) */ - [[nodiscard]] AsyncPropertyGetter getPropertyAsync(const std::string& propertyName); + [[nodiscard]] AsyncPropertyGetter getPropertyAsync(std::string_view propertyName); /*! * @brief Sets value of a property of the D-Bus object @@ -411,7 +426,7 @@ namespace sdbus { /*! * @copydoc IProxy::setProperty(const PropertyName&) */ - [[nodiscard]] PropertySetter setProperty(const std::string& propertyName); + [[nodiscard]] PropertySetter setProperty(std::string_view propertyName); /*! * @brief Sets value of a property of the D-Bus object asynchronously @@ -436,7 +451,7 @@ namespace sdbus { /*! * @copydoc IProxy::setPropertyAsync(const PropertyName&) */ - [[nodiscard]] AsyncPropertySetter setPropertyAsync(const std::string& propertyName); + [[nodiscard]] AsyncPropertySetter setPropertyAsync(std::string_view propertyName); /*! * @brief Gets values of all properties of the D-Bus object @@ -499,6 +514,20 @@ namespace sdbus { * @return Currently processed D-Bus message */ [[nodiscard]] virtual Message getCurrentlyProcessedMessage() const = 0; + + protected: + friend MethodInvoker; + friend AsyncMethodInvoker; + friend SignalSubscriber; + + [[nodiscard]] virtual MethodCall createMethodCall(const char* interfaceName, const char* methodName) = 0; + virtual void registerSignalHandler( const char* interfaceName + , const char* signalName + , signal_handler signalHandler ) = 0; + [[nodiscard]] virtual Slot registerSignalHandler( const char* interfaceName + , const char* signalName + , signal_handler signalHandler + , return_slot_t ) = 0; }; /********************************************//** @@ -577,9 +606,12 @@ namespace sdbus { inline MethodInvoker IProxy::callMethod(const std::string& methodName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(methodName) == sizeof(MethodName)); - return callMethod(static_cast(methodName)); + return MethodInvoker(*this, methodName.c_str()); + } + + inline MethodInvoker IProxy::callMethod(const char* methodName) + { + return MethodInvoker(*this, methodName); } inline AsyncMethodInvoker IProxy::callMethodAsync(const MethodName& methodName) @@ -589,9 +621,12 @@ namespace sdbus { inline AsyncMethodInvoker IProxy::callMethodAsync(const std::string& methodName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(methodName) == sizeof(MethodName)); - return callMethodAsync(static_cast(methodName)); + return AsyncMethodInvoker(*this, methodName.c_str()); + } + + inline AsyncMethodInvoker IProxy::callMethodAsync(const char* methodName) + { + return AsyncMethodInvoker(*this, methodName); } inline SignalSubscriber IProxy::uponSignal(const SignalName& signalName) @@ -601,9 +636,12 @@ namespace sdbus { inline SignalSubscriber IProxy::uponSignal(const std::string& signalName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(signalName) == sizeof(SignalName)); - return uponSignal(static_cast(signalName)); + return SignalSubscriber(*this, signalName.c_str()); + } + + inline SignalSubscriber IProxy::uponSignal(const char* signalName) + { + return SignalSubscriber(*this, signalName); } inline PropertyGetter IProxy::getProperty(const PropertyName& propertyName) @@ -613,7 +651,7 @@ namespace sdbus { inline PropertyGetter IProxy::getProperty(std::string_view propertyName) { - return PropertyGetter(*this, propertyName); + return PropertyGetter(*this, std::move(propertyName)); } inline AsyncPropertyGetter IProxy::getPropertyAsync(const PropertyName& propertyName) @@ -621,11 +659,9 @@ namespace sdbus { return AsyncPropertyGetter(*this, propertyName); } - inline AsyncPropertyGetter IProxy::getPropertyAsync(const std::string& propertyName) + inline AsyncPropertyGetter IProxy::getPropertyAsync(std::string_view propertyName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(propertyName) == sizeof(PropertyName)); - return getPropertyAsync(static_cast(propertyName)); + return AsyncPropertyGetter(*this, std::move(propertyName)); } inline PropertySetter IProxy::setProperty(const PropertyName& propertyName) @@ -633,11 +669,9 @@ namespace sdbus { return PropertySetter(*this, propertyName); } - inline PropertySetter IProxy::setProperty(const std::string& propertyName) + inline PropertySetter IProxy::setProperty(std::string_view propertyName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(propertyName) == sizeof(PropertyName)); - return setProperty(static_cast(propertyName)); + return PropertySetter(*this, std::move(propertyName)); } inline AsyncPropertySetter IProxy::setPropertyAsync(const PropertyName& propertyName) @@ -645,11 +679,9 @@ namespace sdbus { return AsyncPropertySetter(*this, propertyName); } - inline AsyncPropertySetter IProxy::setPropertyAsync(const std::string& propertyName) + inline AsyncPropertySetter IProxy::setPropertyAsync(std::string_view propertyName) { - // Down-cast through static cast for performance reasons (no extra copy and object construction needed) - static_assert(sizeof(propertyName) == sizeof(PropertyName)); - return setPropertyAsync(static_cast(propertyName)); + return AsyncPropertySetter(*this, std::move(propertyName)); } inline AllPropertiesGetter IProxy::getAllProperties() diff --git a/include/sdbus-c++/StandardInterfaces.h b/include/sdbus-c++/StandardInterfaces.h index a4217d0..272a724 100644 --- a/include/sdbus-c++/StandardInterfaces.h +++ b/include/sdbus-c++/StandardInterfaces.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -39,7 +40,7 @@ namespace sdbus { // Proxy for peer class Peer_proxy { - static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.Peer"}; + static inline const char* INTERFACE_NAME = "org.freedesktop.DBus.Peer"; protected: Peer_proxy(sdbus::IProxy& proxy) @@ -78,7 +79,7 @@ namespace sdbus { // Proxy for introspection class Introspectable_proxy { - static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.Introspectable"}; + static inline const char* INTERFACE_NAME = "org.freedesktop.DBus.Introspectable"; protected: Introspectable_proxy(sdbus::IProxy& proxy) @@ -112,7 +113,7 @@ namespace sdbus { // Proxy for properties class Properties_proxy { - static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; + static inline const char* INTERFACE_NAME = "org.freedesktop.DBus.Properties"; protected: Properties_proxy(sdbus::IProxy& proxy) @@ -150,7 +151,7 @@ namespace sdbus { return proxy_->getProperty(propertyName).onInterface(interfaceName); } - sdbus::Variant Get(const InterfaceName& interfaceName, std::string_view propertyName) + sdbus::Variant Get(std::string_view interfaceName, std::string_view propertyName) { return proxy_->getProperty(propertyName).onInterface(interfaceName); } @@ -162,7 +163,7 @@ namespace sdbus { } template - PendingAsyncCall GetAsync(const InterfaceName& interfaceName, const std::string& propertyName, _Function&& callback) + PendingAsyncCall GetAsync(std::string_view interfaceName, std::string_view propertyName, _Function&& callback) { return proxy_->getPropertyAsync(propertyName).onInterface(interfaceName).uponReplyInvoke(std::forward<_Function>(callback)); } @@ -172,7 +173,7 @@ namespace sdbus { return proxy_->getPropertyAsync(propertyName).onInterface(interfaceName).getResultAsFuture(); } - std::future GetAsync(const InterfaceName& interfaceName, const std::string& propertyName, with_future_t) + std::future GetAsync(std::string_view interfaceName, std::string_view propertyName, with_future_t) { return proxy_->getPropertyAsync(propertyName).onInterface(interfaceName).getResultAsFuture(); } @@ -182,7 +183,7 @@ namespace sdbus { proxy_->setProperty(propertyName).onInterface(interfaceName).toValue(value); } - void Set(const InterfaceName& interfaceName, const std::string& propertyName, const sdbus::Variant& value) + void Set(std::string_view interfaceName, const std::string_view propertyName, const sdbus::Variant& value) { proxy_->setProperty(propertyName).onInterface(interfaceName).toValue(value); } @@ -192,7 +193,7 @@ namespace sdbus { proxy_->setProperty(propertyName).onInterface(interfaceName).toValue(value, dont_expect_reply); } - void Set(const InterfaceName& interfaceName, const std::string& propertyName, const sdbus::Variant& value, dont_expect_reply_t) + void Set(std::string_view interfaceName, const std::string_view propertyName, const sdbus::Variant& value, dont_expect_reply_t) { proxy_->setProperty(propertyName).onInterface(interfaceName).toValue(value, dont_expect_reply); } @@ -204,7 +205,7 @@ namespace sdbus { } template - PendingAsyncCall SetAsync(const InterfaceName& interfaceName, const std::string& propertyName, const sdbus::Variant& value, _Function&& callback) + PendingAsyncCall SetAsync(std::string_view interfaceName, std::string_view propertyName, const sdbus::Variant& value, _Function&& callback) { return proxy_->setPropertyAsync(propertyName).onInterface(interfaceName).toValue(value).uponReplyInvoke(std::forward<_Function>(callback)); } @@ -214,7 +215,7 @@ namespace sdbus { return proxy_->setPropertyAsync(propertyName).onInterface(interfaceName).toValue(value).getResultAsFuture(); } - std::future SetAsync(const InterfaceName& interfaceName, const std::string& propertyName, const sdbus::Variant& value, with_future_t) + std::future SetAsync(std::string_view interfaceName, std::string_view propertyName, const sdbus::Variant& value, with_future_t) { return proxy_->setPropertyAsync(propertyName).onInterface(interfaceName).toValue(value).getResultAsFuture(); } @@ -224,17 +225,33 @@ namespace sdbus { return proxy_->getAllProperties().onInterface(interfaceName); } + std::map GetAll(std::string_view interfaceName) + { + return proxy_->getAllProperties().onInterface(interfaceName); + } + template PendingAsyncCall GetAllAsync(const InterfaceName& interfaceName, _Function&& callback) { return proxy_->getAllPropertiesAsync().onInterface(interfaceName).uponReplyInvoke(std::forward<_Function>(callback)); } + template + PendingAsyncCall GetAllAsync(std::string_view interfaceName, _Function&& callback) + { + return proxy_->getAllPropertiesAsync().onInterface(interfaceName).uponReplyInvoke(std::forward<_Function>(callback)); + } + std::future> GetAllAsync(const InterfaceName& interfaceName, with_future_t) { return proxy_->getAllPropertiesAsync().onInterface(interfaceName).getResultAsFuture(); } + std::future> GetAllAsync(std::string_view interfaceName, with_future_t) + { + return proxy_->getAllPropertiesAsync().onInterface(interfaceName).getResultAsFuture(); + } + private: sdbus::IProxy* proxy_; }; @@ -242,7 +259,7 @@ namespace sdbus { // Proxy for object manager class ObjectManager_proxy { - static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.ObjectManager"}; + static inline const char* INTERFACE_NAME = "org.freedesktop.DBus.ObjectManager"; protected: ObjectManager_proxy(sdbus::IProxy& proxy) @@ -301,7 +318,7 @@ namespace sdbus { // Adaptor for properties class Properties_adaptor { - static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.Properties"}; + static inline const char* INTERFACE_NAME = "org.freedesktop.DBus.Properties"; protected: Properties_adaptor(sdbus::IObject& object) : object_(&object) @@ -325,11 +342,21 @@ namespace sdbus { object_->emitPropertiesChangedSignal(interfaceName, properties); } + void emitPropertiesChangedSignal(const char* interfaceName, const std::vector& properties) + { + object_->emitPropertiesChangedSignal(interfaceName, properties); + } + void emitPropertiesChangedSignal(const InterfaceName& interfaceName) { object_->emitPropertiesChangedSignal(interfaceName); } + void emitPropertiesChangedSignal(const char* interfaceName) + { + object_->emitPropertiesChangedSignal(interfaceName); + } + private: sdbus::IObject* object_; }; @@ -346,7 +373,7 @@ namespace sdbus { */ class ObjectManager_adaptor { - static inline const InterfaceName INTERFACE_NAME{"org.freedesktop.DBus.ObjectManager"}; + static inline const char* INTERFACE_NAME = "org.freedesktop.DBus.ObjectManager"; protected: explicit ObjectManager_adaptor(sdbus::IObject& object) : object_(&object) diff --git a/src/Connection.cpp b/src/Connection.cpp index 1353fbf..3481924 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -111,7 +111,7 @@ Connection::~Connection() void Connection::requestName(const ServiceName& name) { - SDBUS_CHECK_SERVICE_NAME(name); + SDBUS_CHECK_SERVICE_NAME(name.c_str()); auto r = sdbus_->sd_bus_request_name(bus_.get(), name.c_str(), 0); SDBUS_THROW_ERROR_IF(r < 0, "Failed to request bus name", -r); @@ -491,15 +491,23 @@ MethodCall Connection::createMethodCall( const ServiceName& destination , const ObjectPath& objectPath , const InterfaceName& interfaceName , const MethodName& methodName ) const +{ + return Connection::createMethodCall(destination.c_str(), objectPath.c_str(), interfaceName.c_str(), methodName.c_str()); +} + +MethodCall Connection::createMethodCall( const char* destination + , const char* objectPath + , const char* interfaceName + , const char* methodName ) const { sd_bus_message *sdbusMsg{}; auto r = sdbus_->sd_bus_message_new_method_call( bus_.get() , &sdbusMsg - , destination.empty() ? nullptr : destination.c_str() - , objectPath.c_str() - , interfaceName.c_str() - , methodName.c_str() ); + , !*destination ? nullptr : destination + , objectPath + , interfaceName + , methodName); SDBUS_THROW_ERROR_IF(r < 0, "Failed to create method call", -r); @@ -509,14 +517,17 @@ MethodCall Connection::createMethodCall( const ServiceName& destination Signal Connection::createSignal( const ObjectPath& objectPath , const InterfaceName& interfaceName , const SignalName& signalName ) const +{ + return Connection::createSignal(objectPath.c_str(), interfaceName.c_str(), signalName.c_str()); +} + +Signal Connection::createSignal( const char* objectPath + , const char* interfaceName + , const char* signalName ) const { sd_bus_message *sdbusMsg{}; - auto r = sdbus_->sd_bus_message_new_signal( bus_.get() - , &sdbusMsg - , objectPath.c_str() - , interfaceName.c_str() - , signalName.c_str() ); + auto r = sdbus_->sd_bus_message_new_signal(bus_.get(), &sdbusMsg, objectPath, interfaceName, signalName); SDBUS_THROW_ERROR_IF(r < 0, "Failed to create signal", -r); @@ -566,12 +577,19 @@ Slot Connection::callMethod(const MethodCall& message, void* callback, void* use void Connection::emitPropertiesChangedSignal( const ObjectPath& objectPath , const InterfaceName& interfaceName , const std::vector& propNames ) +{ + Connection::emitPropertiesChangedSignal(objectPath.c_str(), interfaceName.c_str(), propNames); +} + +void Connection::emitPropertiesChangedSignal( const char* objectPath + , const char* interfaceName + , const std::vector& propNames ) { auto names = to_strv(propNames); auto r = sdbus_->sd_bus_emit_properties_changed_strv( bus_.get() - , objectPath.c_str() - , interfaceName.c_str() + , objectPath + , interfaceName , propNames.empty() ? nullptr : &names[0] ); SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit PropertiesChanged signal", -r); @@ -615,10 +633,10 @@ void Connection::emitInterfacesRemovedSignal( const ObjectPath& objectPath SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesRemoved signal", -r); } -Slot Connection::registerSignalHandler( const ServiceName& sender - , const ObjectPath& objectPath - , const InterfaceName& interfaceName - , const SignalName& signalName +Slot Connection::registerSignalHandler( const char* sender + , const char* objectPath + , const char* interfaceName + , const char* signalName , sd_bus_message_handler_t callback , void* userData ) { @@ -626,10 +644,10 @@ Slot Connection::registerSignalHandler( const ServiceName& sender auto r = sdbus_->sd_bus_match_signal( bus_.get() , &slot - , !sender.empty() ? sender.c_str() : nullptr - , !objectPath.empty() ? objectPath.c_str() : nullptr - , !interfaceName.empty() ? interfaceName.c_str() : nullptr - , !signalName.empty() ? signalName.c_str() : nullptr + , !*sender ? nullptr : sender + , !*objectPath ? nullptr : objectPath + , !*interfaceName ? nullptr : interfaceName + , !*signalName ? nullptr : signalName , callback , userData ); diff --git a/src/Connection.h b/src/Connection.h index 1f83f31..b991772 100644 --- a/src/Connection.h +++ b/src/Connection.h @@ -130,9 +130,16 @@ namespace sdbus::internal { , const ObjectPath& objectPath , const InterfaceName& interfaceName , const MethodName& methodName ) const override; + [[nodiscard]] MethodCall createMethodCall( const char* destination + , const char* objectPath + , const char* interfaceName + , const char* methodName ) const override; [[nodiscard]] Signal createSignal( const ObjectPath& objectPath , const InterfaceName& interfaceName , const SignalName& signalName ) const override; + [[nodiscard]] Signal createSignal( const char* objectPath + , const char* interfaceName + , const char* signalName ) const override; MethodReply callMethod(const MethodCall& message, uint64_t timeout) override; void callMethod(const MethodCall& message, void* callback, void* userData, uint64_t timeout, floating_slot_t) override; @@ -141,6 +148,9 @@ namespace sdbus::internal { void emitPropertiesChangedSignal( const ObjectPath& objectPath , const InterfaceName& interfaceName , const std::vector& propNames ) override; + void emitPropertiesChangedSignal( const char* objectPath + , const char* interfaceName + , const std::vector& propNames ) override; void emitInterfacesAddedSignal(const ObjectPath& objectPath) override; void emitInterfacesAddedSignal( const ObjectPath& objectPath , const std::vector& interfaces ) override; @@ -148,10 +158,10 @@ namespace sdbus::internal { void emitInterfacesRemovedSignal( const ObjectPath& objectPath , const std::vector& interfaces ) override; - Slot registerSignalHandler( const ServiceName& sender - , const ObjectPath& objectPath - , const InterfaceName& interfaceName - , const SignalName& signalName + Slot registerSignalHandler( const char* sender + , const char* objectPath + , const char* interfaceName + , const char* signalName , sd_bus_message_handler_t callback , void* userData ) override; diff --git a/src/IConnection.h b/src/IConnection.h index dc1b189..4b3185c 100644 --- a/src/IConnection.h +++ b/src/IConnection.h @@ -77,9 +77,16 @@ namespace sdbus::internal { , const ObjectPath& objectPath , const InterfaceName& interfaceName , const MethodName& methodName ) const = 0; + [[nodiscard]] virtual MethodCall createMethodCall( const char* destination + , const char* objectPath + , const char* interfaceName + , const char* methodName ) const = 0; [[nodiscard]] virtual Signal createSignal( const ObjectPath& objectPath , const InterfaceName& interfaceName , const SignalName& signalName ) const = 0; + [[nodiscard]] virtual Signal createSignal( const char* objectPath + , const char* interfaceName + , const char* signalName ) const = 0; virtual MethodReply callMethod(const MethodCall& message, uint64_t timeout) = 0; virtual void callMethod(const MethodCall& message, void* callback, void* userData, uint64_t timeout, floating_slot_t) = 0; @@ -88,6 +95,9 @@ namespace sdbus::internal { virtual void emitPropertiesChangedSignal( const ObjectPath& objectPath , const InterfaceName& interfaceName , const std::vector& propNames ) = 0; + virtual void emitPropertiesChangedSignal( const char* objectPath + , const char* interfaceName + , const std::vector& propNames ) = 0; virtual void emitInterfacesAddedSignal(const ObjectPath& objectPath) = 0; virtual void emitInterfacesAddedSignal( const ObjectPath& objectPath , const std::vector& interfaces ) = 0; @@ -98,10 +108,10 @@ namespace sdbus::internal { using sdbus::IConnection::addObjectManager; [[nodiscard]] virtual Slot addObjectManager(const ObjectPath& objectPath, return_slot_t) = 0; - [[nodiscard]] virtual Slot registerSignalHandler( const ServiceName& sender - , const ObjectPath& objectPath - , const InterfaceName& interfaceName - , const SignalName& signalName + [[nodiscard]] virtual Slot registerSignalHandler( const char* sender + , const char* objectPath + , const char* interfaceName + , const char* signalName , sd_bus_message_handler_t callback , void* userData ) = 0; }; diff --git a/src/Object.cpp b/src/Object.cpp index fa90db7..70300c1 100644 --- a/src/Object.cpp +++ b/src/Object.cpp @@ -46,7 +46,7 @@ namespace sdbus::internal { Object::Object(sdbus::internal::IConnection& connection, ObjectPath objectPath) : connection_(connection), objectPath_(std::move(objectPath)) { - SDBUS_CHECK_OBJECT_PATH(objectPath_); + SDBUS_CHECK_OBJECT_PATH(objectPath_.c_str()); } void Object::addVTable(InterfaceName interfaceName, std::vector vtable) @@ -58,7 +58,7 @@ void Object::addVTable(InterfaceName interfaceName, std::vector vtab Slot Object::addVTable(InterfaceName interfaceName, std::vector vtable, return_slot_t) { - SDBUS_CHECK_INTERFACE_NAME(interfaceName); + SDBUS_CHECK_INTERFACE_NAME(interfaceName.c_str()); // 1st pass -- create vtable structure for internal sdbus-c++ purposes auto internalVTable = std::make_unique(createInternalVTable(std::move(interfaceName), std::move(vtable))); @@ -84,6 +84,11 @@ sdbus::Signal Object::createSignal(const InterfaceName& interfaceName, const Sig return connection_.createSignal(objectPath_, interfaceName, signalName); } +sdbus::Signal Object::createSignal(const char* interfaceName, const char* signalName) +{ + return connection_.createSignal(objectPath_.c_str(), interfaceName, signalName); +} + void Object::emitSignal(const sdbus::Signal& message) { SDBUS_THROW_ERROR_IF(!message.isValid(), "Invalid signal message provided", EINVAL); @@ -96,11 +101,21 @@ void Object::emitPropertiesChangedSignal(const InterfaceName& interfaceName, con connection_.emitPropertiesChangedSignal(objectPath_, interfaceName, propNames); } +void Object::emitPropertiesChangedSignal(const char* interfaceName, const std::vector& propNames) +{ + connection_.emitPropertiesChangedSignal(objectPath_.c_str(), interfaceName, propNames); +} + void Object::emitPropertiesChangedSignal(const InterfaceName& interfaceName) { Object::emitPropertiesChangedSignal(interfaceName, {}); } +void Object::emitPropertiesChangedSignal(const char* interfaceName) +{ + Object::emitPropertiesChangedSignal(interfaceName, {}); +} + void Object::emitInterfacesAddedSignal() { connection_.emitInterfacesAddedSignal(objectPath_); @@ -183,7 +198,7 @@ void Object::writeInterfaceFlagsToVTable(InterfaceFlagsVTableItem flags, VTable& void Object::writeMethodRecordToVTable(MethodVTableItem method, VTable& vtable) { - SDBUS_CHECK_MEMBER_NAME(method.name); + SDBUS_CHECK_MEMBER_NAME(method.name.c_str()); SDBUS_THROW_ERROR_IF(!method.callbackHandler, "Invalid method callback provided", EINVAL); vtable.methods.push_back({ std::move(method.name) @@ -196,7 +211,7 @@ void Object::writeMethodRecordToVTable(MethodVTableItem method, VTable& vtable) void Object::writeSignalRecordToVTable(SignalVTableItem signal, VTable& vtable) { - SDBUS_CHECK_MEMBER_NAME(signal.name); + SDBUS_CHECK_MEMBER_NAME(signal.name.c_str()); vtable.signals.push_back({ std::move(signal.name) , std::move(signal.signature) @@ -206,7 +221,7 @@ void Object::writeSignalRecordToVTable(SignalVTableItem signal, VTable& vtable) void Object::writePropertyRecordToVTable(PropertyVTableItem property, VTable& vtable) { - SDBUS_CHECK_MEMBER_NAME(property.name); + SDBUS_CHECK_MEMBER_NAME(property.name.c_str()); SDBUS_THROW_ERROR_IF(!property.getter && !property.setter, "Invalid property callbacks provided", EINVAL); vtable.properties.push_back({ std::move(property.name) diff --git a/src/Object.h b/src/Object.h index f69fbb4..549963d 100644 --- a/src/Object.h +++ b/src/Object.h @@ -54,9 +54,12 @@ namespace sdbus::internal { void unregister() override; sdbus::Signal createSignal(const InterfaceName& interfaceName, const SignalName& signalName) override; + sdbus::Signal createSignal(const char* interfaceName, const char* signalName) override; void emitSignal(const sdbus::Signal& message) override; void emitPropertiesChangedSignal(const InterfaceName& interfaceName, const std::vector& propNames) override; + void emitPropertiesChangedSignal(const char* interfaceName, const std::vector& propNames) override; void emitPropertiesChangedSignal(const InterfaceName& interfaceName) override; + void emitPropertiesChangedSignal(const char* interfaceName) override; void emitInterfacesAddedSignal() override; void emitInterfacesAddedSignal(const std::vector& interfaces) override; void emitInterfacesRemovedSignal() override; diff --git a/src/Proxy.cpp b/src/Proxy.cpp index a55c865..a26ea3a 100644 --- a/src/Proxy.cpp +++ b/src/Proxy.cpp @@ -36,6 +36,7 @@ #include "Utils.h" #include +#include #include SDBUS_HEADER #include @@ -46,8 +47,8 @@ Proxy::Proxy(sdbus::internal::IConnection& connection, ServiceName destination, , destination_(std::move(destination)) , objectPath_(std::move(objectPath)) { - SDBUS_CHECK_SERVICE_NAME(destination_); - SDBUS_CHECK_OBJECT_PATH(objectPath_); + SDBUS_CHECK_SERVICE_NAME(destination_.c_str()); + SDBUS_CHECK_OBJECT_PATH(objectPath_.c_str()); // The connection is not ours only, it is owned and managed by the user and we just reference // it here, so we expect the client to manage the event loop upon this connection themselves. @@ -60,8 +61,8 @@ Proxy::Proxy( std::unique_ptr&& connection , destination_(std::move(destination)) , objectPath_(std::move(objectPath)) { - SDBUS_CHECK_SERVICE_NAME(destination_); - SDBUS_CHECK_OBJECT_PATH(objectPath_); + SDBUS_CHECK_SERVICE_NAME(destination_.c_str()); + SDBUS_CHECK_OBJECT_PATH(objectPath_.c_str()); // The connection is ours only, i.e. it's us who has to manage the event loop upon this connection, // in order that we get and process signals, async call replies, and other messages from D-Bus. @@ -76,8 +77,8 @@ Proxy::Proxy( std::unique_ptr&& connection , destination_(std::move(destination)) , objectPath_(std::move(objectPath)) { - SDBUS_CHECK_SERVICE_NAME(destination_); - SDBUS_CHECK_OBJECT_PATH(objectPath_); + SDBUS_CHECK_SERVICE_NAME(destination_.c_str()); + SDBUS_CHECK_OBJECT_PATH(objectPath_.c_str()); // Even though the connection is ours only, we don't start an event loop thread. // This proxy is meant to be created, used for simple synchronous D-Bus call(s) and then dismissed. @@ -88,6 +89,11 @@ MethodCall Proxy::createMethodCall(const InterfaceName& interfaceName, const Met return connection_->createMethodCall(destination_, objectPath_, interfaceName, methodName); } +MethodCall Proxy::createMethodCall(const char* interfaceName, const char* methodName) +{ + return connection_->createMethodCall(destination_.c_str(), objectPath_.c_str(), interfaceName, methodName); +} + MethodReply Proxy::callMethod(const MethodCall& message, uint64_t timeout) { SDBUS_THROW_ERROR_IF(!message.isValid(), "Invalid method call message provided", EINVAL); @@ -137,6 +143,13 @@ std::future Proxy::callMethodAsync(const MethodCall& message, uint6 void Proxy::registerSignalHandler( const InterfaceName& interfaceName , const SignalName& signalName , signal_handler signalHandler ) +{ + Proxy::registerSignalHandler(interfaceName.c_str(), signalName.c_str(), std::move(signalHandler)); +} + +void Proxy::registerSignalHandler( const char* interfaceName + , const char* signalName + , signal_handler signalHandler ) { auto slot = Proxy::registerSignalHandler(interfaceName, signalName, std::move(signalHandler), return_slot); @@ -147,6 +160,14 @@ Slot Proxy::registerSignalHandler( const InterfaceName& interfaceName , const SignalName& signalName , signal_handler signalHandler , return_slot_t ) +{ + return Proxy::registerSignalHandler(interfaceName.c_str(), signalName.c_str(), std::move(signalHandler), return_slot); +} + +Slot Proxy::registerSignalHandler( const char* interfaceName + , const char* signalName + , signal_handler signalHandler + , return_slot_t ) { SDBUS_CHECK_INTERFACE_NAME(interfaceName); SDBUS_CHECK_MEMBER_NAME(signalName); @@ -154,8 +175,8 @@ Slot Proxy::registerSignalHandler( const InterfaceName& interfaceName auto signalInfo = std::make_unique(SignalInfo{std::move(signalHandler), *this, {}}); - signalInfo->slot = connection_->registerSignalHandler( destination_ - , objectPath_ + signalInfo->slot = connection_->registerSignalHandler( destination_.c_str() + , objectPath_.c_str() , interfaceName , signalName , &Proxy::sdbus_signal_handler diff --git a/src/Proxy.h b/src/Proxy.h index d2d606e..24906ce 100644 --- a/src/Proxy.h +++ b/src/Proxy.h @@ -57,6 +57,7 @@ namespace sdbus::internal { , dont_run_event_loop_thread_t ); MethodCall createMethodCall(const InterfaceName& interfaceName, const MethodName& methodName) override; + MethodCall createMethodCall(const char* interfaceName, const char* methodName) override; MethodReply callMethod(const MethodCall& message, uint64_t timeout) override; PendingAsyncCall callMethodAsync(const MethodCall& message, async_reply_handler asyncReplyCallback, uint64_t timeout) override; std::future callMethodAsync(const MethodCall& message, with_future_t) override; @@ -65,10 +66,17 @@ namespace sdbus::internal { void registerSignalHandler( const InterfaceName& interfaceName , const SignalName& signalName , signal_handler signalHandler ) override; + void registerSignalHandler( const char* interfaceName + , const char* signalName + , signal_handler signalHandler ) override; Slot registerSignalHandler( const InterfaceName& interfaceName , const SignalName& signalName , signal_handler signalHandler , return_slot_t ) override; + Slot registerSignalHandler( const char* interfaceName + , const char* signalName + , signal_handler signalHandler + , return_slot_t ) override; void unregister() override; [[nodiscard]] sdbus::IConnection& getConnection() const override; diff --git a/src/Utils.h b/src/Utils.h index 3c08e0b..edf1c5d 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -31,17 +31,17 @@ #include SDBUS_HEADER #if LIBSYSTEMD_VERSION>=246 -#define SDBUS_CHECK_OBJECT_PATH(_PATH) \ - SDBUS_THROW_ERROR_IF(!sd_bus_object_path_is_valid(_PATH.c_str()), "Invalid object path '" + _PATH + "' provided", EINVAL) \ +#define SDBUS_CHECK_OBJECT_PATH(_PATH) \ + SDBUS_THROW_ERROR_IF(!sd_bus_object_path_is_valid(_PATH), std::string("Invalid object path '") + _PATH + "' provided", EINVAL) \ /**/ -#define SDBUS_CHECK_INTERFACE_NAME(_NAME) \ - SDBUS_THROW_ERROR_IF(!sd_bus_interface_name_is_valid(_NAME.c_str()), "Invalid interface name '" + _NAME + "' provided", EINVAL) \ +#define SDBUS_CHECK_INTERFACE_NAME(_NAME) \ + SDBUS_THROW_ERROR_IF(!sd_bus_interface_name_is_valid(_NAME), std::string("Invalid interface name '") + _NAME + "' provided", EINVAL) \ /**/ -#define SDBUS_CHECK_SERVICE_NAME(_NAME) \ - SDBUS_THROW_ERROR_IF(!_NAME.empty() && !sd_bus_service_name_is_valid(_NAME.c_str()), "Invalid service name '" + _NAME + "' provided", EINVAL) \ +#define SDBUS_CHECK_SERVICE_NAME(_NAME) \ + SDBUS_THROW_ERROR_IF(*_NAME && !sd_bus_service_name_is_valid(_NAME), std::string("Invalid service name '") + _NAME + "' provided", EINVAL) \ /**/ -#define SDBUS_CHECK_MEMBER_NAME(_NAME) \ - SDBUS_THROW_ERROR_IF(!sd_bus_member_name_is_valid(_NAME.c_str()), std::string("Invalid member name '") + _NAME.c_str() + "' provided", EINVAL) \ +#define SDBUS_CHECK_MEMBER_NAME(_NAME) \ + SDBUS_THROW_ERROR_IF(!sd_bus_member_name_is_valid(_NAME), std::string("Invalid member name '") + _NAME + "' provided", EINVAL) \ /**/ #else #define SDBUS_CHECK_OBJECT_PATH(_PATH) diff --git a/tests/integrationtests/DBusStandardInterfacesTests.cpp b/tests/integrationtests/DBusStandardInterfacesTests.cpp index 578ba5b..d62fe75 100644 --- a/tests/integrationtests/DBusStandardInterfacesTests.cpp +++ b/tests/integrationtests/DBusStandardInterfacesTests.cpp @@ -234,10 +234,10 @@ TYPED_TEST(SdbusTestObject, GetsManagedObjectsSuccessfully) ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(2)); EXPECT_THAT(objectsInterfacesAndProperties.at(OBJECT_PATH) - .at(org::sdbuscpp::integrationtests_adaptor::INTERFACE_NAME) + .at(sdbus::InterfaceName{org::sdbuscpp::integrationtests_adaptor::INTERFACE_NAME}) .at(ACTION_PROPERTY).template get(), Eq(DEFAULT_ACTION_VALUE)); EXPECT_THAT(objectsInterfacesAndProperties.at(OBJECT_PATH_2) - .at(org::sdbuscpp::integrationtests_adaptor::INTERFACE_NAME) + .at(sdbus::InterfaceName{org::sdbuscpp::integrationtests_adaptor::INTERFACE_NAME}) .at(ACTION_PROPERTY).template get(), Eq(DEFAULT_ACTION_VALUE)); } diff --git a/tests/integrationtests/integrationtests-adaptor.h b/tests/integrationtests/integrationtests-adaptor.h index fe651a9..a34146f 100644 --- a/tests/integrationtests/integrationtests-adaptor.h +++ b/tests/integrationtests/integrationtests-adaptor.h @@ -16,7 +16,7 @@ namespace sdbuscpp { class integrationtests_adaptor { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.integrationtests"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.integrationtests"; protected: integrationtests_adaptor(sdbus::IObject& object) diff --git a/tests/integrationtests/integrationtests-proxy.h b/tests/integrationtests/integrationtests-proxy.h index edae7a5..48e91a5 100644 --- a/tests/integrationtests/integrationtests-proxy.h +++ b/tests/integrationtests/integrationtests-proxy.h @@ -16,7 +16,7 @@ namespace sdbuscpp { class integrationtests_proxy { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.integrationtests"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.integrationtests"; protected: integrationtests_proxy(sdbus::IProxy& proxy) diff --git a/tests/perftests/perftests-adaptor.h b/tests/perftests/perftests-adaptor.h index 4930117..6aefa1a 100644 --- a/tests/perftests/perftests-adaptor.h +++ b/tests/perftests/perftests-adaptor.h @@ -16,7 +16,7 @@ namespace sdbuscpp { class perftests_adaptor { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.perftests"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.perftests"; protected: perftests_adaptor(sdbus::IObject& object) diff --git a/tests/perftests/perftests-proxy.h b/tests/perftests/perftests-proxy.h index 22544ae..dee4bf9 100644 --- a/tests/perftests/perftests-proxy.h +++ b/tests/perftests/perftests-proxy.h @@ -16,7 +16,7 @@ namespace sdbuscpp { class perftests_proxy { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.perftests"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.perftests"; protected: perftests_proxy(sdbus::IProxy& proxy) diff --git a/tests/stresstests/celsius-thermometer-adaptor.h b/tests/stresstests/celsius-thermometer-adaptor.h index 6b4b030..36a32ba 100644 --- a/tests/stresstests/celsius-thermometer-adaptor.h +++ b/tests/stresstests/celsius-thermometer-adaptor.h @@ -18,7 +18,7 @@ namespace celsius { class thermometer_adaptor { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.celsius.thermometer"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.celsius.thermometer"; protected: thermometer_adaptor(sdbus::IObject& object) diff --git a/tests/stresstests/celsius-thermometer-proxy.h b/tests/stresstests/celsius-thermometer-proxy.h index 480f79a..b4a5715 100644 --- a/tests/stresstests/celsius-thermometer-proxy.h +++ b/tests/stresstests/celsius-thermometer-proxy.h @@ -18,7 +18,7 @@ namespace celsius { class thermometer_proxy { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.celsius.thermometer"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.celsius.thermometer"; protected: thermometer_proxy(sdbus::IProxy& proxy) diff --git a/tests/stresstests/concatenator-adaptor.h b/tests/stresstests/concatenator-adaptor.h index 42eae54..0bd47e7 100644 --- a/tests/stresstests/concatenator-adaptor.h +++ b/tests/stresstests/concatenator-adaptor.h @@ -17,7 +17,7 @@ namespace stresstests { class concatenator_adaptor { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.concatenator"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.concatenator"; protected: concatenator_adaptor(sdbus::IObject& object) diff --git a/tests/stresstests/concatenator-proxy.h b/tests/stresstests/concatenator-proxy.h index b5fdfef..2383dc7 100644 --- a/tests/stresstests/concatenator-proxy.h +++ b/tests/stresstests/concatenator-proxy.h @@ -17,7 +17,7 @@ namespace stresstests { class concatenator_proxy { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.concatenator"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.concatenator"; protected: concatenator_proxy(sdbus::IProxy& proxy) diff --git a/tests/stresstests/fahrenheit-thermometer-adaptor.h b/tests/stresstests/fahrenheit-thermometer-adaptor.h index 883e574..0710fbb 100644 --- a/tests/stresstests/fahrenheit-thermometer-adaptor.h +++ b/tests/stresstests/fahrenheit-thermometer-adaptor.h @@ -18,7 +18,7 @@ namespace fahrenheit { class thermometer_adaptor { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.fahrenheit.thermometer"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer"; protected: thermometer_adaptor(sdbus::IObject& object) @@ -56,7 +56,7 @@ namespace thermometer { class factory_adaptor { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.fahrenheit.thermometer.factory"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer.factory"; protected: factory_adaptor(sdbus::IObject& object) diff --git a/tests/stresstests/fahrenheit-thermometer-proxy.h b/tests/stresstests/fahrenheit-thermometer-proxy.h index d24a2b5..3a1fc26 100644 --- a/tests/stresstests/fahrenheit-thermometer-proxy.h +++ b/tests/stresstests/fahrenheit-thermometer-proxy.h @@ -18,7 +18,7 @@ namespace fahrenheit { class thermometer_proxy { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.fahrenheit.thermometer"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer"; protected: thermometer_proxy(sdbus::IProxy& proxy) @@ -60,7 +60,7 @@ namespace thermometer { class factory_proxy { public: - static inline const sdbus::InterfaceName INTERFACE_NAME{"org.sdbuscpp.stresstests.fahrenheit.thermometer.factory"}; + static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer.factory"; protected: factory_proxy(sdbus::IProxy& proxy) diff --git a/tools/xml2cpp-codegen/AdaptorGenerator.cpp b/tools/xml2cpp-codegen/AdaptorGenerator.cpp index 1ee3f0d..3c7c24c 100644 --- a/tools/xml2cpp-codegen/AdaptorGenerator.cpp +++ b/tools/xml2cpp-codegen/AdaptorGenerator.cpp @@ -82,7 +82,7 @@ std::string AdaptorGenerator::processInterface(Node& interface) const body << "class " << className << endl << "{" << endl << "public:" << endl - << tab << "static inline const sdbus::InterfaceName INTERFACE_NAME{\"" << ifaceName << "\"};" << endl << endl + << tab << "static constexpr const char* INTERFACE_NAME = \"" << ifaceName << "\";" << endl << endl << "protected:" << endl << tab << className << "(sdbus::IObject& object)" << endl << tab << tab << ": object_(&object)" << endl diff --git a/tools/xml2cpp-codegen/ProxyGenerator.cpp b/tools/xml2cpp-codegen/ProxyGenerator.cpp index f95a2fc..99225a7 100644 --- a/tools/xml2cpp-codegen/ProxyGenerator.cpp +++ b/tools/xml2cpp-codegen/ProxyGenerator.cpp @@ -81,7 +81,7 @@ std::string ProxyGenerator::processInterface(Node& interface) const body << "class " << className << endl << "{" << endl << "public:" << endl - << tab << "static inline const sdbus::InterfaceName INTERFACE_NAME{\"" << ifaceName << "\"};" << endl << endl + << tab << "static constexpr const char* INTERFACE_NAME = \"" << ifaceName << "\";" << endl << endl << "protected:" << endl << tab << className << "(sdbus::IProxy& proxy)" << endl << tab << tab << ": proxy_(&proxy)" << endl