This extends the functionality of SDBUSCPP_REGISTER_STRUCT macro.
It now provides functionality for serializing a user-defined struct as an a{sv} dictionary, and for deserializing an a{sv} dictionary into a user-defined struct. The former one is achieved by decorating the struct with sdbus::as_dictionary(struct), the latter one is an automatic behavior -- when sdbus-c++ is asked to deserialize into a struct but the data in the message is of type a{sv}, then the dict-to-struct deserialization is performed automatically.
There are some aspects of behavior in the serialization/deserialization functionality that can be customized by the client. Newly introduced SDBUSCPP_ENABLE_NESTED_STRUCT2DICT_SERIALIZATION and SDBUSCPP_ENABLE_RELAXED_DICT2STRUCT_DESERIALIZATION macros serve the purpose.
Fix inconsistencies in documentation and CMake files regarding minimum required libsystemd version (which is v238 for sdbus-c++ v2.0). Also fix compiler error bug in sdbus-c++ code when compiled against older libsystemd versions. Plus some extra related cleanups.
This introduces SDBUSCPP_REGISTER_STRUCT macro that helps clients conveniently, in one line, teach sdbus-c++ to recognize and accept their custom C++ struct types wherever D-Bus structs are expected in a D-Bus API.
The macro saves some boilerplate that would otherwise be needed on client side for every registered struct.
Make all the API consistent by using return_slot_t-based overloads for returning the slots to clients, and overloads without that tag for "floating" slots. floating_slot_t tag was previously added for API backwards compatibility reasons, but now is a (counter-)duplicate to the return_slot_t.
Moving adaptor or proxy instances changes their `this` pointer. But `this` is captured by value in closures used by those instances, and this remains unchanged on move, leading to accessing an invalid instance when a lambda expression executes. Supporting move semantics would require unsubscribing/unregistering vtable, handlers, etc. and re-subscribing and re-registering all that, which is too complicated and may have side effects. Hence it has been decided that these classes are not moveable. One may use an indirection with e.g. `std::unique_ptr` to get move semantics.
Since sdbus-c++ knows types of D-Bus call/signal/property input/output parameters at compile time, why not assemble the D-Bus signature strings at compile time, too, instead of assembling them at run time as std::string with likely cost of (unnecessary) heap allocations...
std::array is well supported constexpr type in C++20, so we harness it to build the D-Bus signature string and store it into the binary at compile time.
Having explicit conversion operator is a good practice according to the C++ core guidelines, as it makes the code safer and better follows the principle of least astonishment. Also, it is consistent with the standard library style, where wrappers like std::variant, std::any, std::optional... also do not provide an implicit conversion to the underlying type. Last but not least, it paves the way for the upcoming std::variant <-> sdbus::Variant implicit conversions without surprising behavior in some edge cases.
This introduces strong types for `std::string`-based D-Bus types. This facilitates safer, less error-prone and more expressive API.
What previously was `auto proxy = createProxy("org.sdbuscpp.concatenator", "/org/sdbuscpp/concatenator");` is now written like `auto proxy = createProxy(ServiceName{"org.sdbuscpp.concatenator"}, ObjectPath{"/org/sdbuscpp/concatenator"});`.
These types are:
* `ObjectPath` type for the object path (the type has been around already but now is also used consistently in sdbus-c++ API for object path strings),
* `InterfaceName` type for D-Bus interface names,
* `BusName` (and its aliases `ServiceName` and `ConnectionName`) type for bus/service/connection names,
* `MemberName` (and its aliases `MethodName`, `SignalName` and `PropertyName`) type for D-Bus method, signal and property names,
* `Signature` type for the D-Bus signature (the type has been around already but now is also used consistently in sdbus-c++ API for signature strings),
* `Error::Name` type for D-Bus error names.
A new CMake configuration variable SDBUSCPP_SDBUS_LIB has been introduced that enables clients to specify which sd-bus implementation library shall be used by sdbus-c++.
This PR makes things around connection factories a little more consistent and more intuitive:
* createConnection() has been removed. One shall call more expressive createSystemConnection() instead to get a connection to the system bus.
* createDefaultBusConnection() has been renamed to createBusConnection(), so as not to be confused with libsystemd's default_bus, which is a different thing (a reusable thread-local bus).
Proxies still by default call createBusConnection() to get a connection when the connection is not provided explicitly by the caller, but now createBusConnection() does a different thing, so now the proxies connect to either session bus or system bus depending on the context (as opposed to always to system bus like before).
The integration tests were modified to use createBusConnection().
This improves usability of sdbus-c++ in downstream CMake projects. CMake options now have `SDBUSCPP_` prefix so potential conflicts with downstream options/variables are minimized. Also, all configurable options and variables are placed in a single place in the root CMake file.
This switches from a raw pointer to std::optional type to pass prospective call errors to the client (using std::optional was not possible years back when sdbus-c++ was based on C++14). This makes the API a little clearer, safer, idiomatically more expressive, and removes potential confusion associated with raw pointers (like ownership, lifetime questions, etc.).
This makes D-Bus proxy signal registration more flexible, more dynamic, and less error-prone since no `finishRegistration()` call is needed. A proxy can register to a signal at any time during its lifetime, and can unregister freely by simply destroying the associated slot.
This improves the D-Bus object API registration/unregistration by making it more flexible, more dynamic, closer to sd-bus API design but still on high abstraction level, and -- most importantly -- less error-prone since no `finishRegistration()` call is needed anymore.
Signatures of callbacks async_reply_handler, signal_handler, message_handler and property_set_callback were modified to take input message objects by value, as opposed to non-const ref.
The callee assumes ownership of the message. This API is more idiomatic, more expressive, cleaner and safer. Move semantics is used to pass messages to the callback handlers. In some cases, this also improves performance.
* Catch and process all exceptions (not just sdbus::Error) from callback handlers
* Unify handling of exceptions from all types of callbacks -- always set sd_bus_error and return a negative result number in case of exception
Although libsystemd logs (with DEBUG severity) all errors from such callback handlers (except method callback handler), it seems to be out of our control. One of handy sdbus-c++ features could be the ability for clients to install a log callback, which sdbus-c++ would call in case of exceptions flying from callback handlers. In case something doesn't work for clients (especially novices), they can first look into these logs.
This may be handy in common situations like ignored signals on client side because of the inadvertent mismatch between real signal signature and signal handler signature. Like here: #373. (Although in this specific case of signals, there is a solution with an additional const sdbus::Error* argument that would reveal such an error.)
* feat: add support for direct connections
* refactor: simplify a bit, change comments, extend tests
* fix: compiler warning about unused variable
* docs: add section on direct connections to the tutorial
---------
Co-authored-by: Maksim Fedyarov <m.fedyarov@omp.ru>
Co-authored-by: Stanislav Angelovič <stanislav.angelovic@protonmail.com>
* feat: add async property get/set convenience support classes
* feat: add no-reply and async overloads to Properties_proxy
* feat: add convenience functions for GetAll functionality
* test: add tests for new functionality
* add codegen IDL support and documentation
* feat: support serialization of array, span and unordered_map
* fix some spelling mistakes
* docs: update table of valid c++ types
---------
Co-authored-by: Marcel Hellwig <github@cookiesoft.de>
* Added D-Bus type C++ type table
* docs: do corrections and rewordings in the proposed chapter
Co-authored-by: Stanislav Angelovič <stanislav.angelovic@protonmail.com>
Allow to use human readable chrono literals to specify method call
timeout. The change is backward compatbile - if no unit is provided,
the fallback is "us".
Example:
<annotation name="org.freedesktop.DBus.Method.Timeout" value="500ms"/>