You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2019/07/23 20:08:48 UTC
[celix] 02/02: CELIX-370: Update ServiceDependency implementation
This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/cxx
in repository https://gitbox.apache.org/repos/asf/celix.git
commit 41cb4b5be5239d11d57e0af68ea760d7bd328c93
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Tue Jul 23 22:08:17 2019 +0200
CELIX-370: Update ServiceDependency implementation
---
.../gtest/src/ComponentManager_tests.cc | 9 +-
.../framework_cxx/include/celix/ComponentManager.h | 207 ++++++++++++++-------
libs/framework_cxx/src/ComponentManager.cc | 31 ++-
libs/registry/include/celix/ServiceRegistry.h | 2 +-
4 files changed, 169 insertions(+), 80 deletions(-)
diff --git a/libs/framework_cxx/gtest/src/ComponentManager_tests.cc b/libs/framework_cxx/gtest/src/ComponentManager_tests.cc
index f9a42ad..77dc8de 100644
--- a/libs/framework_cxx/gtest/src/ComponentManager_tests.cc
+++ b/libs/framework_cxx/gtest/src/ComponentManager_tests.cc
@@ -53,9 +53,16 @@ TEST_F(ComponentManagerTest, AddSvcDep) {
class ISvc {};
celix::ComponentManager<Cmp> cmpMng{ctx, std::make_shared<Cmp>()};
- cmpMng.addServiceDependency(); //TODO
+ cmpMng.addServiceDependency<ISvc>()
+ .setRequired(true);
cmpMng.enable();
EXPECT_TRUE(cmpMng.isEnabled());
+ //dep not available -> cmp manager not resolved
+ EXPECT_FALSE(cmpMng.isResolved());
+
+ auto svcReg = ctx->registerService(std::make_shared<ISvc>());
+ //dep available -> cmp manager resolved
+ EXPECT_TRUE(cmpMng.isResolved());
}
\ No newline at end of file
diff --git a/libs/framework_cxx/include/celix/ComponentManager.h b/libs/framework_cxx/include/celix/ComponentManager.h
index 431b784..bfbd971 100644
--- a/libs/framework_cxx/include/celix/ComponentManager.h
+++ b/libs/framework_cxx/include/celix/ComponentManager.h
@@ -49,13 +49,15 @@ namespace celix {
//TODO make friend of SvcDep
void updateState();
protected:
- GenericComponentManager(std::shared_ptr<BundleContext> _ctx, std::shared_ptr<void> cmpInstance) : ctx{std::move(_ctx)}, instance{std::move(cmpInstance)} {};
+ GenericComponentManager(std::shared_ptr<BundleContext> _ctx) : ctx{std::move(_ctx)} {};
void removeServiceDependency(long serviceDependencyId);
void setEnabled(bool enable);
/**** Fields ****/
+ std::shared_ptr<BundleContext> ctx;
+
mutable std::mutex mutex{}; //protects below
ComponentState state = ComponentState::Disabled;
bool enabled = false;
@@ -64,11 +66,8 @@ namespace celix {
std::function<void()> stop{};
std::function<void()> deinit{};
- std::shared_ptr<BundleContext> ctx;
- std::shared_ptr<void> instance;
-
long nextServiceDependencyId = 1L;
- std::unordered_map<long,GenericServiceDependency> serviceDependencies{};
+ std::unordered_map<long,std::unique_ptr<GenericServiceDependency>> serviceDependencies{};
};
template<typename T>
@@ -82,17 +81,21 @@ namespace celix {
ComponentManager<T>& enable();
ComponentManager<T>& disable();
+ std::shared_ptr<T> instance();
+
ComponentManager<T>& setCallbacks(
void (T::*init)(),
void (T::*start)(),
void (T::*stop)(),
void (T::*deinit)());
-// template<typename I>
-// ServiceDependency<T,I>& addServiceDependency();
+ template<typename I>
+ ServiceDependency<T,I>& addServiceDependency();
//
// template<typename F>
// ServiceDependency<T,F>& addFunctionServiceDependency(const std::string &functionName);
+ private:
+ std::shared_ptr<T> inst;
};
@@ -109,18 +112,26 @@ namespace celix {
Cardinality getCardinality() const;
bool getRequired() const;
const std::string& getFilter() const;
+ void setEnable(bool enable);
protected:
- GenericServiceDependency(std::shared_ptr<BundleContext> ctx);
+ GenericServiceDependency(
+ std::shared_ptr<BundleContext> ctx,
+ std::function<void()> stateChangedCallback,
+ std::function<void()> enable,
+ std::function<void()> disable);
//Fields
+ std::shared_ptr<BundleContext> ctx;
+ const std::function<void()> stateChangedCallback;
+ const std::function<void()> enable;
+ std::function<void()> disable;
+
mutable std::mutex mutex{}; //protects below
bool required = false;
std::string filter{};
Cardinality cardinality = Cardinality::One;
std::vector<ServiceTracker> tracker{}; //max 1
-
- std::shared_ptr<BundleContext> ctx;
};
template<typename T, typename I>
@@ -129,7 +140,7 @@ namespace celix {
using ComponentType = T;
using ServiceType = I;
- ServiceDependency(std::shared_ptr<ComponentManager<T>> mng);
+ ServiceDependency(std::shared_ptr<BundleContext> ctx, std::function<void()> stateChangedCallback, std::function<std::shared_ptr<T>()> getCmpInstance);
~ServiceDependency() override = default;
ServiceDependency<T,I>& setFilter(const std::string &filter);
@@ -138,15 +149,25 @@ namespace celix {
ServiceDependency<T,I>& setCallbacks(void (T::*set)(std::shared_ptr<I>));
ServiceDependency<T,I>& setCallbacks(void (T::*add)(std::shared_ptr<I>), void (T::*remove)(std::shared_ptr<I>));
//TODO update callback
+ //TODO callbacks with properties and owner
+
+ ServiceDependency<T,I>& setFunctionCallbacks(
+ std::function<void(std::shared_ptr<I>, const celix::Properties &props, const celix::IResourceBundle &owner)> set,
+ std::function<void(std::shared_ptr<I>, const celix::Properties &props, const celix::IResourceBundle &owner)> add,
+ std::function<void(std::shared_ptr<I>, const celix::Properties &props, const celix::IResourceBundle &owner)> rem,
+ std::function<void(std::vector<std::tuple<std::shared_ptr<I>, const celix::Properties*, const celix::IResourceBundle *>> rankedServices)> update);
- void enable();
- void disable();
+ ServiceDependency<T,I>& enable();
+ ServiceDependency<T,I>& disable();
bool isResolved();
private:
- std::function<void(std::shared_ptr<I>)> set{};
- std::function<void(std::shared_ptr<I>)> add{};
- std::function<void(std::shared_ptr<I>)> rem{};
- std::shared_ptr<ComponentManager<T>> mng;
+ const std::function<std::shared_ptr<T>()> getCmpInstance;
+
+
+ std::function<void(std::shared_ptr<I> svc, const celix::Properties &props, const celix::IResourceBundle &owner)> set{};
+ std::function<void(std::shared_ptr<I> svc, const celix::Properties &props, const celix::IResourceBundle &owner)> add{};
+ std::function<void(std::shared_ptr<I> svc, const celix::Properties &props, const celix::IResourceBundle &owner)> rem{};
+ std::function<void(std::vector<std::tuple<std::shared_ptr<I>, const celix::Properties*, const celix::IResourceBundle *>> rankedServices)> update{};
};
}
@@ -155,8 +176,9 @@ namespace celix {
/**************************** IMPLEMENTATION *************************************************************************/
template<typename T>
-celix::ComponentManager<T>::ComponentManager(std::shared_ptr<BundleContext> ctx, std::shared_ptr<T> cmpInstance) :
- GenericComponentManager(ctx, std::static_pointer_cast<void>(cmpInstance)) {}
+celix::ComponentManager<T>::ComponentManager(
+ std::shared_ptr<BundleContext> ctx,
+ std::shared_ptr<T> cmpInstance) : GenericComponentManager{ctx}, inst{std::move(cmpInstance)} {}
template<typename T>
celix::ComponentManager<T>& celix::ComponentManager<T>::enable() {
@@ -172,95 +194,138 @@ celix::ComponentManager<T>& celix::ComponentManager<T>::disable() {
template<typename T>
celix::ComponentManager<T>& celix::ComponentManager<T>::setCallbacks(
- void (T::*init)(),
- void (T::*start)(),
- void (T::*stop)(),
- void (T::*deinit)()) {
+ void (T::*memberInit)(),
+ void (T::*memberStart)(),
+ void (T::*memberStop)(),
+ void (T::*memberDeinit)()) {
std::lock_guard<std::mutex> lck{mutex};
- auto initFunc = [this,init]() {
- if (init) {
- (this->instance->*init)();
+ init = [this, memberInit]() {
+ if (memberInit) {
+ (this->instance()->*memberInit)();
}
};
- auto startFunc = [this,start]() {
- if (start) {
- (this->instance->*start)();
+ start = [this, memberStart]() {
+ if (memberStart) {
+ (this->instance()->*memberStart)();
}
};
- auto stopFunc = [this,stop]() {
- if (stop) {
- (this->instance->*stop)();
+ stop = [this, memberStop]() {
+ if (memberStop) {
+ (this->instance()->*memberStop)();
}
};
- auto deinitFunc = [this,deinit]() {
- if (deinit) {
- (this->instance->*deinit)();
+ deinit = [this, memberDeinit]() {
+ if (memberDeinit) {
+ (this->instance()->*memberDeinit)();
}
};
+ return *this;
+}
+template<typename T>
+std::shared_ptr<T> celix::ComponentManager<T>::instance() {
+ return inst;
}
-template<typename T, typename I>
-celix::ServiceDependency<T,I>::ServiceDependency(std::shared_ptr<ComponentManager<T>> _mng) : mng{std::move(_mng)} {
- add = [this](std::shared_ptr<I>) {
- mng->updateState();
- };
- rem = [this](std::shared_ptr<I>) {
- mng->updateState();
- };
+
+template<typename T>
+template<typename I>
+celix::ServiceDependency<T,I>& celix::ComponentManager<T>::addServiceDependency() {
+ auto *dep = new celix::ServiceDependency<T,I>{ctx, []{/*TODO*/}, [this]{return instance();}};
+ std::lock_guard<std::mutex> lck{mutex};
+ serviceDependencies[nextServiceDependencyId++] = std::unique_ptr<GenericServiceDependency>{dep};
+ return *dep;
}
+
+
+
+
+
+
+
template<typename T, typename I>
-void celix::ServiceDependency<T,I>::enable() {
- std::vector<celix::ServiceTracker> localTrackers{};
- {
- std::lock_guard<std::mutex> lck{mutex};
- std::swap(localTrackers, tracker);
- assert(tracker.size() == 0);
+celix::ServiceDependency<T,I>::ServiceDependency(
+ std::shared_ptr<celix::BundleContext> _ctx,
+ std::function<void()> _stateChangedCallback,
+ std::function<std::shared_ptr<T>()> _getCmpInstance) : GenericServiceDependency{_ctx, _stateChangedCallback, [this]{enable();}, [this]{disable();}}, getCmpInstance{_getCmpInstance} {};
+template<typename T, typename I>
+celix::ServiceDependency<T,I>& celix::ServiceDependency<T,I>::enable() {
+ std::lock_guard<std::mutex> lck{mutex};
+ if (tracker.size() == 0) { //disabled
ServiceTrackerOptions<I> opts{};
opts.filter = this->filter;
- opts.set = set;
- opts.add = add;
- opts.remove = rem;
-
+ opts.setWithOwner = set;
+ opts.addWithOwner = add;
+ opts.removeWithOwner = rem;
+ opts.updateWithOwner = [this](std::vector<std::tuple<std::shared_ptr<I>, const celix::Properties*, const celix::IResourceBundle *>> rankedServices) {
+ if (this->update) {
+ //TODO lock?
+ this->update(std::move(rankedServices));
+ }
+ this->stateChangedCallback();
+ };
this->tracker.push_back(this->ctx->trackServices(opts));
}
+ return *this;
+}
+template<typename T, typename I>
+celix::ServiceDependency<T,I>& celix::ServiceDependency<T,I>::disable() {
+ std::lock_guard<std::mutex> lck{mutex};
+ tracker.clear();
+ return *this;
}
template<typename T, typename I>
-void celix::ServiceDependency<T,I>::disable() {
- std::vector<celix::ServiceTracker> localTrackers{};
- {
- std::lock_guard<std::mutex> lck{mutex};
- std::swap(localTrackers, tracker);
- assert(tracker.size() == 0);
+celix::ServiceDependency<T,I>& celix::ServiceDependency<T,I>::setFunctionCallbacks(
+ std::function<void(std::shared_ptr<I> svc, const celix::Properties &props, const celix::IResourceBundle &owner)> setArg,
+ std::function<void(std::shared_ptr<I> svc, const celix::Properties &props, const celix::IResourceBundle &owner)> addArg,
+ std::function<void(std::shared_ptr<I> svc, const celix::Properties &props, const celix::IResourceBundle &owner)> remArg,
+ std::function<void(std::vector<std::tuple<std::shared_ptr<I>, const celix::Properties*, const celix::IResourceBundle *>> rankedServices)> updateArg) {
+
+ //TODO lock or disable?
+ set = {};
+ add = {};
+ rem = {};
+ update = {};
+
+ if (setArg) {
+ set = std::move(setArg);
+ }
+ if (addArg) {
+ add = addArg;
+ }
+ if (remArg) {
+ rem = remArg;
+ }
+ if (updateArg) {
+ update = std::move(updateArg);
}
+ return *this;
}
-
template<typename T, typename I>
celix::ServiceDependency<T,I>& celix::ServiceDependency<T,I>::setCallbacks(void (T::*setfp)(std::shared_ptr<I>)) {
std::lock_guard<std::mutex> lck{mutex};
- set = [this, setfp](std::shared_ptr<I> svc) {
- (mng->instance->*setfp)(svc);
+ auto setFunc = [this, setfp](std::shared_ptr<I> svc, const celix::Properties &, const celix::IResourceBundle &) {
+ (getCmpInstance()->instance->*setfp)(svc);
};
- return *this;
+ return setFunctionCallbacks(std::move(setFunc), {}, {}, {});
}
+
template<typename T, typename I>
celix::ServiceDependency<T,I>& celix::ServiceDependency<T,I>::setCallbacks(void (T::*addfp)(std::shared_ptr<I>), void (T::*remfp)(std::shared_ptr<I>)) {
std::lock_guard<std::mutex> lck{mutex};
- add = [this, addfp](std::shared_ptr<I> svc) {
- (mng->instance->*addfp)(svc);
- mng->updateState();
+ auto addFunc = [this, addfp](std::shared_ptr<I> svc, const celix::Properties &, const celix::IResourceBundle &) {
+ (getCmpInstance()->instance->*addfp)(svc);
};
- rem = [this, remfp](std::shared_ptr<I> svc) {
- (mng->instance->*remfp)(svc);
- mng->updateState();
+ auto remFunc = [this, remfp](std::shared_ptr<I> svc, const celix::Properties &, const celix::IResourceBundle &) {
+ (getCmpInstance()->instance->*remfp)(svc);
};
- return *this;
+ return setFunctionCallbacks({}, std::move(addFunc), std::move(remFunc), {});
}
template<typename T, typename I>
@@ -285,4 +350,4 @@ celix::ServiceDependency<T,I>& celix::ServiceDependency<T,I>::setCardinality(cel
}
-#endif //CXX_CELIX_PROPERTIES_H
+#endif //CXX_CELIX_COMPONENT_MANAGER_H
diff --git a/libs/framework_cxx/src/ComponentManager.cc b/libs/framework_cxx/src/ComponentManager.cc
index b3b4205..f087b19 100644
--- a/libs/framework_cxx/src/ComponentManager.cc
+++ b/libs/framework_cxx/src/ComponentManager.cc
@@ -19,10 +19,16 @@
#include <iostream>
+#include <celix/ComponentManager.h>
+
#include "celix/ComponentManager.h"
-celix::GenericServiceDependency::GenericServiceDependency(std::shared_ptr<celix::BundleContext> _ctx) : ctx{_ctx} {}
+celix::GenericServiceDependency::GenericServiceDependency(
+ std::shared_ptr<celix::BundleContext> _ctx,
+ std::function<void()> _stateChangedCallback,
+ std::function<void()> _enable,
+ std::function<void()> _disable) : ctx{_ctx}, stateChangedCallback{std::move(_stateChangedCallback)}, enable{std::move(_enable)}, disable{std::move(_disable)} {}
bool celix::GenericServiceDependency::isResolved() const {
@@ -49,6 +55,14 @@ const std::string &celix::GenericServiceDependency::getFilter() const {
return filter;
}
+void celix::GenericServiceDependency::setEnable(bool e) {
+ if (e) {
+ enable();
+ } else {
+ disable();
+ }
+}
+
celix::ComponentState celix::GenericComponentManager::getState() const {
std::lock_guard<std::mutex> lck{mutex};
return state;
@@ -62,11 +76,11 @@ bool celix::GenericComponentManager::isEnabled() const {
bool celix::GenericComponentManager::isResolved() const {
std::lock_guard<std::mutex> lck{mutex};
-// for (auto &pair : serviceDependencies) {
-// if (!pair->second.isResolved()) {
-// return false;
-// }
-// }
+ for (auto &pair : serviceDependencies) {
+ if (!pair.second->isResolved()) {
+ return false;
+ }
+ }
return true;
}
@@ -78,6 +92,9 @@ void celix::GenericComponentManager::removeServiceDependency(long serviceDepende
void celix::GenericComponentManager::setEnabled(bool e) {
std::lock_guard<std::mutex> lck{mutex};
enabled = e;
+ for (auto &pair : serviceDependencies) {
+ pair.second->setEnable(e);
+ }
}
void celix::GenericComponentManager::updateState() {
@@ -89,7 +106,7 @@ void celix::GenericComponentManager::updateState() {
bool allDependenciesResolved = true;
for (auto &pair : serviceDependencies) {
- if (!pair.second.isResolved()) {
+ if (!pair.second->isResolved()) {
allDependenciesResolved = false;
break;
}
diff --git a/libs/registry/include/celix/ServiceRegistry.h b/libs/registry/include/celix/ServiceRegistry.h
index c9a9a8e..4457d0e 100644
--- a/libs/registry/include/celix/ServiceRegistry.h
+++ b/libs/registry/include/celix/ServiceRegistry.h
@@ -601,7 +601,7 @@ inline celix::ServiceTracker celix::ServiceRegistry::trackServices(std::string s
};
}
- return trackAnyServices(std::move(svcName), std::move(opts), requester);
+ return trackAnyServices(std::move(svcName), std::move(opts), std::move(requester));
}
#endif //CXX_CELIX_SERVICEREGISTRY_H