This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/celix.git
commit f80ac951c27e6f323ab7c0619dd67a2b0f248d90 Author: Pepijn Noltes <[email protected]> AuthorDate: Fri Aug 16 14:31:06 2019 +0200 CELIX-464: Updates documentation to reflect udpate Celix api. --- .../getting_started/creating_a_simple_bundle.md | 110 +++++++-------------- .../getting_started/using_services_with_cxx.md | 68 +++++++------ .../services_example_cxx/bar/src/BarActivator.h | 2 +- .../services_example_cxx/baz/src/BazActivator.h | 2 +- .../services_example_cxx/foo/src/FooActivator.h | 2 +- libs/dependency_manager/TODO.md | 5 +- libs/dependency_manager_cxx/TODO.md | 7 +- 7 files changed, 75 insertions(+), 121 deletions(-) diff --git a/documents/getting_started/creating_a_simple_bundle.md b/documents/getting_started/creating_a_simple_bundle.md index 5e2b3e6..b13d9a0 100644 --- a/documents/getting_started/creating_a_simple_bundle.md +++ b/documents/getting_started/creating_a_simple_bundle.md @@ -65,7 +65,6 @@ SET(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG") #Note. If celix is not installed in /usr/local dir, change the location accordingly. set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "/usr/local/share/celix/cmake/modules") find_package(CELIX REQUIRED) -include_directories(${CELIX_INCLUDE_DIRS}) #Part 4. Choose C, C++ or both add_subdirectory(bundles/HelloWorld_c) #C @@ -96,7 +95,6 @@ Create the sub directory: cd ${WS}/myproject mkdir -p bundles/HelloWorld_c/src mkdir -p bundles/HelloWorld_cxx/src -mkdir -p bundles/HelloWorld_cxx/include ``` @@ -110,12 +108,6 @@ add_celix_bundle(HelloWorld_c SOURCES src/HelloWorld_activator.c ) - -if(APPLE) - target_link_libraries(HelloWorld_c ${CELIX_LIBRARIES} -Wl,-all_load ${CELIX_DM_STATIC_LIB}) -else() - target_link_libraries(HelloWorld_c -Wl,--no-undefined -Wl,--whole-archive ${CELIX_DM_STATIC_LIB} -Wl,--no-whole-archive ${CELIX_LIBRARIES}) -endif() ``` And/or the following CMakeLists.txt for the C++ bundle: @@ -128,97 +120,70 @@ add_celix_bundle(HelloWorld_cxx SOURCES src/HelloWorldActivator.cc ) -target_include_directories(HelloWorld_cxx PRIVATE include) - -IF(APPLE) - target_link_libraries(HelloWorld_cxx ${CELIX_LIBRARIES} -Wl,-all_load ${CELIX_DM_STATIC_CXX_LIB}) -else() - target_link_libraries(HelloWorld_cxx -Wl,--no-undefined -Wl,--whole-archive ${CELIX_DM_STATIC_CXX_LIB} -Wl,--no-whole-archive ${CELIX_LIBRARIES}) -endif() ``` -These CMakeLists.txt files declare that the bundles should be build based on the build result (shared library) of the declared sources (in this case the `private/src/hello_world_activator.c` or `private/src/HelloWorldActivator.cc` source). +These CMakeLists.txt files declare that the bundles should be build based on the build result (shared library) of the declared sources (in this case the `src/hello_world_activator.c` or `src/HelloWorldActivator.cc` source). The `add_celix_bundle` CMake function is an Apache Celix specific CMake extension. -The library used for the bundle will also be linked against the dependency manager static library. - The Celix framework will install the bundle, load the bundle shared library and call the bundle activator entry symbols. These entries need to be programmed by the user. -Note that in these examples we use the dependency manager libraries (C and C++ version) instead of developing a "vanilla" bundle activator; -The dependency manager uses a higher abstraction and is more simple to understand and maintain, but not part of the OSGi standard. +Note that in these examples we use the CELIX_GEN_BUNDLE_ACTIVATOR and CELIX_GEN_CXX_BUNDLE_ACTIVATOR +to generate the bundle activator functions (and as result the symbols needed for the Celix framework); although not necessary, this prevents the need for writing some boiler plating code. The C Bundle Activator: ```C //${WS}/myproject/bundles/hello_world/src/HelloWorld_activator.c -#include <stdlib.h> #include <stdio.h> +#include <celix_api.h> -#include "dm_activator.h" +typedef struct activator_data { + /*intentional empty*/ +} activator_data_t; -struct userData { - char * word; -}; -celix_status_t dm_create(bundle_context_pt context, void **out) { - celix_status_t status = CELIX_SUCCESS; - struct userData* result = calloc(1, sizeof(*result)); - if (result != NULL) { - result->word = "C World"; - *out = result; - } else { - status = CELIX_START_ERROR; - } - return status; -} - -celix_status_t dm_init(void* userData, bundle_context_pt context, dm_dependency_manager_pt manager) { - struct userData* data = (struct userData *) userData; - printf("Hello %s\n", data->word); +static celix_status_t activator_start(activator_data_t *data, celix_bundle_context_t *ctx) { + printf("Hello world from C bundle with id %li\n", celix_bundle_getId(celix_bundleContext_getBundle(ctx))); return CELIX_SUCCESS; } -celix_status_t dm_destroy(void* userData, bundle_context_pt context, dm_dependency_manager_pt manager) { - free(userData); +static celix_status_t activator_stop(activator_data_t *data, celix_bundle_context_t *ctx) { + printf("Goodbye world from C bundle with id %li\n", celix_bundle_getId(celix_bundleContext_getBundle(ctx))); return CELIX_SUCCESS; } + +CELIX_GEN_BUNDLE_ACTIVATOR(activator_data_t, activator_start, activator_stop) ``` -The C++ Bundle Activator (header + source): -```C++ -//${WS}/myproject/bundles/HelloWorld/include/HelloWorldActivator.h -#ifndef HELLOWORLDACTIVATOR_H_ -#define HELLOWORLDACTIVATOR_H_ - -#include "celix/dm/DmActivator.h" - -class HelloWorldActivator : public celix::dm::DmActivator { -private: - const std::string word {"C++ World"}; -public: - HelloWorldActivator(celix::dm::DependencyManager& mng) : DmActivator {mng} {} - virtual void init(); - virtual void deinit(); -}; - -#endif //HELLOWORLDACTIVATOR_H_ -``` +The C++ Bundle Activator: ```C++ //${WS}/myproject/bundles/HelloWorld/private/src/HelloWorldActivator.cc -#include "HelloWorldActivator.h" +#include <memory> #include <iostream> -DmActivator* DmActivator::create(celix::dm::DependencyManager& mng) { - return new HelloWorldActivator(mng); -} +#include <celix_api.h> -void HelloWorldActivator::init() { - std::cout << "Hello " << this->word << "\n"; -} +namespace /*anon*/ { + + class BundleActivator { + public: + BundleActivator(std::shared_ptr<celix::dm::DependencyManager> _mng) : mng{_mng} { + std::cout << "Hello world from C++ bundle with id " << bndId() << std::endl; + } + ~BundleActivator() { + std::cout << "Goodbye world from C++ bundle with id " << bndId() << std::endl; + } + private: + long bndId() const { + return celix_bundle_getId(celix_bundleContext_getBundle(mng->bundleContext())); + } + + std::shared_ptr<celix::dm::DependencyManager> mng; + }; -void HelloWorldActivator::deinit() { - //nothing to do } + +CELIX_GEN_CXX_BUNDLE_ACTIVATOR(BundleActivator) ``` ### Building @@ -252,9 +217,8 @@ To create a deployment for the hello world bundles two things are needed: add_celix_container(myproject CXX BUNDLES - ${CELIX_BUNDLES_DIR}/shell.zip - ${CELIX_BUNDLES_DIR}/shell_tui.zip - ${CELIX_BUNDLES_DIR}/dm_shell.zip + Celix::shell + Celix::shell_tui HelloWorld_c #C bundle HelloWorld_cxx #C++ bundle ) diff --git a/documents/getting_started/using_services_with_cxx.md b/documents/getting_started/using_services_with_cxx.md index 0a727b1..d4690b6 100644 --- a/documents/getting_started/using_services_with_cxx.md +++ b/documents/getting_started/using_services_with_cxx.md @@ -28,6 +28,7 @@ To start of, C++ service in Celix are just (abstract) classes. In the following example there also a projected default constructor and destructor to ensure no instantiation / deletion of the service is possible: ```C++ +//IAnotherExample.h #ifndef IANOTHER_EXAMPLE_H #define IANOTHER_EXAMPLE_H @@ -149,8 +150,8 @@ The Bar example is a simple component providing the C `example` service and C++ Note that the `Bar` component is just a plain old C++ object and does need to implement any specific Celix interfaces. -The `BarActivator` is the entry point for a C++ bundle. It must implement the `DmActivator::create` method so that C++ Dependency manager can create a instance `DmActivator` without needing to known the subclass. -It should also override the `DmActivator::init` to be able to declaratively program components and their provided service and service dependencies. +The `BarActivator` is the entry point for a C++ bundle. It must implement the bundle activator functions so that the framework can start the bundles. +It also used the C++ Dependency manager to declarative program components and their provided service and service dependencies. The C++ Dependency Manager can use C++ member function pointers to control the component lifecycle (`init`, `start`, `stop` and `deinit`) @@ -181,20 +182,19 @@ public: ```C++ //BarActivator.h -#ifndef BAR_ACTIVATOR_H +##ifndef BAR_ACTIVATOR_H #define BAR_ACTIVATOR_H -#include "celix/dm/DmActivator.h" +#include "celix/dm/DependencyManager.h" #include "example.h" using namespace celix::dm; -class BarActivator : public DmActivator { +class BarActivator { private: example_t cExample {nullptr, nullptr}; public: - BarActivator(DependencyManager& mng) : DmActivator(mng) {} - virtual void init() override; + explicit BarActivator(std::shared_ptr<DependencyManager> mng); }; #endif //BAR_ACTIVATOR_H @@ -235,17 +235,16 @@ int Bar::cMethod(int arg1, double arg2, double *out) { ```C++ //BarActivator.cc +#include <celix_api.h> + #include "Bar.h" #include "BarActivator.h" using namespace celix::dm; -DmActivator* DmActivator::create(DependencyManager& mng) { - return new BarActivator(mng); -} -void BarActivator::init() { - std::shared_ptr<Bar> bar = std::shared_ptr<Bar>{new Bar{}}; +BarActivator::BarActivator(std::shared_ptr<DependencyManager> mng) { + auto bar = std::unique_ptr<Bar>{new Bar{}}; Properties props; props["meta.info.key"] = "meta.info.value"; @@ -259,11 +258,13 @@ void BarActivator::init() { return bar->cMethod(arg1, arg2, out); }; - mng.createComponent(bar) //using a pointer a instance. Also supported is lazy initialization (default constructor needed) or a rvalue reference (move) + mng->createComponent(std::move(bar)) //using a pointer a instance. Also supported is lazy initialization (default constructor needed) or a rvalue reference (move) .addInterface<IAnotherExample>(IANOTHER_EXAMPLE_VERSION, props) .addCInterface(&this->cExample, EXAMPLE_NAME, EXAMPLE_VERSION, cProps) .setCallbacks(&Bar::init, &Bar::start, &Bar::stop, &Bar::deinit); } + +CELIX_GEN_CXX_BUNDLE_ACTIVATOR(BarActivator) ``` ### Foo Example @@ -288,6 +289,9 @@ public: Foo() = default; virtual ~Foo() = default; + Foo(const Foo&) = delete; + Foo& operator=(const Foo&) = delete; + void start(); void stop(); @@ -305,15 +309,13 @@ public: #ifndef FOO_ACTIVATOR_H #define FOO_ACTIVATOR_H -#include "celix/dm/DmActivator.h" +#include "celix/dm/DependencyManager.h" using namespace celix::dm; -class FooActivator : public DmActivator { -private: +class FooActivator { public: - FooActivator(DependencyManager& mng) : DmActivator(mng) {} - virtual void init() override; + explicit FooActivator(std::shared_ptr<DependencyManager> mng); }; #endif //FOO_ACTIVATOR_H @@ -368,16 +370,13 @@ void Foo::poll() { //FooActivator.cc #include "Foo.h" #include "FooActivator.h" +#include <celix_api.h> using namespace celix::dm; -DmActivator* DmActivator::create(DependencyManager& mng) { - return new FooActivator(mng); -} - -void FooActivator::init() { +FooActivator::FooActivator(std::shared_ptr<DependencyManager> mng) { - Component<Foo>& cmp = mng.createComponent<Foo>() + Component<Foo>& cmp = mng->createComponent<Foo>() .setCallbacks(nullptr, &Foo::start, &Foo::stop, nullptr); cmp.createServiceDependency<IAnotherExample>() @@ -390,6 +389,8 @@ void FooActivator::init() { .setVersionRange(EXAMPLE_CONSUMER_RANGE) .setCallbacks(&Foo::setExample); } + +CELIX_GEN_CXX_BUNDLE_ACTIVATOR(FooActivator) ``` ### Baz Example @@ -442,15 +443,13 @@ public: #ifndef BAZ_ACTIVATOR_H #define BAZ_ACTIVATOR_H -#include "celix/dm/DmActivator.h" +#include "celix/dm/DependencyManager.h" using namespace celix::dm; -class BazActivator : public DmActivator { -private: +class BazActivator { public: - BazActivator(DependencyManager& mng) : DmActivator(mng) {} - virtual void init() override; + explicit BazActivator(std::shared_ptr<DependencyManager> mng); }; #endif //BAZ_ACTIVATOR_H @@ -529,16 +528,13 @@ void Baz::poll() { //BazActivator.cc #include "Baz.h" #include "BazActivator.h" +#include <celix_api.h> using namespace celix::dm; -DmActivator* DmActivator::create(DependencyManager& mng) { - return new BazActivator(mng); -} - -void BazActivator::init() { +BazActivator::BazActivator(std::shared_ptr<DependencyManager> mng) { - Component<Baz>& cmp = mng.createComponent<Baz>() + Component<Baz>& cmp = mng->createComponent<Baz>() .setCallbacks(nullptr, &Baz::start, &Baz::stop, nullptr); cmp.createServiceDependency<IAnotherExample>() @@ -553,6 +549,8 @@ void BazActivator::init() { .setVersionRange(EXAMPLE_CONSUMER_RANGE) .setCallbacks(&Baz::addExample, &Baz::removeExample); } + +CELIX_GEN_CXX_BUNDLE_ACTIVATOR(BazActivator) ``` ## Locking and Suspending diff --git a/examples/celix-examples/services_example_cxx/bar/src/BarActivator.h b/examples/celix-examples/services_example_cxx/bar/src/BarActivator.h index 58e1bb8..b09ca22 100644 --- a/examples/celix-examples/services_example_cxx/bar/src/BarActivator.h +++ b/examples/celix-examples/services_example_cxx/bar/src/BarActivator.h @@ -29,7 +29,7 @@ class BarActivator { private: example_t cExample {nullptr, nullptr}; public: - BarActivator(std::shared_ptr<DependencyManager> mng); + explicit BarActivator(std::shared_ptr<DependencyManager> mng); }; diff --git a/examples/celix-examples/services_example_cxx/baz/src/BazActivator.h b/examples/celix-examples/services_example_cxx/baz/src/BazActivator.h index 445002d..ad1c371 100644 --- a/examples/celix-examples/services_example_cxx/baz/src/BazActivator.h +++ b/examples/celix-examples/services_example_cxx/baz/src/BazActivator.h @@ -26,7 +26,7 @@ using namespace celix::dm; class BazActivator { public: - BazActivator(std::shared_ptr<DependencyManager> mng); + explicit BazActivator(std::shared_ptr<DependencyManager> mng); }; #endif //BAZ_ACTIVATOR_H diff --git a/examples/celix-examples/services_example_cxx/foo/src/FooActivator.h b/examples/celix-examples/services_example_cxx/foo/src/FooActivator.h index 664a515..cb1e6b0 100644 --- a/examples/celix-examples/services_example_cxx/foo/src/FooActivator.h +++ b/examples/celix-examples/services_example_cxx/foo/src/FooActivator.h @@ -26,7 +26,7 @@ using namespace celix::dm; class FooActivator { public: - FooActivator(std::shared_ptr<DependencyManager> mng); + explicit FooActivator(std::shared_ptr<DependencyManager> mng); }; #endif //FOO_ACTIVATOR_H diff --git a/libs/dependency_manager/TODO.md b/libs/dependency_manager/TODO.md index a6ddb83..a344048 100644 --- a/libs/dependency_manager/TODO.md +++ b/libs/dependency_manager/TODO.md @@ -17,8 +17,5 @@ limitations under the License. # TODO integrate dep man into framework +- Update documentetion for CELIX_GEN_BUNDLE_ACTIVATOR usage and removal of dep manager libs / shell_dm - Move documentation -- Move dummy targets -- Deprecate the Celix::dm_shell, Celix::dependency_manager_static -and Celix::dependency_manager_so targets. (how?) -- Eventually remove the deprecated dm targets diff --git a/libs/dependency_manager_cxx/TODO.md b/libs/dependency_manager_cxx/TODO.md index 9b5eb4b..9127511 100644 --- a/libs/dependency_manager_cxx/TODO.md +++ b/libs/dependency_manager_cxx/TODO.md @@ -17,10 +17,5 @@ limitations under the License. # TODO integrate cxx dep man into framework +- Update documentetion for CELIX_GEN_CXX_BUNDLE_ACTIVATOR usage and removal of dep manager libs / shell_dm - Move documentation -- Move dummy targets -- Deprecate the Celix::dependency_manager_cxx_static target. (how?) -- Eventually remove the deprecated cxx dm target -- The bundle activator is now still a small .cc file, still resulting in -a static library which has to be linked as whole. Make this a src dependency? or some how a -header impl ? \ No newline at end of file
