CELIX-426; Refactoring for update C bundle context api and ads some C++ examples
Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/7df4d26d Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/7df4d26d Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/7df4d26d Branch: refs/heads/feature/CELIX-426-cxx-api Commit: 7df4d26d984e3ed223ee30ff36de3a567ade45f4 Parents: 37217c2 Author: Pepijn Noltes <[email protected]> Authored: Tue May 8 21:33:51 2018 +0200 Committer: Pepijn Noltes <[email protected]> Committed: Tue May 8 21:33:51 2018 +0200 ---------------------------------------------------------------------- diff.tmp | 1166 ++++++++++++++++++ examples/celix-examples/CMakeLists.txt | 4 +- .../best_practice_example_cxx/CMakeLists.txt | 62 + .../api/IAnotherExample.h | 34 + .../best_practice_example_cxx/api/example.h | 43 + .../best_practice_example_cxx/bar/Bar.cc | 48 + .../best_practice_example_cxx/bar/Bar.h | 40 + .../bar/BarActivator.cc | 49 + .../bar/BarActivator.h | 34 + .../best_practice_example_cxx/baz/Baz.cc | 84 ++ .../best_practice_example_cxx/baz/Baz.h | 54 + .../baz/BazActivator.cc | 45 + .../baz/BazActivator.h | 31 + .../best_practice_example_cxx/foo/Foo.cc | 60 + .../best_practice_example_cxx/foo/Foo.h | 48 + .../foo/FooActivator.cc | 43 + .../foo/FooActivator.h | 32 + .../bundle_example_cxx/src/BundleActivator.cc | 9 +- .../services_example_cxx/CMakeLists.txt | 48 +- .../services_example_cxx/api/IAnotherExample.h | 34 - .../services_example_cxx/api/ICalc.h | 37 + .../services_example_cxx/api/calc.h | 43 + .../services_example_cxx/api/example.h | 43 - .../services_example_cxx/bar/CMakeLists.txt | 41 - .../bar/private/include/Bar.h | 40 - .../bar/private/include/BarActivator.h | 36 - .../services_example_cxx/bar/private/src/Bar.cc | 48 - .../bar/private/src/BarActivator.cc | 48 - .../services_example_cxx/baz/CMakeLists.txt | 41 - .../baz/private/include/Baz.h | 54 - .../baz/private/include/BazActivator.h | 34 - .../services_example_cxx/baz/private/src/Baz.cc | 84 -- .../baz/private/src/BazActivator.cc | 45 - .../services_example_cxx/foo/CMakeLists.txt | 41 - .../foo/private/include/Foo.h | 48 - .../foo/private/include/FooActivator.h | 34 - .../services_example_cxx/foo/private/src/Foo.cc | 60 - .../foo/private/src/FooActivator.cc | 43 - .../src/ConsumerBundleActivator.cc | 72 ++ .../src/ProviderBundleActivator.cc | 98 ++ framework/gtest/src/cxx_BundleContext_tests.cc | 43 +- framework/include/celix/BundleContext.h | 35 +- .../include/celix/impl/BundleContextImpl.h | 68 +- 43 files changed, 2224 insertions(+), 880 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/diff.tmp ---------------------------------------------------------------------- diff --git a/diff.tmp b/diff.tmp new file mode 100644 index 0000000..f936290 --- /dev/null +++ b/diff.tmp @@ -0,0 +1,1166 @@ +diff --git a/examples/celix-examples/CMakeLists.txt b/examples/celix-examples/CMakeLists.txt +index fd2ec1cb..bd700658 100644 +--- a/examples/celix-examples/CMakeLists.txt ++++ b/examples/celix-examples/CMakeLists.txt +@@ -23,11 +23,13 @@ endif () + if (EXAMPLES) + add_subdirectory(bundle_example_cxx) + ++ add_subdirectory(services_example_cxx) ++ + add_subdirectory(hello_world) + add_subdirectory(hello_world_test) + + add_subdirectory(services_example_c) +- add_subdirectory(services_example_cxx) ++ add_subdirectory(best_practice_example_cxx) + + add_subdirectory(dm_example) + add_subdirectory(dm_example_cxx) +diff --git a/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt b/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt +new file mode 100644 +index 00000000..faa7c002 +--- /dev/null ++++ b/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt +@@ -0,0 +1,62 @@ ++# Licensed to the Apache Software Foundation (ASF) under one ++# or more contributor license agreements. See the NOTICE file ++# distributed with this work for additional information ++# regarding copyright ownership. The ASF licenses this file ++# to you under the Apache License, Version 2.0 (the ++# "License"); you may not use this file except in compliance ++# with the License. You may obtain a copy of the License at ++# ++# http://www.apache.org/licenses/LICENSE-2.0 ++# ++# Unless required by applicable law or agreed to in writing, ++# software distributed under the License is distributed on an ++# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ++# KIND, either express or implied. See the License for the ++# specific language governing permissions and limitations ++# under the License. ++ ++add_library(cxx_services_example_api INTERFACE) ++target_include_directories(cxx_services_example_api INTERFACE api) ++ ++add_celix_bundle(cxx_foo ++ VERSION 1.0.0 ++ SOURCES ++ foo/Foo.cc ++ foo/Foo.h ++ foo/FooActivator.cc ++ foo/FooActivator.h ++ ) ++target_link_libraries(cxx_foo PRIVATE cxx_services_example_api) ++ ++add_celix_bundle(cxx_bar ++ VERSION 1.0.0 ++ SOURCES ++ bar/Bar.cc ++ bar/Bar.h ++ bar/BarActivator.cc ++ bar/BarActivator.h ++) ++target_link_libraries(cxx_bar PRIVATE cxx_services_example_api) ++ ++add_celix_bundle(cxx_baz ++ VERSION 1.0.0 ++ SOURCES ++ baz/Baz.cc ++ baz/Baz.h ++ baz/BazActivator.cc ++ baz/BazActivator.h ++) ++target_link_libraries(cxx_baz PRIVATE cxx_services_example_api) ++ ++add_celix_container(best_practice_example_cxx ++ GROUP services_example ++ COPY ++ BUNDLES ++ Celix::shell ++ Celix::shell_tui ++ cxx_bar ++ cxx_foo ++ cxx_baz ++ PROPERTIES ++ example=value ++) +diff --git a/examples/celix-examples/services_example_cxx/api/IAnotherExample.h b/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h +similarity index 87% +rename from examples/celix-examples/services_example_cxx/api/IAnotherExample.h +rename to examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h +index 0cd6c225..2ed4d6dd 100644 +--- a/examples/celix-examples/services_example_cxx/api/IAnotherExample.h ++++ b/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h +@@ -20,14 +20,14 @@ + #ifndef IANOTHER_EXAMPLE_H + #define IANOTHER_EXAMPLE_H + +-#define IANOTHER_EXAMPLE_VERSION "1.0.0" +-#define IANOTHER_EXAMPLE_CONSUMER_RANGE "[1.0.0,2.0.0)" + + class IAnotherExample { +-protected: +- IAnotherExample() = default; +- virtual ~IAnotherExample() = default; + public: ++ static constexpr const char * const VERSION = "1.0.0"; ++ static constexpr const char * const CONSUMER_RANGE = "[1.0.0,2.0.0)"; ++ ++ virtual ~IAnotherExample() = default; ++ + virtual double method(int arg1, double arg2) = 0; + }; + +diff --git a/examples/celix-examples/services_example_cxx/api/example.h b/examples/celix-examples/best_practice_example_cxx/api/example.h +similarity index 100% +rename from examples/celix-examples/services_example_cxx/api/example.h +rename to examples/celix-examples/best_practice_example_cxx/api/example.h +diff --git a/examples/celix-examples/services_example_cxx/bar/private/src/Bar.cc b/examples/celix-examples/best_practice_example_cxx/bar/Bar.cc +similarity index 100% +rename from examples/celix-examples/services_example_cxx/bar/private/src/Bar.cc +rename to examples/celix-examples/best_practice_example_cxx/bar/Bar.cc +diff --git a/examples/celix-examples/services_example_cxx/bar/private/include/Bar.h b/examples/celix-examples/best_practice_example_cxx/bar/Bar.h +similarity index 100% +rename from examples/celix-examples/services_example_cxx/bar/private/include/Bar.h +rename to examples/celix-examples/best_practice_example_cxx/bar/Bar.h +diff --git a/examples/celix-examples/services_example_cxx/bar/private/src/BarActivator.cc b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc +similarity index 83% +rename from examples/celix-examples/services_example_cxx/bar/private/src/BarActivator.cc +rename to examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc +index e4b8becd..1dc5a7e4 100644 +--- a/examples/celix-examples/services_example_cxx/bar/private/src/BarActivator.cc ++++ b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc +@@ -20,13 +20,14 @@ + #include "Bar.h" + #include "BarActivator.h" + +-using namespace celix::dm; ++#include "celix/BundleActivator.h" + +-DmActivator* DmActivator::create(DependencyManager& mng) { +- return new BarActivator(mng); ++celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) { ++ return new BarActivator{ctx}; + } + +-void BarActivator::init() { ++BarActivator::BarActivator(celix::BundleContext& ctx) { ++ auto &mng = ctx.getDependencyManager(); + auto bar = std::unique_ptr<Bar>{new Bar{}}; + + Properties props; +@@ -42,7 +43,7 @@ void BarActivator::init() { + }; + + 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) ++ .addInterface<IAnotherExample>(IAnotherExample::VERSION, props) + .addCInterface(&this->cExample, EXAMPLE_NAME, EXAMPLE_VERSION, cProps) + .setCallbacks(&Bar::init, &Bar::start, &Bar::stop, &Bar::deinit); + } +\ No newline at end of file +diff --git a/examples/celix-examples/services_example_cxx/bar/private/include/BarActivator.h b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h +similarity index 82% +rename from examples/celix-examples/services_example_cxx/bar/private/include/BarActivator.h +rename to examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h +index 0c635a83..8642c4f6 100644 +--- a/examples/celix-examples/services_example_cxx/bar/private/include/BarActivator.h ++++ b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h +@@ -20,17 +20,15 @@ + #ifndef BAR_ACTIVATOR_H + #define BAR_ACTIVATOR_H + +-#include "celix/dm/DmActivator.h" ++#include "celix/IBundleActivator.h" + #include "example.h" + +-using namespace celix::dm; +- +-class BarActivator : public DmActivator { ++class BarActivator : public celix::IBundleActivator { ++public: ++ BarActivator(celix::BundleContext &ctx); ++ virtual ~BarActivator() = default; + private: + example_t cExample {nullptr, nullptr}; +-public: +- BarActivator(DependencyManager& mng) : DmActivator(mng) {} +- virtual void init() override; + }; + + #endif //BAR_ACTIVATOR_H +diff --git a/examples/celix-examples/services_example_cxx/baz/private/src/Baz.cc b/examples/celix-examples/best_practice_example_cxx/baz/Baz.cc +similarity index 100% +rename from examples/celix-examples/services_example_cxx/baz/private/src/Baz.cc +rename to examples/celix-examples/best_practice_example_cxx/baz/Baz.cc +diff --git a/examples/celix-examples/services_example_cxx/baz/private/include/Baz.h b/examples/celix-examples/best_practice_example_cxx/baz/Baz.h +similarity index 100% +rename from examples/celix-examples/services_example_cxx/baz/private/include/Baz.h +rename to examples/celix-examples/best_practice_example_cxx/baz/Baz.h +diff --git a/examples/celix-examples/services_example_cxx/baz/private/src/BazActivator.cc b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc +similarity index 82% +rename from examples/celix-examples/services_example_cxx/baz/private/src/BazActivator.cc +rename to examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc +index 3f17b5ad..a3d3a4fa 100644 +--- a/examples/celix-examples/services_example_cxx/baz/private/src/BazActivator.cc ++++ b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc +@@ -20,21 +20,21 @@ + #include "Baz.h" + #include "BazActivator.h" + +-using namespace celix::dm; ++#include "celix/BundleActivator.h" + +-DmActivator* DmActivator::create(DependencyManager& mng) { +- return new BazActivator(mng); ++celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) { ++ return new BazActivator{ctx}; + } + +-void BazActivator::init() { +- ++BazActivator::BazActivator(celix::BundleContext& ctx) { ++ auto &mng = ctx.getDependencyManager(); + Component<Baz>& cmp = mng.createComponent<Baz>() + .setCallbacks(nullptr, &Baz::start, &Baz::stop, nullptr); + + cmp.createServiceDependency<IAnotherExample>() + .setRequired(true) + .setStrategy(DependencyUpdateStrategy::locking) +- .setVersionRange(IANOTHER_EXAMPLE_CONSUMER_RANGE) ++ .setVersionRange(IAnotherExample::CONSUMER_RANGE) + .setCallbacks(&Baz::addAnotherExample, &Baz::removeAnotherExample); + + cmp.createCServiceDependency<example_t>(EXAMPLE_NAME) +diff --git a/examples/celix-examples/services_example_cxx/baz/private/include/BazActivator.h b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h +similarity index 81% +rename from examples/celix-examples/services_example_cxx/baz/private/include/BazActivator.h +rename to examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h +index fe249184..e1a7c38a 100644 +--- a/examples/celix-examples/services_example_cxx/baz/private/include/BazActivator.h ++++ b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h +@@ -20,15 +20,12 @@ + #ifndef BAZ_ACTIVATOR_H + #define BAZ_ACTIVATOR_H + +-#include "celix/dm/DmActivator.h" ++#include "celix/IBundleActivator.h" + +-using namespace celix::dm; +- +-class BazActivator : public DmActivator { +-private: ++class BazActivator : public celix::IBundleActivator { + public: +- BazActivator(DependencyManager& mng) : DmActivator(mng) {} +- virtual void init() override; ++ BazActivator(celix::BundleContext &ctx); ++ virtual ~BazActivator() = default; + }; + + #endif //BAZ_ACTIVATOR_H +diff --git a/examples/celix-examples/services_example_cxx/foo/private/src/Foo.cc b/examples/celix-examples/best_practice_example_cxx/foo/Foo.cc +similarity index 100% +rename from examples/celix-examples/services_example_cxx/foo/private/src/Foo.cc +rename to examples/celix-examples/best_practice_example_cxx/foo/Foo.cc +diff --git a/examples/celix-examples/services_example_cxx/foo/private/include/Foo.h b/examples/celix-examples/best_practice_example_cxx/foo/Foo.h +similarity index 100% +rename from examples/celix-examples/services_example_cxx/foo/private/include/Foo.h +rename to examples/celix-examples/best_practice_example_cxx/foo/Foo.h +diff --git a/examples/celix-examples/services_example_cxx/foo/private/src/FooActivator.cc b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc +similarity index 80% +rename from examples/celix-examples/services_example_cxx/foo/private/src/FooActivator.cc +rename to examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc +index fba10cec..719da165 100644 +--- a/examples/celix-examples/services_example_cxx/foo/private/src/FooActivator.cc ++++ b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc +@@ -20,20 +20,20 @@ + #include "Foo.h" + #include "FooActivator.h" + +-using namespace celix::dm; ++#include "celix/BundleActivator.h" + +-DmActivator* DmActivator::create(DependencyManager& mng) { +- return new FooActivator(mng); ++celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) { ++ return new FooActivator{ctx}; + } + +-void FooActivator::init() { +- ++FooActivator::FooActivator(celix::BundleContext& ctx) { ++ auto &mng = ctx.getDependencyManager(); + Component<Foo>& cmp = mng.createComponent<Foo>() + .setCallbacks(nullptr, &Foo::start, &Foo::stop, nullptr); + + cmp.createServiceDependency<IAnotherExample>() + .setRequired(true) +- .setVersionRange(IANOTHER_EXAMPLE_CONSUMER_RANGE) ++ .setVersionRange(IAnotherExample::CONSUMER_RANGE) + .setCallbacks(&Foo::setAnotherExample); + + cmp.createCServiceDependency<example_t>(EXAMPLE_NAME) +diff --git a/examples/celix-examples/services_example_cxx/foo/private/include/FooActivator.h b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h +similarity index 81% +rename from examples/celix-examples/services_example_cxx/foo/private/include/FooActivator.h +rename to examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h +index 2917cbd6..a79d3659 100644 +--- a/examples/celix-examples/services_example_cxx/foo/private/include/FooActivator.h ++++ b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h +@@ -20,15 +20,13 @@ + #ifndef FOO_ACTIVATOR_H + #define FOO_ACTIVATOR_H + +-#include "celix/dm/DmActivator.h" ++#include "celix/IBundleActivator.h" + +-using namespace celix::dm; +- +-class FooActivator : public DmActivator { ++class FooActivator : public celix::IBundleActivator { + private: + public: +- FooActivator(DependencyManager& mng) : DmActivator(mng) {} +- virtual void init() override; ++ FooActivator(celix::BundleContext &ctx); ++ virtual ~FooActivator() = default; + }; + + #endif //FOO_ACTIVATOR_H +diff --git a/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc b/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc +index 5687ff0e..367d1dcb 100644 +--- a/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc ++++ b/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc +@@ -24,14 +24,15 @@ + namespace { + class BundleActivator : public celix::IBundleActivator { + public: +- BundleActivator(celix::BundleContext &_ctx) : ctx{_ctx} { +- std::cout << "Hello world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl; ++ BundleActivator(celix::BundleContext &) { ++ //std::cout << "Hello world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl; ++ std::cout << "Hello world from C++ bundle " << std::endl; + } + virtual ~BundleActivator() { +- std::cout << "Goodbye world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl; ++ //std::cout << "Goodbye world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl; + } + protected: +- celix::BundleContext &ctx; ++ //celix::BundleContext &ctx; + }; + } + +diff --git a/examples/celix-examples/services_example_cxx/CMakeLists.txt b/examples/celix-examples/services_example_cxx/CMakeLists.txt +index ba132519..fabd48f5 100644 +--- a/examples/celix-examples/services_example_cxx/CMakeLists.txt ++++ b/examples/celix-examples/services_example_cxx/CMakeLists.txt +@@ -5,39 +5,35 @@ + # to you under the Apache License, Version 2.0 (the + # "License"); you may not use this file except in compliance + # with the License. You may obtain a copy of the License at +-# ++# + # http://www.apache.org/licenses/LICENSE-2.0 +-# ++# + # Unless required by applicable law or agreed to in writing, + # software distributed under the License is distributed on an + # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + # KIND, either express or implied. See the License for the + # specific language governing permissions and limitations + # under the License. +-if (BUILD_DEPENDENCY_MANAGER_CXX) +- include_directories( +- ${PROJECT_SOURCE_DIR}/dependency_manager/public/include +- ${PROJECT_SOURCE_DIR}/dependency_manager_cxx/include +- ${PROJECT_SOURCE_DIR}/utils/public/include +- api +- ) + +- add_subdirectory(bar) +- add_subdirectory(foo) +- add_subdirectory(baz) ++add_library(services_example_api_cxx INTERFACE) ++target_include_directories(services_example_api_cxx INTERFACE api) + +- add_celix_container(services_example_cxx +- GROUP services_example +- COPY +- BUNDLES +- Celix::shell +- Celix::shell_tui +- dm_shell +- bar_cxx +- foo_cxx +- baz_cxx +- PROPERTIES +- example=value +- ) ++add_celix_bundle(provider_example_cxx ++ VERSION 1.0.0 ++ SOURCES src/ProviderBundleActivator.cc ++) ++target_link_libraries(provider_example_cxx PRIVATE services_example_api_cxx) + +-endif () ++add_celix_bundle(consumer_example_cxx ++ VERSION 1.0.0 ++ SOURCES src/ConsumerBundleActivator.cc ++) ++target_link_libraries(consumer_example_cxx PRIVATE services_example_api_cxx) ++ ++add_celix_container(services_example_cxx ++ BUNDLES ++ Celix::shell ++ Celix::shell_tui ++ provider_example_cxx ++ consumer_example_cxx ++) +\ No newline at end of file +diff --git a/examples/celix-examples/services_example_cxx/api/ICalc.h b/examples/celix-examples/services_example_cxx/api/ICalc.h +new file mode 100644 +index 00000000..4507d1ab +--- /dev/null ++++ b/examples/celix-examples/services_example_cxx/api/ICalc.h +@@ -0,0 +1,37 @@ ++/** ++ *Licensed to the Apache Software Foundation (ASF) under one ++ *or more contributor license agreements. See the NOTICE file ++ *distributed with this work for additional information ++ *regarding copyright ownership. The ASF licenses this file ++ *to you under the Apache License, Version 2.0 (the ++ *"License"); you may not use this file except in compliance ++ *with the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ *Unless required by applicable law or agreed to in writing, ++ *software distributed under the License is distributed on an ++ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ++ * KIND, either express or implied. See the License for the ++ *specific language governing permissions and limitations ++ *under the License. ++ */ ++ ++#ifndef CELIX_ICALC_H ++#define CELIX_ICALC_H ++ ++namespace example { ++class ICalc { ++ public: ++ static constexpr const char * const NAME = "example::ICalc"; ++ static constexpr const char * const VERSION = "1.0.0"; ++ static constexpr const char * const CONSUMER_RANGE = "[1.0.0,2.0.0)"; ++ ++ ++ virtual ~ICalc() = default; ++ ++ virtual double calc(double input) = 0; ++ }; ++} ++ ++#endif //CELIX_ICALC_H +diff --git a/examples/celix-examples/services_example_cxx/api/calc.h b/examples/celix-examples/services_example_cxx/api/calc.h +new file mode 100644 +index 00000000..522dd767 +--- /dev/null ++++ b/examples/celix-examples/services_example_cxx/api/calc.h +@@ -0,0 +1,43 @@ ++/** ++ *Licensed to the Apache Software Foundation (ASF) under one ++ *or more contributor license agreements. See the NOTICE file ++ *distributed with this work for additional information ++ *regarding copyright ownership. The ASF licenses this file ++ *to you under the Apache License, Version 2.0 (the ++ *"License"); you may not use this file except in compliance ++ *with the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ *Unless required by applicable law or agreed to in writing, ++ *software distributed under the License is distributed on an ++ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ++ * KIND, either express or implied. See the License for the ++ *specific language governing permissions and limitations ++ *under the License. ++ */ ++ ++#ifndef CALC_H_ ++#define CALC_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define CALC_NAME "org.example" ++#define CALC_VERSION "1.0.0" ++#define CALC_CONSUMER_RANGE "[1.0.0,2.0.0)" ++ ++ ++struct calc_struct { ++ void *handle; ++ double (*calc)(double input); ++} ; ++ ++typedef struct calc_struct calc_t; ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* CALC_H_ */ +diff --git a/examples/celix-examples/services_example_cxx/bar/CMakeLists.txt b/examples/celix-examples/services_example_cxx/bar/CMakeLists.txt +deleted file mode 100644 +index c660ce6d..00000000 +--- a/examples/celix-examples/services_example_cxx/bar/CMakeLists.txt ++++ /dev/null +@@ -1,41 +0,0 @@ +-# Licensed to the Apache Software Foundation (ASF) under one +-# or more contributor license agreements. See the NOTICE file +-# distributed with this work for additional information +-# regarding copyright ownership. The ASF licenses this file +-# to you under the Apache License, Version 2.0 (the +-# "License"); you may not use this file except in compliance +-# with the License. You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, +-# software distributed under the License is distributed on an +-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-# KIND, either express or implied. See the License for the +-# specific language governing permissions and limitations +-# under the License. +- +-include_directories( +- private/include +-) +- +-add_celix_bundle(bar_cxx +- SYMBOLIC_NAME Bar +- VERSION 1.0.0 +- SOURCES +- private/src/Bar.cc +- private/src/BarActivator.cc +-) +- +-target_compile_options(bar_cxx PUBLIC -Wall -Wextra -Weffc++ -Werror) +- +-IF(APPLE) +- target_link_libraries(bar_cxx PRIVATE -Wl,-all_load dependency_manager_cxx_static) +-else() +- if(ENABLE_ADDRESS_SANITIZER) +- #With asan there can be undefined symbols +- target_link_libraries(bar_cxx PRIVATE -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive) +- else() +- target_link_libraries(bar_cxx PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive) +- endif() +-endif() +\ No newline at end of file +diff --git a/examples/celix-examples/services_example_cxx/baz/CMakeLists.txt b/examples/celix-examples/services_example_cxx/baz/CMakeLists.txt +deleted file mode 100644 +index ce5bfd0a..00000000 +--- a/examples/celix-examples/services_example_cxx/baz/CMakeLists.txt ++++ /dev/null +@@ -1,41 +0,0 @@ +-# Licensed to the Apache Software Foundation (ASF) under one +-# or more contributor license agreements. See the NOTICE file +-# distributed with this work for additional information +-# regarding copyright ownership. The ASF licenses this file +-# to you under the Apache License, Version 2.0 (the +-# "License"); you may not use this file except in compliance +-# with the License. You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, +-# software distributed under the License is distributed on an +-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-# KIND, either express or implied. See the License for the +-# specific language governing permissions and limitations +-# under the License. +- +-include_directories( +- private/include +-) +- +-add_celix_bundle(baz_cxx +- SYMBOLIC_NAME Baz +- VERSION 1.0.0 +- SOURCES +- private/src/Baz.cc +- private/src/BazActivator.cc +-) +- +-target_compile_options(baz_cxx PUBLIC -Wall -Wextra -Weffc++ -Werror) +- +-IF(APPLE) +- target_link_libraries(baz_cxx PRIVATE -Wl,-all_load dependency_manager_cxx_static) +-else() +- if(ENABLE_ADDRESS_SANITIZER) +- #With asan there can be undefined symbols +- target_link_libraries(baz_cxx PRIVATE -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive) +- else() +- target_link_libraries(baz_cxx PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive) +- endif() +-endif() +diff --git a/examples/celix-examples/services_example_cxx/foo/CMakeLists.txt b/examples/celix-examples/services_example_cxx/foo/CMakeLists.txt +deleted file mode 100644 +index ba2aa556..00000000 +--- a/examples/celix-examples/services_example_cxx/foo/CMakeLists.txt ++++ /dev/null +@@ -1,41 +0,0 @@ +-# Licensed to the Apache Software Foundation (ASF) under one +-# or more contributor license agreements. See the NOTICE file +-# distributed with this work for additional information +-# regarding copyright ownership. The ASF licenses this file +-# to you under the Apache License, Version 2.0 (the +-# "License"); you may not use this file except in compliance +-# with the License. You may obtain a copy of the License at +-# +-# http://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, +-# software distributed under the License is distributed on an +-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-# KIND, either express or implied. See the License for the +-# specific language governing permissions and limitations +-# under the License. +- +-include_directories( +- private/include +-) +- +-add_celix_bundle(foo_cxx +- SYMBOLIC_NAME Foo +- VERSION 1.0.0 +- SOURCES +- private/src/Foo.cc +- private/src/FooActivator.cc +-) +- +-target_compile_options(foo_cxx PUBLIC -Wall -Wextra -Weffc++ -Werror) +- +-IF(APPLE) +- target_link_libraries(foo_cxx PRIVATE -Wl,-all_load dependency_manager_cxx_static) +-else() +- if(ENABLE_ADDRESS_SANITIZER) +- #With asan there can be undefined symbols +- target_link_libraries(foo_cxx PRIVATE -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive) +- else() +- target_link_libraries(foo_cxx PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_cxx_static -Wl,--no-whole-archive) +- endif() +-endif() +diff --git a/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc b/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc +new file mode 100644 +index 00000000..5ad00fed +--- /dev/null ++++ b/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc +@@ -0,0 +1,72 @@ ++/** ++ *Licensed to the Apache Software Foundation (ASF) under one ++ *or more contributor license agreements. See the NOTICE file ++ *distributed with this work for additional information ++ *regarding copyright ownership. The ASF licenses this file ++ *to you under the Apache License, Version 2.0 (the ++ *"License"); you may not use this file except in compliance ++ *with the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ *Unless required by applicable law or agreed to in writing, ++ *software distributed under the License is distributed on an ++ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ++ * KIND, either express or implied. See the License for the ++ *specific language governing permissions and limitations ++ *under the License. ++ */ ++ ++#include <iostream> ++#include <thread> ++ ++#include "celix/BundleActivator.h" ++ ++#include "ICalc.h" ++ ++namespace { ++ class BundleActivator : public celix::IBundleActivator { ++ public: ++ BundleActivator(celix::BundleContext &_ctx) : ctx{_ctx} {} ++ ++ virtual ~BundleActivator() { ++ this->useThread.join(); ++ } ++ ++ protected: ++ void use() { ++ while(this->running) { ++ int count = 0; ++ double total = 0; ++ ctx.useServices<example::ICalc>(example::ICalc::NAME, [&](example::ICalc &calc, const celix::Properties &, const celix::Bundle&) { ++ count++; ++ total += calc.calc(1); ++ }); ++ std::cout << "Called calc " << count << " times. Total is " << total << std::endl; ++ std::this_thread::sleep_for(std::chrono::seconds(5)); ++ } ++ } ++ ++ void setRunning(bool r) { ++ std::lock_guard<std::mutex> lock{this->mutex}; ++ this->running = r; ++ } ++ ++ bool isRunning() { ++ std::lock_guard<std::mutex> lock{this->mutex}; ++ return this->running; ++ } ++ ++ private: ++ celix::BundleContext &ctx; ++ std::thread useThread{[this] { this->use(); }}; ++ ++ std::mutex mutex{}; //protects running ++ bool running{true}; ++ }; ++} ++ ++celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) { ++ return new BundleActivator{ctx}; ++} ++ +diff --git a/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc b/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc +new file mode 100644 +index 00000000..fd8466e4 +--- /dev/null ++++ b/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc +@@ -0,0 +1,98 @@ ++/** ++ *Licensed to the Apache Software Foundation (ASF) under one ++ *or more contributor license agreements. See the NOTICE file ++ *distributed with this work for additional information ++ *regarding copyright ownership. The ASF licenses this file ++ *to you under the Apache License, Version 2.0 (the ++ *"License"); you may not use this file except in compliance ++ *with the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ *Unless required by applicable law or agreed to in writing, ++ *software distributed under the License is distributed on an ++ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ++ * KIND, either express or implied. See the License for the ++ *specific language governing permissions and limitations ++ *under the License. ++ */ ++ ++#include <iostream> ++#include <thread> ++#include <mutex> ++#include <vector> ++ ++#include "celix/BundleActivator.h" ++ ++#include "ICalc.h" ++ ++namespace { ++ class CalcImpl : public example::ICalc { ++ double calc(double input) override { ++ return input * 42.0; ++ } ++ }; ++ ++ class BundleActivator : public celix::IBundleActivator { ++ public: ++ BundleActivator(celix::BundleContext &ctx) { ++ /* ++ * This thread registers calc service to a max of 100, then unregistered the services and repeats. ++ */ ++ th = std::thread{[this, &ctx]{ ++ std::cout << "Starting service register thread" << std::endl; ++ CalcImpl calc{}; ++ std::vector<long> svcIds{}; ++ bool up = true; ++ while (this->isRunning()) { ++ if (up) { ++ celix::Properties props{}; ++ props[celix::Constants::SERVICE_RANKING] = "10"; //TODO random ++ long svcId = ctx.registerService(example::ICalc::NAME, &calc, example::ICalc::VERSION, std::move(props)); ++ svcIds.push_back(svcId); ++ } else { ++ if (svcIds.size() > 0) { ++ long svcId = svcIds.back(); ++ svcIds.pop_back(); ++ ctx.unregisterService(svcId); ++ } else { ++ up = true; ++ } ++ } ++ if (svcIds.size() >= 100) { ++ up = false; ++ } ++ std::this_thread::yield(); ++ } ++ std::cout << "Exiting service register thread, services count is " << svcIds.size() << std::endl; ++ std::for_each(svcIds.begin(), svcIds.end(), [&ctx](long id){ctx.unregisterService(id);}); ++ ++ }}; ++ } ++ ++ virtual ~BundleActivator() { ++ this->setRunning(false); ++ th.join(); ++ } ++ ++ void setRunning(bool r) { ++ std::lock_guard<std::mutex> lock{this->mutex}; ++ this->running = r; ++ } ++ ++ bool isRunning() { ++ std::lock_guard<std::mutex> lock{this->mutex}; ++ return this->running; ++ } ++ private: ++ std::thread th{}; ++ ++ std::mutex mutex{}; //protects running ++ bool running{true}; ++ }; ++} ++ ++celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) { ++ return new BundleActivator{ctx}; ++} ++ +diff --git a/framework/gtest/src/cxx_BundleContext_tests.cc b/framework/gtest/src/cxx_BundleContext_tests.cc +index d1a6a06a..76870110 100644 +--- a/framework/gtest/src/cxx_BundleContext_tests.cc ++++ b/framework/gtest/src/cxx_BundleContext_tests.cc +@@ -107,32 +107,35 @@ TEST_F(BundleContextTest, UseService) { + TEST_F(BundleContextTest, UseServices) { + auto &ctx = this->framework().getFrameworkContext(); + +- struct test_svc { +- int (*calc)(int input); ++ class ITestSvc { ++ public: ++ virtual ~ITestSvc(){}; ++ virtual int calc(int input) = 0; + }; +- +- test_svc svc{}; +- svc.calc = [](int input) -> int { +- return input * 42; ++ class TestImpl : public ITestSvc { ++ public: ++ virtual ~TestImpl(){}; ++ int calc(int input) override { return input * 42; } + }; ++ TestImpl svc{}; + +- long svcId1 = ctx.registerCService("test service", &svc); ++ long svcId1 = ctx.registerService<ITestSvc>("test service", &svc); + EXPECT_TRUE(svcId1 > 0); + +- long svcId2 = ctx.registerCService("test service", &svc); ++ long svcId2 = ctx.registerService<ITestSvc>("test service", &svc); + EXPECT_TRUE(svcId2 > 0); + + + int result = 0; +- std::function<void(test_svc &svc, const celix::Properties&, const celix::Bundle&)> func = [&result](test_svc &svc, const celix::Properties&, const celix::Bundle&) { ++ auto func = [&result](ITestSvc &svc, const celix::Properties&, const celix::Bundle&) { + result += svc.calc(1); + }; +- ctx.useServices("test service", "", "", func); ++ ctx.useServices<ITestSvc>("test service", func); + EXPECT_EQ(result, 84); //two times + + ctx.unregisterService(svcId1); + +- ctx.useServices("test service", "", "", func); ++ ctx.useServices<ITestSvc>("test service", func); + EXPECT_EQ(result, 126); //one time + + ctx.unregisterService(svcId2); +@@ -144,17 +147,19 @@ TEST_F(BundleContextTest, TrackService) { + + int count = 0; + +- struct test_svc { +- int (*calc)(int input); ++ class ITestSvc { ++ public: ++ virtual ~ITestSvc(){}; ++ virtual int calc(int input) = 0; + }; + +- struct test_svc *svc1 = (struct test_svc*)0x100; //no ranking +- struct test_svc *svc2 = (struct test_svc*)0x200; //no ranking +- struct test_svc *svc3 = (struct test_svc*)0x300; //10 ranking +- struct test_svc *svc4 = (struct test_svc*)0x400; //5 ranking ++ ITestSvc *svc1 = (ITestSvc*)0x100; //no ranking ++ ITestSvc *svc2 = (ITestSvc*)0x200; //no ranking ++ ITestSvc *svc3 = (ITestSvc*)0x300; //10 ranking ++ ITestSvc *svc4 = (ITestSvc*)0x400; //5 ranking + + +- auto set = [&](struct test_svc *svc, const celix::Properties &, const celix::Bundle &) { ++ auto set = [&](ITestSvc *svc, const celix::Properties &, const celix::Bundle &) { + static int callCount = 0; + callCount += 1; + if (callCount == 1) { +@@ -175,7 +180,7 @@ TEST_F(BundleContextTest, TrackService) { + long svcId2 = ctx.registerService("NA", svc2); + + //starting tracker should lead to first set call +- long trackerId = ctx.trackService<struct test_svc>("NA", "", "", set); ++ long trackerId = ctx.trackService<ITestSvc>("NA", set); + EXPECT_TRUE(trackerId > 0); + + //register svc3 should lead to second set call +diff --git a/framework/include/celix/BundleContext.h b/framework/include/celix/BundleContext.h +index b26cdd04..e6da72f1 100644 +--- a/framework/include/celix/BundleContext.h ++++ b/framework/include/celix/BundleContext.h +@@ -98,11 +98,9 @@ namespace celix { + template<typename I> + long trackService( + const std::string &serviceName, +- const std::string &versionRange, +- const std::string &filter, + std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> set + ) noexcept { +- return this->trackServiceInternal(serviceName, versionRange, filter, [set](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) { ++ return this->trackServiceInternal(serviceName, [set](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) { + I* typedSvc = static_cast<I*>(voidSvc); + set(typedSvc, props, bnd); + }); +@@ -123,12 +121,10 @@ namespace celix { + template<typename I> + long trackServices( + const std::string &serviceName, +- const std::string &versionRange, +- const std::string &filter, + std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> add, + std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> remove + ) noexcept { +- return this->trackServicesInternal(serviceName, versionRange, filter, ++ return this->trackServicesInternal(serviceName, + [add](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) { + I *typedSvc = static_cast<I *>(voidSvc); + add(typedSvc, props, bnd); +@@ -141,7 +137,8 @@ namespace celix { + } + + //TODO make add / remove service refs?? +- //TODO missing lang for track services ++ //TODO add trackService(s)WithOptions ++ //TODO add trackCService(s) variants + + /** + * Note use fucntion by const reference. Only used during the call. +@@ -150,27 +147,31 @@ namespace celix { + * @return + */ + template<typename I> +- bool useService(long serviceId, const std::string &serviceName /*sanity*/, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept { ++ bool useService(long serviceId, const std::string &/*serviceName*/ /*sanity*/, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &/*use*/) noexcept { + std::string filter = std::string{"(service.id="} + std::to_string(serviceId) + std::string{")"}; +- return this->useService<I>(serviceName, "", filter, use); ++ //TODO use useServiceWithOptions return this->useService<I>(serviceName, "", filter, use); ++ return false; + } + + template<typename I> +- bool useService(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept { +- return this->useServiceInternal(serviceName, versionRange, filter, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) { ++ bool useService(const std::string &serviceName, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept { ++ return this->useServiceInternal(serviceName, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) { + I *typedSvc = static_cast<I*>(voidSvc); + use(*typedSvc, props, svcOwner); + }); + } + + template<typename I> +- void useServices(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept { +- this->useServicesInternal(serviceName, filter, versionRange, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) { ++ void useServices(const std::string &serviceName, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept { ++ this->useServicesInternal(serviceName, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) { + I *typedSvc = static_cast<I*>(voidSvc); + use(*typedSvc, props, svcOwner); + }); + } + ++ //TODO add useService(s)WithOptions ++ //TODO add useCService(s) variants ++ + /** + * Note ordered by service rank. + */ +@@ -225,20 +226,16 @@ namespace celix { + virtual long registerServiceInternal(const std::string &serviceName, void *svc, const std::string &version, const std::string &lang, celix::Properties props) noexcept = 0; + + virtual long trackServiceInternal(const std::string &serviceName, +- const std::string &versionRange, +- const std::string &filter, + std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> set) noexcept = 0; + + virtual long trackServicesInternal( + const std::string &serviceName, +- const std::string &versionRange, +- const std::string &filter, + std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> add, + std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> remove + ) noexcept = 0; + +- virtual bool useServiceInternal(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0; +- virtual void useServicesInternal(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0; ++ virtual bool useServiceInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0; ++ virtual void useServicesInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0; + }; + + } +diff --git a/framework/include/celix/impl/BundleContextImpl.h b/framework/include/celix/impl/BundleContextImpl.h +index 80ee6622..cc2bc0e3 100644 +--- a/framework/include/celix/impl/BundleContextImpl.h ++++ b/framework/include/celix/impl/BundleContextImpl.h +@@ -71,15 +71,15 @@ namespace celix { + celix_bundleContext_unregisterService(this->c_ctx, serviceId); + } + +- std::vector<long> findServices(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::string &/*lang = ""*/) noexcept override { ++ std::vector<long> findServices(const std::string &/*serviceName*/, const std::string &/*versionRange*/, const std::string &/*filter*/, const std::string &/*lang = ""*/) noexcept override { + std::vector<long> result{}; +- auto use = [&result](void *, const celix::Properties &props, const celix::Bundle &) { +- long id = celix::getProperty(props, OSGI_FRAMEWORK_SERVICE_ID, -1); +- if (id >= 0) { +- result.push_back(id); +- } +- }; +- this->useServicesInternal(serviceName, versionRange, filter, use); ++// auto use = [&result](void *, const celix::Properties &props, const celix::Bundle &) { ++// long id = celix::getProperty(props, OSGI_FRAMEWORK_SERVICE_ID, -1); ++// if (id >= 0) { ++// result.push_back(id); ++// } ++// }; ++ //TODO useServicesWithOptions this->useServicesInternal(serviceName, versionRange, filter, use); + return result; + } + +@@ -175,10 +175,8 @@ namespace celix { + } + + long trackServiceInternal(const std::string &serviceName, +- const std::string &versionRange, +- const std::string &filter, + std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> set) noexcept override { +- celix_service_tracker_options_t opts; ++ celix_service_tracking_options_t opts; + std::memset(&opts, 0, sizeof(opts)); + + auto c_set = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) { +@@ -189,12 +187,8 @@ namespace celix { + (entry->set)(svc, props, bnd); + }; + const char *cname = serviceName.empty() ? nullptr : serviceName.c_str(); +- const char *crange = versionRange.empty() ? nullptr : versionRange.c_str(); +- const char *cfilter = filter.empty() ? nullptr : filter.c_str(); + + opts.serviceName = cname; +- opts.versionRange = crange; +- opts.filter = cfilter; + opts.lang = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE; + + auto te = std::unique_ptr<TrackEntry>{new TrackEntry{}}; +@@ -213,12 +207,10 @@ namespace celix { + + long trackServicesInternal( + const std::string &serviceName, +- const std::string &versionRange, +- const std::string &filter, + std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> add, + std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> remove + ) noexcept override { +- celix_service_tracker_options_t opts; ++ celix_service_tracking_options_t opts; + std::memset(&opts, 0, sizeof(opts)); + + auto c_add = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) { +@@ -236,13 +228,7 @@ namespace celix { + (entry->remove)(svc, props, bnd); + }; + +- const char *cname = serviceName.empty() ? nullptr : serviceName.c_str(); +- const char *crange = versionRange.empty() ? nullptr : versionRange.c_str(); +- const char *cfilter = filter.empty() ? nullptr : filter.c_str(); +- +- opts.serviceName = cname; +- opts.versionRange = crange; +- opts.filter = cfilter; ++ opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str(); + opts.lang = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE; + + auto te = std::unique_ptr<TrackEntry>{new TrackEntry{}}; +@@ -263,8 +249,6 @@ namespace celix { + + bool useServiceInternal( + const std::string &serviceName, +- const std::string &versionRange, +- const std::string &filter, + const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept override { + auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) { + auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle); +@@ -273,16 +257,20 @@ namespace celix { + celix::impl::BundleImpl bnd{m_bnd}; + (*fn)(svc, props, bnd); + }; +- const char *cname = serviceName.empty() ? nullptr : serviceName.c_str(); +- const char *crange = versionRange.empty() ? nullptr : versionRange.c_str(); +- const char *cfilter = filter.empty() ? nullptr : filter.c_str(); +- return celix_bundleContext_useService(this->c_ctx, cname, crange, cfilter, (void*)(&use), c_use); ++ ++ celix_service_use_options_t opts; ++ std::memset(&opts, 0, sizeof(opts)); ++ ++ opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();; ++ opts.lang = celix::Constants::SERVICE_CXX_LANG; ++ opts.callbackHandle = (void*)&use; ++ opts.use = c_use; ++ ++ return celix_bundleContext_useServiceWithOptions(this->c_ctx, &opts); + } + + void useServicesInternal( + const std::string &serviceName, +- const std::string &versionRange, +- const std::string &filter, + const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept override { + auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) { + auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle); +@@ -291,10 +279,16 @@ namespace celix { + celix::impl::BundleImpl bnd{m_bnd}; + (*fn)(svc, props, bnd); + }; +- const char *cname = serviceName.empty() ? nullptr : serviceName.c_str(); +- const char *crange = versionRange.empty() ? nullptr : versionRange.c_str(); +- const char *cfilter = filter.empty() ? nullptr : filter.c_str(); +- celix_bundleContext_useServices(this->c_ctx, cname, crange, cfilter, (void*)(&use), c_use); ++ ++ celix_service_use_options_t opts; ++ std::memset(&opts, 0, sizeof(opts)); ++ ++ opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();; ++ opts.lang = celix::Constants::SERVICE_CXX_LANG; ++ opts.callbackHandle = (void*)&use; ++ opts.use = c_use; ++ ++ celix_bundleContext_useServicesWithOptions(this->c_ctx, &opts); + } + + private: http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/CMakeLists.txt b/examples/celix-examples/CMakeLists.txt index fd2ec1c..bd70065 100644 --- a/examples/celix-examples/CMakeLists.txt +++ b/examples/celix-examples/CMakeLists.txt @@ -23,11 +23,13 @@ endif () if (EXAMPLES) add_subdirectory(bundle_example_cxx) + add_subdirectory(services_example_cxx) + add_subdirectory(hello_world) add_subdirectory(hello_world_test) add_subdirectory(services_example_c) - add_subdirectory(services_example_cxx) + add_subdirectory(best_practice_example_cxx) add_subdirectory(dm_example) add_subdirectory(dm_example_cxx) http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt b/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt new file mode 100644 index 0000000..faa7c00 --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/CMakeLists.txt @@ -0,0 +1,62 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +add_library(cxx_services_example_api INTERFACE) +target_include_directories(cxx_services_example_api INTERFACE api) + +add_celix_bundle(cxx_foo + VERSION 1.0.0 + SOURCES + foo/Foo.cc + foo/Foo.h + foo/FooActivator.cc + foo/FooActivator.h + ) +target_link_libraries(cxx_foo PRIVATE cxx_services_example_api) + +add_celix_bundle(cxx_bar + VERSION 1.0.0 + SOURCES + bar/Bar.cc + bar/Bar.h + bar/BarActivator.cc + bar/BarActivator.h +) +target_link_libraries(cxx_bar PRIVATE cxx_services_example_api) + +add_celix_bundle(cxx_baz + VERSION 1.0.0 + SOURCES + baz/Baz.cc + baz/Baz.h + baz/BazActivator.cc + baz/BazActivator.h +) +target_link_libraries(cxx_baz PRIVATE cxx_services_example_api) + +add_celix_container(best_practice_example_cxx + GROUP services_example + COPY + BUNDLES + Celix::shell + Celix::shell_tui + cxx_bar + cxx_foo + cxx_baz + PROPERTIES + example=value +) http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h b/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h new file mode 100644 index 0000000..2ed4d6d --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/api/IAnotherExample.h @@ -0,0 +1,34 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef IANOTHER_EXAMPLE_H +#define IANOTHER_EXAMPLE_H + + +class IAnotherExample { +public: + static constexpr const char * const VERSION = "1.0.0"; + static constexpr const char * const CONSUMER_RANGE = "[1.0.0,2.0.0)"; + + virtual ~IAnotherExample() = default; + + virtual double method(int arg1, double arg2) = 0; +}; + +#endif //IANOTHER_EXAMPLE_H http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/api/example.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/api/example.h b/examples/celix-examples/best_practice_example_cxx/api/example.h new file mode 100644 index 0000000..68ce0e3 --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/api/example.h @@ -0,0 +1,43 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#ifndef EXAMPLE_H_ +#define EXAMPLE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define EXAMPLE_NAME "org.example" +#define EXAMPLE_VERSION "1.0.0" +#define EXAMPLE_CONSUMER_RANGE "[1.0.0,2.0.0)" + + +struct example_struct { + void *handle; + int (*method)(void *handle, int arg1, double arg2, double *result); +} ; + +typedef struct example_struct example_t; + +#ifdef __cplusplus +} +#endif + +#endif /* EXAMPLE_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/bar/Bar.cc ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/bar/Bar.cc b/examples/celix-examples/best_practice_example_cxx/bar/Bar.cc new file mode 100644 index 0000000..7490005 --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/bar/Bar.cc @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "Bar.h" +#include <iostream> + +void Bar::init() { + std::cout << "init Bar\n"; +} + +void Bar::start() { + std::cout << "start Bar\n"; +} + +void Bar::stop() { + std::cout << "stop Bar\n"; +} + +void Bar::deinit() { + std::cout << "deinit Bar\n"; +} + +double Bar::method(int arg1, double arg2) { + double update = (this->seed + arg1) * arg2; + return update; +} + +int Bar::cMethod(int arg1, double arg2, double *out) { + double r = this->method(arg1, arg2); + *out = r; + return 0; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/bar/Bar.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/bar/Bar.h b/examples/celix-examples/best_practice_example_cxx/bar/Bar.h new file mode 100644 index 0000000..799f8a9 --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/bar/Bar.h @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef BAR_H +#define BAR_H + +#include "IAnotherExample.h" + +class Bar : public IAnotherExample { + const double seed = 42; +public: + Bar() = default; + virtual ~Bar() = default; + + void init(); + void start(); + void stop(); + void deinit(); + + virtual double method(int arg1, double arg2) override; //implementation of IAnotherExample::method + int cMethod(int arg1, double arg2, double *out); //implementation of example_t->method; +}; + +#endif //BAR_H http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc new file mode 100644 index 0000000..1dc5a7e --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.cc @@ -0,0 +1,49 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "Bar.h" +#include "BarActivator.h" + +#include "celix/BundleActivator.h" + +celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) { + return new BarActivator{ctx}; +} + +BarActivator::BarActivator(celix::BundleContext& ctx) { + auto &mng = ctx.getDependencyManager(); + auto bar = std::unique_ptr<Bar>{new Bar{}}; + + Properties props; + props["meta.info.key"] = "meta.info.value"; + + Properties cProps; + cProps["also.meta.info.key"] = "also.meta.info.value"; + + this->cExample.handle = bar.get(); + this->cExample.method = [](void *handle, int arg1, double arg2, double *out) { + Bar* bar = static_cast<Bar*>(handle); + return bar->cMethod(arg1, arg2, out); + }; + + 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>(IAnotherExample::VERSION, props) + .addCInterface(&this->cExample, EXAMPLE_NAME, EXAMPLE_VERSION, cProps) + .setCallbacks(&Bar::init, &Bar::start, &Bar::stop, &Bar::deinit); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h new file mode 100644 index 0000000..8642c4f --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/bar/BarActivator.h @@ -0,0 +1,34 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef BAR_ACTIVATOR_H +#define BAR_ACTIVATOR_H + +#include "celix/IBundleActivator.h" +#include "example.h" + +class BarActivator : public celix::IBundleActivator { +public: + BarActivator(celix::BundleContext &ctx); + virtual ~BarActivator() = default; +private: + example_t cExample {nullptr, nullptr}; +}; + +#endif //BAR_ACTIVATOR_H http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/baz/Baz.cc ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/baz/Baz.cc b/examples/celix-examples/best_practice_example_cxx/baz/Baz.cc new file mode 100644 index 0000000..bf258fb --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/baz/Baz.cc @@ -0,0 +1,84 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "Baz.h" +#include <iostream> + +void Baz::start() { + std::cout << "start Baz\n"; + this->running = true; + pollThread = std::thread {&Baz::poll, this}; +} + +void Baz::stop() { + std::cout << "stop Baz\n"; + this->running = false; + this->pollThread.join(); +} + +void Baz::addAnotherExample(IAnotherExample *e) { + std::lock_guard<std::mutex> lock(this->lock_for_examples); + this->examples.push_back(e); +} + +void Baz::removeAnotherExample(IAnotherExample *e) { + std::lock_guard<std::mutex> lock(this->lock_for_examples); + this->examples.remove(e); +} + +void Baz::addExample(const example_t *e) { + std::lock_guard<std::mutex> lock(this->lock_for_cExamples); + this->cExamples.push_back(e); +} + +void Baz::removeExample(const example_t *e) { + std::lock_guard<std::mutex> lock(this->lock_for_cExamples); + this->cExamples.remove(e); +} + +void Baz::poll() { + double r1 = 1.0; + double r2 = 1.0; + while (this->running) { + //c++ service required -> if component started always available + + { + std::lock_guard<std::mutex> lock(this->lock_for_examples); + int index = 0; + for (IAnotherExample *e : this->examples) { + r1 = e->method(3, r1); + std::cout << "Result IAnotherExample " << index++ << " is " << r1 << "\n"; + } + } + + + { + std::lock_guard<std::mutex> lock(this->lock_for_cExamples); + int index = 0; + for (const example_t *e : this->cExamples) { + double out; + e->method(e->handle, 4, r2, &out); + r2 = out; + std::cout << "Result example_t " << index++ << " is " << r2 << "\n"; + } + } + + std::this_thread::sleep_for(std::chrono::milliseconds(4000)); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/baz/Baz.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/baz/Baz.h b/examples/celix-examples/best_practice_example_cxx/baz/Baz.h new file mode 100644 index 0000000..d881627 --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/baz/Baz.h @@ -0,0 +1,54 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef BAZ_H +#define BAZ_H + +#include "example.h" +#include "IAnotherExample.h" +#include <thread> +#include <list> +#include <mutex> + +class Baz { + std::list<IAnotherExample*> examples {}; + std::mutex lock_for_examples {}; + + std::list<const example_t*> cExamples {}; + std::mutex lock_for_cExamples {}; + + std::thread pollThread {}; + bool running = false; +public: + Baz() = default; + virtual ~Baz() = default; + + void start(); + void stop(); + + void addAnotherExample(IAnotherExample* e); + void removeAnotherExample(IAnotherExample* e); + + void addExample(const example_t* e); + void removeExample(const example_t* e); + + void poll(); +}; + +#endif //BAZ_H http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc new file mode 100644 index 0000000..a3d3a4f --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.cc @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "Baz.h" +#include "BazActivator.h" + +#include "celix/BundleActivator.h" + +celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) { + return new BazActivator{ctx}; +} + +BazActivator::BazActivator(celix::BundleContext& ctx) { + auto &mng = ctx.getDependencyManager(); + Component<Baz>& cmp = mng.createComponent<Baz>() + .setCallbacks(nullptr, &Baz::start, &Baz::stop, nullptr); + + cmp.createServiceDependency<IAnotherExample>() + .setRequired(true) + .setStrategy(DependencyUpdateStrategy::locking) + .setVersionRange(IAnotherExample::CONSUMER_RANGE) + .setCallbacks(&Baz::addAnotherExample, &Baz::removeAnotherExample); + + cmp.createCServiceDependency<example_t>(EXAMPLE_NAME) + .setRequired(false) + .setStrategy(DependencyUpdateStrategy::locking) + .setVersionRange(EXAMPLE_CONSUMER_RANGE) + .setCallbacks(&Baz::addExample, &Baz::removeExample); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h new file mode 100644 index 0000000..e1a7c38 --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/baz/BazActivator.h @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef BAZ_ACTIVATOR_H +#define BAZ_ACTIVATOR_H + +#include "celix/IBundleActivator.h" + +class BazActivator : public celix::IBundleActivator { +public: + BazActivator(celix::BundleContext &ctx); + virtual ~BazActivator() = default; +}; + +#endif //BAZ_ACTIVATOR_H http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/foo/Foo.cc ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/foo/Foo.cc b/examples/celix-examples/best_practice_example_cxx/foo/Foo.cc new file mode 100644 index 0000000..241513c --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/foo/Foo.cc @@ -0,0 +1,60 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "Foo.h" +#include <iostream> + +void Foo::start() { + std::cout << "start Foo\n"; + this->running = true; + pollThread = std::thread {&Foo::poll, this}; +} + +void Foo::stop() { + std::cout << "stop Foo\n"; + this->running = false; + this->pollThread.join(); +} + +void Foo::setAnotherExample(IAnotherExample *e) { + this->example = e; +} + +void Foo::setExample(const example_t *e) { + this->cExample = e; +} + +void Foo::poll() { + double r1 = 1.0; + double r2 = 1.0; + while (this->running) { + //c++ service required -> if component started always available + r1 = this->example->method(3, r1); + std::cout << "Result IAnotherExample is " << r1 << "\n"; + + //c service is optional, can be nullptr + if (this->cExample != nullptr) { + double out; + this->cExample->method(this->cExample->handle, 4, r2, &out); + r2 = out; + std::cout << "Result example_t is " << r2 << "\n"; + } + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/foo/Foo.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/foo/Foo.h b/examples/celix-examples/best_practice_example_cxx/foo/Foo.h new file mode 100644 index 0000000..0035b77 --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/foo/Foo.h @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef FOO_H +#define FOO_H + +#include "example.h" +#include "IAnotherExample.h" +#include <thread> + +class Foo { + IAnotherExample* example {nullptr}; + const example_t* cExample {nullptr}; + std::thread pollThread {}; + bool running = false; +public: + Foo() = default; + virtual ~Foo() = default; + + Foo(const Foo&) = delete; + Foo& operator=(const Foo&) = delete; + + void start(); + void stop(); + + void setAnotherExample(IAnotherExample* e); + void setExample(const example_t* e); + + void poll(); +}; + +#endif //FOO_H http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc new file mode 100644 index 0000000..719da16 --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.cc @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "Foo.h" +#include "FooActivator.h" + +#include "celix/BundleActivator.h" + +celix::IBundleActivator* celix::createBundleActivator(celix::BundleContext &ctx) { + return new FooActivator{ctx}; +} + +FooActivator::FooActivator(celix::BundleContext& ctx) { + auto &mng = ctx.getDependencyManager(); + Component<Foo>& cmp = mng.createComponent<Foo>() + .setCallbacks(nullptr, &Foo::start, &Foo::stop, nullptr); + + cmp.createServiceDependency<IAnotherExample>() + .setRequired(true) + .setVersionRange(IAnotherExample::CONSUMER_RANGE) + .setCallbacks(&Foo::setAnotherExample); + + cmp.createCServiceDependency<example_t>(EXAMPLE_NAME) + .setRequired(false) + .setVersionRange(EXAMPLE_CONSUMER_RANGE) + .setCallbacks(&Foo::setExample); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h ---------------------------------------------------------------------- diff --git a/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h new file mode 100644 index 0000000..a79d365 --- /dev/null +++ b/examples/celix-examples/best_practice_example_cxx/foo/FooActivator.h @@ -0,0 +1,32 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef FOO_ACTIVATOR_H +#define FOO_ACTIVATOR_H + +#include "celix/IBundleActivator.h" + +class FooActivator : public celix::IBundleActivator { +private: +public: + FooActivator(celix::BundleContext &ctx); + virtual ~FooActivator() = default; +}; + +#endif //FOO_ACTIVATOR_H http://git-wip-us.apache.org/repos/asf/celix/blob/7df4d26d/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc ---------------------------------------------------------------------- diff --git a/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc b/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc index 5687ff0..367d1dc 100644 --- a/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc +++ b/examples/celix-examples/bundle_example_cxx/src/BundleActivator.cc @@ -24,14 +24,15 @@ namespace { class BundleActivator : public celix::IBundleActivator { public: - BundleActivator(celix::BundleContext &_ctx) : ctx{_ctx} { - std::cout << "Hello world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl; + BundleActivator(celix::BundleContext &) { + //std::cout << "Hello world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl; + std::cout << "Hello world from C++ bundle " << std::endl; } virtual ~BundleActivator() { - std::cout << "Goodbye world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl; + //std::cout << "Goodbye world from C++ bundle with id " << ctx.getBundle().getBundleId() << std::endl; } protected: - celix::BundleContext &ctx; + //celix::BundleContext &ctx; }; }
