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/08/22 19:58:12 UTC
[celix] branch feature/cxx updated: CELIX-370: Adds initial
implementation for component manager state transition
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
The following commit(s) were added to refs/heads/feature/cxx by this push:
new bc4a582 CELIX-370: Adds initial implementation for component manager state transition
bc4a582 is described below
commit bc4a582fab6495823f25254440eda6e2652d8d31
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Thu Aug 22 21:57:46 2019 +0200
CELIX-370: Adds initial implementation for component manager state transition
---
.../gtest/src/ComponentManager_tests.cc | 44 ++++
.../framework_cxx/include/celix/ComponentManager.h | 131 +++++++----
libs/framework_cxx/src/ComponentManager.cc | 246 ++++++++++++++++++---
libs/registry/include/celix/Utils.h | 19 +-
4 files changed, 367 insertions(+), 73 deletions(-)
diff --git a/libs/framework_cxx/gtest/src/ComponentManager_tests.cc b/libs/framework_cxx/gtest/src/ComponentManager_tests.cc
index 77dc8de..db7fc7e 100644
--- a/libs/framework_cxx/gtest/src/ComponentManager_tests.cc
+++ b/libs/framework_cxx/gtest/src/ComponentManager_tests.cc
@@ -44,6 +44,11 @@ TEST_F(ComponentManagerTest, CreateDestroy) {
cmpMng.enable();
EXPECT_TRUE(cmpMng.isEnabled());
+ EXPECT_EQ(cmpMng.getState(), celix::ComponentState::Started);
+
+ cmpMng.disable();
+ EXPECT_FALSE(cmpMng.isEnabled());
+ EXPECT_EQ(cmpMng.getState(), celix::ComponentState::Disabled);
}
TEST_F(ComponentManagerTest, AddSvcDep) {
@@ -57,6 +62,8 @@ TEST_F(ComponentManagerTest, AddSvcDep) {
.setRequired(true);
cmpMng.enable();
EXPECT_TRUE(cmpMng.isEnabled());
+ EXPECT_EQ(cmpMng.getState(), celix::ComponentState::Uninitialized);
+
//dep not available -> cmp manager not resolved
EXPECT_FALSE(cmpMng.isResolved());
@@ -65,4 +72,41 @@ TEST_F(ComponentManagerTest, AddSvcDep) {
auto svcReg = ctx->registerService(std::make_shared<ISvc>());
//dep available -> cmp manager resolved
EXPECT_TRUE(cmpMng.isResolved());
+ EXPECT_EQ(cmpMng.getState(), celix::ComponentState::Started);
+
+ cmpMng.disable();
+ //cmp disabled -> not resolved
+ EXPECT_FALSE(cmpMng.isResolved());
+ EXPECT_EQ(cmpMng.getState(), celix::ComponentState::Disabled);
+
+ //dmp enabled & svc available -> resolved.
+ cmpMng.enable();
+ EXPECT_TRUE(cmpMng.isResolved());
+ EXPECT_EQ(cmpMng.getState(), celix::ComponentState::Started);
+
+ svcReg.unregister();
+ EXPECT_EQ(cmpMng.getState(), celix::ComponentState::Initialized);
+ //dep unregisted -> state is Initialized
+}
+
+TEST_F(ComponentManagerTest, AddAndRemoveSvcDep) {
+ auto ctx = framework().context();
+
+ class Cmp {};
+ class ISvc {};
+ std::string svcDepUuid;
+
+ celix::ComponentManager<Cmp> cmpMng{ctx, std::make_shared<Cmp>()};
+ cmpMng.addServiceDependency<ISvc>()
+ .setRequired(true)
+ .extractUUID(svcDepUuid);
+ cmpMng.enable();
+ EXPECT_TRUE(cmpMng.isEnabled());
+
+ //dep not available -> cmp manager not resolved
+ EXPECT_FALSE(cmpMng.isResolved());
+
+ cmpMng.removeServiceDependency(svcDepUuid);
+ //dep removed -> 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 bfbd971..2612fa5 100644
--- a/libs/framework_cxx/include/celix/ComponentManager.h
+++ b/libs/framework_cxx/include/celix/ComponentManager.h
@@ -22,7 +22,9 @@
#include <memory>
#include <unordered_map>
+#include <queue>
+#include "celix/Utils.h"
#include "celix/BundleContext.h"
namespace celix {
@@ -45,29 +47,41 @@ namespace celix {
ComponentState getState() const;
bool isEnabled() const;
bool isResolved() const;
+ std::string getName() const;
+ std::string getUUD() const;
//TODO make friend of SvcDep
void updateState();
+
+ void removeServiceDependency(const std::string& serviceDependencyUUID);
protected:
- GenericComponentManager(std::shared_ptr<BundleContext> _ctx) : ctx{std::move(_ctx)} {};
+ GenericComponentManager(std::shared_ptr<BundleContext> _ctx, const std::string &_name);
- void removeServiceDependency(long serviceDependencyId);
void setEnabled(bool enable);
-
/**** Fields ****/
- std::shared_ptr<BundleContext> ctx;
+ const std::shared_ptr<BundleContext> ctx;
+ const std::string name;
+ const std::string uuid;
+
+ std::mutex callbacksMutex{}; //protects below std::functions
+ std::function<void()> init{[]{/*nop*/}};
+ std::function<void()> start{[]{/*nop*/}};
+ std::function<void()> stop{[]{/*nop*/}};
+ std::function<void()> deinit{[]{/*nop*/}};
+
+ std::mutex serviceDependenciesMutex{};
+ std::unordered_map<std::string,std::shared_ptr<GenericServiceDependency>> serviceDependencies{}; //key = dep uuid
+ private:
+ void setState(ComponentState state);
+ void setInitialized(bool initialized);
+ void transition();
- mutable std::mutex mutex{}; //protects below
+ mutable std::mutex stateMutex{}; //protects below
ComponentState state = ComponentState::Disabled;
bool enabled = false;
- std::function<void()> init{};
- std::function<void()> start{};
- std::function<void()> stop{};
- std::function<void()> deinit{};
-
- long nextServiceDependencyId = 1L;
- std::unordered_map<long,std::unique_ptr<GenericServiceDependency>> serviceDependencies{};
+ bool initialized = false;
+ std::queue<std::pair<ComponentState,ComponentState>> transitionQueue{};
};
template<typename T>
@@ -75,7 +89,7 @@ namespace celix {
public:
using ComponentType = T;
- ComponentManager(std::shared_ptr<BundleContext> ctx, std::shared_ptr<T> cmpInstance);
+ ComponentManager(std::shared_ptr<BundleContext> ctx, std::shared_ptr<T> cmpInstance, const std::string &name = celix::typeName<T>());
~ComponentManager() override = default;
ComponentManager<T>& enable();
@@ -91,6 +105,11 @@ namespace celix {
template<typename I>
ServiceDependency<T,I>& addServiceDependency();
+
+ template<typename I>
+ ServiceDependency<T,I>* findServiceDependency(const std::string& serviceDependencyUUID);
+
+ ComponentManager<T>& extractUUID(std::string& out);
//
// template<typename F>
// ServiceDependency<T,F>& addFunctionServiceDependency(const std::string &functionName);
@@ -112,26 +131,25 @@ namespace celix {
Cardinality getCardinality() const;
bool getRequired() const;
const std::string& getFilter() const;
- void setEnable(bool enable);
+ std::string getUUD();
+ bool isEnabled();
+ virtual void setEnabled(bool e) = 0;
protected:
GenericServiceDependency(
std::shared_ptr<BundleContext> ctx,
- std::function<void()> stateChangedCallback,
- std::function<void()> enable,
- std::function<void()> disable);
+ std::function<void()> stateChangedCallback);
//Fields
- std::shared_ptr<BundleContext> ctx;
+ const std::shared_ptr<BundleContext> ctx;
const std::function<void()> stateChangedCallback;
- const std::function<void()> enable;
- std::function<void()> disable;
+ const std::string uuid;
mutable std::mutex mutex{}; //protects below
bool required = false;
std::string filter{};
Cardinality cardinality = Cardinality::One;
- std::vector<ServiceTracker> tracker{}; //max 1
+ std::vector<ServiceTracker> tracker{}; //max 1 (1 == enabled / 0 = disabled
};
template<typename T, typename I>
@@ -157,9 +175,12 @@ namespace celix {
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);
+ ServiceDependency<T,I>& extractUUID(std::string& out);
ServiceDependency<T,I>& enable();
ServiceDependency<T,I>& disable();
- bool isResolved();
+
+ void setEnabled(bool e) override;
+
private:
const std::function<std::shared_ptr<T>()> getCmpInstance;
@@ -171,6 +192,8 @@ namespace celix {
};
}
+std::ostream& operator<< (std::ostream& out, celix::ComponentState state);
+
/**************************** IMPLEMENTATION *************************************************************************/
@@ -178,17 +201,19 @@ namespace celix {
template<typename T>
celix::ComponentManager<T>::ComponentManager(
std::shared_ptr<BundleContext> ctx,
- std::shared_ptr<T> cmpInstance) : GenericComponentManager{ctx}, inst{std::move(cmpInstance)} {}
+ std::shared_ptr<T> cmpInstance,
+ const std::string &name) : GenericComponentManager{ctx, name}, inst{std::move(cmpInstance)} {
+}
template<typename T>
celix::ComponentManager<T>& celix::ComponentManager<T>::enable() {
- this->setEnabled(true);
+ setEnabled(true);
return *this;
}
template<typename T>
celix::ComponentManager<T>& celix::ComponentManager<T>::disable() {
- this->setEnabled(false);
+ setEnabled(false);
return *this;
}
@@ -198,7 +223,7 @@ celix::ComponentManager<T>& celix::ComponentManager<T>::setCallbacks(
void (T::*memberStart)(),
void (T::*memberStop)(),
void (T::*memberDeinit)()) {
- std::lock_guard<std::mutex> lck{mutex};
+ std::lock_guard<std::mutex> lck{callbacksMutex};
init = [this, memberInit]() {
if (memberInit) {
(this->instance()->*memberInit)();
@@ -227,17 +252,28 @@ std::shared_ptr<T> celix::ComponentManager<T>::instance() {
return inst;
}
+template<typename T>
+celix::ComponentManager<T>& celix::ComponentManager<T>::extractUUID(std::string &out) {
+ out = uuid;
+ return *this;
+}
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};
+ auto *dep = new celix::ServiceDependency<T,I>{ctx, [this]{updateState();}, [this]{return instance();}};
+ std::lock_guard<std::mutex> lck{serviceDependenciesMutex};
+ serviceDependencies[dep->getUUD()] = std::unique_ptr<GenericServiceDependency>{dep};
return *dep;
}
-
+template<typename T>
+template<typename I>
+celix::ServiceDependency<T,I>* celix::ComponentManager<T>::findServiceDependency(const std::string& serviceDependencyUUID) {
+ std::lock_guard<std::mutex> lck{serviceDependenciesMutex};
+ auto it = serviceDependencies.find(serviceDependencyUUID);
+ return it != serviceDependencies.end() ? nullptr : it->second.get();
+}
@@ -248,12 +284,14 @@ template<typename T, typename I>
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} {};
+ std::function<std::shared_ptr<T>()> _getCmpInstance) : GenericServiceDependency{std::move(_ctx), std::move(_stateChangedCallback)}, 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
+void celix::ServiceDependency<T,I>::setEnabled(bool enable) {
+ bool currentlyEnabled = isEnabled();
+ std::vector<ServiceTracker> newTracker{};
+ if (enable && !currentlyEnabled) {
+ //enable
ServiceTrackerOptions<I> opts{};
opts.filter = this->filter;
opts.setWithOwner = set;
@@ -266,15 +304,28 @@ celix::ServiceDependency<T,I>& celix::ServiceDependency<T,I>::enable() {
}
this->stateChangedCallback();
};
- this->tracker.push_back(this->ctx->trackServices(opts));
+ newTracker.emplace_back(ctx->trackServices(opts));
+ std::lock_guard<std::mutex> lck{mutex};
+ std::swap(tracker, newTracker);
+
+ } else if (!enable and currentlyEnabled) {
+ //disable
+ std::lock_guard<std::mutex> lck{mutex};
+ std::swap(tracker, newTracker/*empty*/);
}
+
+ //newTracker out of scope -> RAII -> for disable clear current tracker, for enable empty newTracker
+}
+
+template<typename T, typename I>
+celix::ServiceDependency<T,I>& celix::ServiceDependency<T,I>::enable() {
+ setEnabled(true);
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();
+ setEnabled(false);
return *this;
}
@@ -349,5 +400,11 @@ celix::ServiceDependency<T,I>& celix::ServiceDependency<T,I>::setCardinality(cel
return *this;
}
+template<typename T, typename I>
+celix::ServiceDependency<T,I>& celix::ServiceDependency<T,I>::extractUUID(std::string& out) {
+ out = uuid;
+ return *this;
+}
+
#endif //CXX_CELIX_COMPONENT_MANAGER_H
diff --git a/libs/framework_cxx/src/ComponentManager.cc b/libs/framework_cxx/src/ComponentManager.cc
index f087b19..07e3bc0 100644
--- a/libs/framework_cxx/src/ComponentManager.cc
+++ b/libs/framework_cxx/src/ComponentManager.cc
@@ -19,16 +19,29 @@
#include <iostream>
+#include <uuid/uuid.h>
#include <celix/ComponentManager.h>
+#include <glog/logging.h>
#include "celix/ComponentManager.h"
+static std::string genUUID() {
+ uuid_t tmpUUID;
+ uuid_string_t str;
+
+ uuid_generate(tmpUUID);
+ uuid_unparse(tmpUUID, str);
+
+ return std::string{str};
+}
+
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)} {}
+ std::function<void()> _stateChangedCallback) :
+ ctx{std::move(_ctx)},
+ stateChangedCallback{std::move(_stateChangedCallback)},
+ uuid{genUUID()} {}
bool celix::GenericServiceDependency::isResolved() const {
@@ -55,27 +68,27 @@ const std::string &celix::GenericServiceDependency::getFilter() const {
return filter;
}
-void celix::GenericServiceDependency::setEnable(bool e) {
- if (e) {
- enable();
- } else {
- disable();
- }
+std::string celix::GenericServiceDependency::getUUD() {
+ return uuid;
}
-celix::ComponentState celix::GenericComponentManager::getState() const {
+bool celix::GenericServiceDependency::isEnabled() {
std::lock_guard<std::mutex> lck{mutex};
+ return !tracker.empty();
+}
+
+celix::ComponentState celix::GenericComponentManager::getState() const {
+ std::lock_guard<std::mutex> lck{stateMutex};
return state;
}
bool celix::GenericComponentManager::isEnabled() const {
- std::lock_guard<std::mutex> lck{mutex};
- //TODO update state
+ std::lock_guard<std::mutex> lck{stateMutex};
return enabled;
}
bool celix::GenericComponentManager::isResolved() const {
- std::lock_guard<std::mutex> lck{mutex};
+ std::lock_guard<std::mutex> lck{stateMutex};
for (auto &pair : serviceDependencies) {
if (!pair.second->isResolved()) {
return false;
@@ -84,36 +97,207 @@ bool celix::GenericComponentManager::isResolved() const {
return true;
}
-void celix::GenericComponentManager::removeServiceDependency(long serviceDependencyId) {
- std::lock_guard<std::mutex> lck{mutex};
- serviceDependencies.erase(serviceDependencyId);
-}
-
void celix::GenericComponentManager::setEnabled(bool e) {
- std::lock_guard<std::mutex> lck{mutex};
- enabled = e;
- for (auto &pair : serviceDependencies) {
- pair.second->setEnable(e);
+ {
+ std::lock_guard<std::mutex> lck{stateMutex};
+ enabled = e;
}
+ std::vector<std::shared_ptr<GenericServiceDependency>> deps{};
+ {
+ std::lock_guard<std::mutex> lck{serviceDependenciesMutex};
+ for (auto &pair : serviceDependencies) {
+ deps.push_back(pair.second);
+ }
+ }
+
+ //NOTE updating outside of the lock
+ for (auto &dep : deps) {
+ dep->setEnabled(e);
+ }
+ updateState();
}
void celix::GenericComponentManager::updateState() {
- std::lock_guard<std::mutex> lck{mutex};
+ bool allDependenciesResolved = true;
+ {
+ std::lock_guard<std::mutex> lck{serviceDependenciesMutex};
+ for (auto &pair : serviceDependencies) {
+ if (!pair.second->isResolved()) {
+ allDependenciesResolved = false;
+ break;
+ }
+ }
+ }
- //TODO state thing
+ {
+ std::lock_guard<std::mutex> lck{stateMutex};
+ ComponentState currentState = state;
+ ComponentState targetState = ComponentState::Disabled;
- //TODO check enabled.
+ if (enabled && allDependenciesResolved) {
+ targetState = ComponentState::Started;
+ } else if (enabled) /*not all dep resolved*/ {
+ targetState = initialized ? ComponentState::Initialized : ComponentState::Uninitialized;
+ }
- bool allDependenciesResolved = true;
- for (auto &pair : serviceDependencies) {
- if (!pair.second->isResolved()) {
- allDependenciesResolved = false;
- break;
+ if (currentState != targetState) {
+ transitionQueue.emplace(currentState, targetState);
}
}
+ transition();
+}
- std::cout << "resolved? " << (allDependenciesResolved ? "true" : "false") << std::endl;
+void celix::GenericComponentManager::transition() {
+ ComponentState currentState;
+ ComponentState targetState;
+
+ {
+ std::lock_guard<std::mutex> lck{stateMutex};
+ if (transitionQueue.empty()) {
+ return;
+ }
+ auto pair = transitionQueue.front();
+ transitionQueue.pop();
+ currentState = pair.first;
+ targetState = pair.second;
+ }
+
+ DLOG(INFO) << "Transition for " << name << " from " << currentState << " to " << targetState;
+
+ //TODO note callbacks are called outside of mutex. make local copies or ensure that callback can only be changed with disabled component managers ...
+
+ if (targetState == ComponentState::Disabled) {
+ switch (currentState) {
+ case celix::ComponentState::Disabled:
+ //nop
+ break;
+ case celix::ComponentState::Uninitialized:
+ //TODO may disable callback to cmp
+ setState(ComponentState::Disabled);
+ break;
+ case celix::ComponentState::Initialized:;
+ deinit();
+ setInitialized(false);
+ setState(ComponentState::Uninitialized);
+ break;
+ case celix::ComponentState::Started:
+ stop();
+ setState(ComponentState::Initialized);
+ break;
+ }
+ } else if (targetState == ComponentState::Uninitialized) {
+ switch (currentState) {
+ case celix::ComponentState::Disabled:
+ //TODO maybe enable callback
+ setState(ComponentState::Uninitialized);
+ break;
+ case celix::ComponentState::Uninitialized:
+ //nop
+ break;
+ case celix::ComponentState::Initialized:
+ deinit();
+ setInitialized(false);
+ setState(ComponentState::Uninitialized);
+ break;
+ case celix::ComponentState::Started:
+ stop();
+ setState(ComponentState::Initialized);
+ break;
+ }
+ } else if (targetState == ComponentState::Initialized) {
+ switch (currentState) {
+ case celix::ComponentState::Disabled:
+ //TODO maybe enabled callback
+ setState(ComponentState::Uninitialized);
+ break;
+ case celix::ComponentState::Uninitialized:
+ init();
+ setInitialized(true);
+ setState(ComponentState::Initialized);
+ break;
+ case celix::ComponentState::Initialized:
+ //nop
+ break;
+ case celix::ComponentState::Started:
+ stop();
+ setState(ComponentState ::Initialized);
+ break;
+ }
+ } else if (targetState == ComponentState::Started) {
+ switch (currentState) {
+ case celix::ComponentState::Disabled:
+ //TODO maybe enabled callback
+ setState(ComponentState::Uninitialized);
+ break;
+ case celix::ComponentState::Uninitialized:
+ init();
+ setInitialized(true);
+ setState(ComponentState::Initialized);
+ break;
+ case celix::ComponentState::Initialized:
+ start();
+ setState(ComponentState::Started);
+ break;
+ case celix::ComponentState::Started:
+ //nop
+ break;
+ }
+ } else {
+ LOG(ERROR) << "Unexpected target state: " << targetState;
+ }
+
+ updateState();
+}
+
+void celix::GenericComponentManager::setState(ComponentState s) {
+ std::lock_guard<std::mutex> lck{stateMutex};
+ state = s;
+}
+
+
+std::string celix::GenericComponentManager::getUUD() const {
+ return uuid;
+}
+
+celix::GenericComponentManager::GenericComponentManager(std::shared_ptr<celix::BundleContext> _ctx, const std::string &_name) : ctx{std::move(_ctx)}, name{_name}, uuid{genUUID()} {
+}
+
+void celix::GenericComponentManager::removeServiceDependency(const std::string& serviceDependencyUUID) {
+ std::lock_guard<std::mutex> lck{stateMutex};
+ auto it = serviceDependencies.find(serviceDependencyUUID);
+ if (it != serviceDependencies.end()) {
+ serviceDependencies.erase(it);
+ } else {
+ LOG(WARNING) << "Cannot find service dependency with uuid " << serviceDependencyUUID << " in component manager " << name << " with uuid " << uuid << ".";
+ }
+}
+
+std::string celix::GenericComponentManager::getName() const {
+ return name;
+}
+
+void celix::GenericComponentManager::setInitialized(bool i) {
+ std::lock_guard<std::mutex> lck{stateMutex};
+ initialized = i;
}
+std::ostream& operator<< (std::ostream& out, celix::ComponentState state)
+{
+ switch (state) {
+ case celix::ComponentState::Disabled:
+ out << "Disabled";
+ break;
+ case celix::ComponentState::Uninitialized:
+ out << "Uninitialized";
+ break;
+ case celix::ComponentState::Initialized:
+ out << "Initialized";
+ break;
+ case celix::ComponentState::Started:
+ out << "Started";
+ break;
+ }
+ return out;
+}
diff --git a/libs/registry/include/celix/Utils.h b/libs/registry/include/celix/Utils.h
index ce72e4f..56c4f53 100644
--- a/libs/registry/include/celix/Utils.h
+++ b/libs/registry/include/celix/Utils.h
@@ -34,7 +34,7 @@ namespace impl {
namespace {
template<typename INTERFACE_TYPENAME>
- std::string typeName() {
+ std::string typeNameInternal() {
static const std::string templateStr = "INTERFACE_TYPENAME = ";
std::string pretty = __PRETTY_FUNCTION__;
return celix::impl::typeNameFromPrettyFunction(templateStr, __PRETTY_FUNCTION__);
@@ -42,27 +42,35 @@ namespace {
template<typename Arg>
std::string argName() {
- return typeName<Arg>(); //terminal;
+ return typeNameInternal<Arg>(); //terminal;
}
template<typename Arg1, typename Arg2, typename... Args>
std::string argName() {
- return typeName<Arg1>() + ", " + argName<Arg2, Args...>();
+ return typeNameInternal<Arg1>() + ", " + argName<Arg2, Args...>();
}
template<typename R>
std::string functionName() {
- return "std::function<" + typeName<R>() + "()>";
+ return "std::function<" + typeNameInternal<R>() + "()>";
}
template<typename R, typename Arg1, typename... Args>
std::string functionName() {
- return "std::function<" + typeName<R>() + "(" + argName<Arg1, Args...>() + ")>";
+ return "std::function<" + typeNameInternal<R>() + "(" + argName<Arg1, Args...>() + ")>";
}
};
namespace celix {
+ /**
+ * Returns the type name of the provided template T
+ */
+ template<typename T>
+ std::string typeName() {
+ return typeNameInternal<T>();
+ }
+
/* TODO
template<typename I>
typename std::enable_if<I::FQN, std::string>::type
@@ -81,6 +89,7 @@ namespace celix {
return svcName;
}
+
//TODO resolve FQN for Function Service.
/**