Hi All, A while ago I created a proposal for a v3 Celix API. Since a few week I have started working on some of the the changes, but adjusted them to keep close to the OSGI api/nomenclature. In this thread I would like to explain the changes I made and hope to start a discussion to see if these change are in line with that we want as a Celix community.
The API changes are added in new headers so that a) they can coexist with the current API and b) the headers are not cluttered with two different styles of API. The basis premise is that most of the updated API is centred around the bundle context. The bundle context is (from the OSGI spec) a object that represents the execution context of a single bundle within the OSGi framework, and acts as a proxy to the underlying Framework. And as such should IMO be the primary entry to interact with everything the Celix framework is offering. This for example means that now both register and unregistering service is done through the bundle context, also that setting up and stopping a service tracker is done though the bundle context, etc. Some of the more important changes are: - All the updated APIs are location in the celix_ prefixed headers. - All public functions in the update API are prefixed with celix_. This is of course to prevent symbol collisions. - Explicit locking is prevented by calling useService(s) functions, which accepts user provided callbacks so that the framework can take care of locking/race-conditions during the invocation of the callbacks. Locking is really necessary in Celix to ensure that services cannot be freed/unloaded if that service is still in use. On the other hand exposing explicit lock functions or lock types are ugly, cumbersome and error prone. The updated bundle context API now has useService(s) calls which lets the users provide a callback. In the callback the framework ensure the locking and the user can safely use the service - and other arguments - during the callback. - More focus on const correctness, specifically in the tracker/use callbacks. - Simpler error reporting. Although always returning a int stating if a error occurred is very clear, it does make the code more verbose and (IMO) unnatural to read. In most cases the returning type can easily be used to indicate an error. This is now more often used. - Less use of pointers. E.g. registering a service now returns a service id (or <0 if error) instead of a service_registration_t pointer and setting up a service tracker now return a tracker id (long). This prevents dangling pointers and reduces the public api. - Most of the bundle context calls now have a simple call (e.g. celix_bundleContext_registerService) with a few arguments and a more complex call which accepts a pointer to a options struct (e.g. celix_bundleContext_registerServiceWithOptions). This ensure that the basic use can be left simple and also ensure that more complex setup are still readable. For example something like: celix_bundleContext_registerServiceComplex(ctx, "service name", NULL, NULL, props, NULL, "1.2.0"); Can be written as: celix_service_registrations_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; opts.serviceName = "servicename"; opts.properties = props; opts.serviceLanguage = lang; celix_bundleContext_registerServiceWithOptions(ctx, &opts); More verbose, but also more readable. With the additional benefit that these options struct can be extended in a (source level) backwards manner. - Although not a change, but IMO a benefit: Documenting the bundle context API should help a lot in making the Celix framework more easier to understand and get started with Celix. For the code and updated examples see: - celix_bundle_context.h https://github.com/apache/celix/blob/3e27acf533a195132934a3a5d6935c95f47c7ea9/libs/framework/include/celix_bundle_context.h - C bundle example https://github.com/apache/celix/tree/3e27acf533a195132934a3a5d6935c95f47c7ea9/examples/celix-examples/bundle_example_c - C services example https://github.com/apache/celix/tree/3e27acf533a195132934a3a5d6935c95f47c7ea9/examples/celix-examples/services_example_c Some work is also already done for a C++ api. This is currently a fully header based implementation, meaning that the installed celix libraries can be kept pure C, but user can choose to create bundles in C++. Note that there are still a lot of TODO and the API is not stable. For more info see: - C++ BundleContext https://github.com/apache/celix/blob/be6612f0f259cf080fe5ca1f6fbbfa9bb61a502c/libs/framework/include/celix/BundleContext.h - C++ bundle example https://github.com/apache/celix/tree/be6612f0f259cf080fe5ca1f6fbbfa9bb61a502c/examples/celix-examples/bundle_example_cxx - C++ services example https://github.com/apache/celix/tree/be6612f0f259cf080fe5ca1f6fbbfa9bb61a502c/examples/celix-examples/services_example_cxx All in all my hope it that this simplifies to usage of Celix, but at the same time ensure that we can still support the "old" API for the foreseeable future. Any though, comments or no-dont-do-this remarks are welcome. Greetings, Pepijn
