This reorganizes the layers of abstraction in the sense how `Message` depends on `Connection` and vice versa. Now, `Message` has a link to the `Connection`. This replaces the shortcut link to the low-level `SdBus` interface that the `Message` kept. The interactions from `Message` now go through `Connection` which forwards them to `SdBus`. `Connection` is now a sole owner of the low-level `SdBus` interface. This allows for future changes around `SdBus` (e.g. a change from virtual functions back to non-virtual functions) without affecting the rest of the library. `Proxy`s and `Object`s can now send messages directly without having to go through `Connection`. The `Connection` no more depends on `Message` business-logic methods; it serves only as a factory for messages.
The flow for creating messages: `Proxy`/`Object` -> `Connection` -> `SdBus`
The flow for sending messages: (`Proxy`/`Object` ->) `Message` -> `Connection` -> `SdBus`
This also better reflects how dependencies are managed in the underlying sd-bus library.
Additionally, `getSdBusInterface()` methods are removed which was anyway planned, and improves the design by "Tell, don't ask" principle.
This refactoring is the necessary enabler for other upcoming improvements (regarding sending long messages, or creds refactoring, for example).
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.
In sdbus-c++ v1, new virtual functions (e.g. overloads of existing virtual functions) were always placed at the end of the class to keep backwards ABI compatibility. Now, with v2, these functions are reordered and functions forming a logical group are together.
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.
* 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
This provides access to the proxy's bus connection so code using
the proxy does not need to store an external reference to it.
A matching function is already available in IObject.