28 std::lock_guard<std::mutex> lck{
mutex};
35 std::lock_guard<std::mutex> lck{
mutex};
51 celix_dependencyManager_wait(cDepMan);
57 FILE* stream = open_memstream(&buf, &bufSize);
70 celix_bundle_context_t *context,
71 celix_dependency_manager_t* cDepMan,
76 celix::cmpTypeName<T>(name),
85 static_assert(std::is_base_of<I,T>::value,
"Component T must implement Interface I");
86 if (!serviceName.empty()) {
87 T* cmpPtr = &this->getInstance();
88 I* svcPtr =
static_cast<I*
>(cmpPtr);
89 std::shared_ptr<I> svc{svcPtr, [](I*){}};
90 auto provide = std::make_shared<ProvidedService<T,I>>(cComponent(), serviceName, std::move(svc),
true);
91 provide->setVersion(version);
92 provide->setProperties(properties);
93 std::lock_guard<std::mutex> lck{mutex};
94 providedServices.push_back(provide);
96 std::cerr <<
"Cannot add interface with a empty name\n";
105 static_assert(std::is_base_of<I,T>::value,
"Component T must implement Interface I");
106 std::string serviceName = typeName<I>();
107 if (serviceName.empty()) {
108 std::cerr <<
"Cannot add interface, because type name could not be inferred. function: '" << __PRETTY_FUNCTION__ <<
"'\n";
110 auto svcVersion = celix::typeVersion<I>(version);
111 if (!svcVersion.empty()) {
115 return this->addInterfaceWithName<I>(serviceName, version, properties);
121 std::shared_ptr<I> svc{svcPtr, [](I*){}};
122 auto provide = std::make_shared<ProvidedService<T,I>>(cComponent(), serviceName, std::move(svc),
false);
123 provide->setVersion(version);
124 provide->setProperties(properties);
125 std::lock_guard<std::mutex> lck{mutex};
126 providedServices.push_back(provide);
134 std::lock_guard<std::mutex> lck{mutex};
135 for (
auto it = providedServices.begin(); it != providedServices.end(); ++it) {
136 std::shared_ptr<BaseProvidedService> provide = *it;
137 if (provide->getService() ==
static_cast<const void*
>(svc)) {
138 providedServices.erase(it);
149 std::lock_guard<std::mutex> lck{mutex};
150 dependencies.push_back(dep);
159 std::lock_guard<std::mutex> lck{mutex};
160 this->dependencies.erase(std::remove(this->dependencies.begin(), this->dependencies.end(), dep));
168 std::lock_guard<std::mutex> lck{mutex};
169 dependencies.push_back(dep);
178 std::lock_guard<std::mutex> lck{mutex};
179 this->dependencies.erase(std::remove(this->dependencies.begin(), this->dependencies.end(), dep));
184 std::shared_ptr<Component<T>>
Component<T>::create(celix_bundle_context_t *context, celix_dependency_manager_t* cDepMan, std::string name, std::string uuid) {
185 std::string cmpName = celix::cmpTypeName<T>(name);
186 return std::shared_ptr<Component<T>>{
new Component<T>(context, cDepMan, std::move(cmpName), std::move(uuid)), [](
Component<T>* cmp){
189 auto cb = [](
void *data) {
194 if (cmp->cmpAddedToDepMan) {
195 celix_dependencyManager_removeAsync(cmp->cDepMan, cmp->cCmp, cmp, cb);
204 return this->bundleContext() !=
nullptr;
210 typename std::enable_if<std::is_default_constructible<T>::value, T*>::type
217 typename std::enable_if<!std::is_default_constructible<T>::value, T*>::type
224 std::lock_guard<std::mutex> lck{instanceMutex};
225 if (!valInstance.empty()) {
226 return valInstance.front();
227 }
else if (sharedInstance) {
228 return *sharedInstance;
229 }
else if (instance) {
232 T* newInstance = createInstance<T>();
233 instance = std::unique_ptr<T>{newInstance};
240 std::lock_guard<std::mutex> lck{instanceMutex};
241 this->valInstance.clear();
242 this->instance = std::unique_ptr<T> {
nullptr};
243 this->sharedInstance = std::move(inst);
249 std::lock_guard<std::mutex> lck{instanceMutex};
250 this->valInstance.clear();
251 this->sharedInstance = std::shared_ptr<T> {
nullptr};
252 this->instance = std::move(inst);
258 std::lock_guard<std::mutex> lck{instanceMutex};
259 this->instance = std::unique_ptr<T> {
nullptr};
260 this->sharedInstance = std::shared_ptr<T> {
nullptr};
261 this->valInstance.clear();
262 this->valInstance.push_back(std::forward<T>(inst));
269 if (lifecycleMethod !=
nullptr) {
270 T& inst = getInstance();
271 (inst.*lifecycleMethod)();
273 }
catch (
const std::exception& e) {
274 celix_bundleContext_log(context, CELIX_LOG_LEVEL_ERROR,
"Error invoking %s for component %s (uuid=%s). Exception: %s",
295 void (T::*deinit)() ) {
298 this->startFp = start;
300 this->deinitFp = deinit;
303 int (*cInit)(
void *) = [](
void *handle) {
305 return cmp->invokeLifecycleMethod(
"init", cmp->initFp);
307 int (*cStart)(
void *) = [](
void *handle) {
309 return cmp->invokeLifecycleMethod(
"start", cmp->startFp);
311 int (*cStop)(
void *) = [](
void *handle) {
313 return cmp->invokeLifecycleMethod(
"stop", cmp->stopFp);
315 int (*cDeinit)(
void *) = [](
void *handle) {
317 return cmp->invokeLifecycleMethod(
"deinit", cmp->deinitFp);
330 int (T::*deinit)() ) {
332 this->initFpNoExc = init;
333 this->startFpNoExc = start;
334 this->stopFpNoExc = stop;
335 this->deinitFpNoExc = deinit;
337 int (*cInit)(
void *) = [](
void *handle) {
340 int (T::*fp)() = cmp->initFpNoExc;
342 return (inst->*fp)();
346 int (*cStart)(
void *) = [](
void *handle) {
349 int (T::*fp)() = cmp->startFpNoExc;
351 return (inst->*fp)();
355 int (*cStop)(
void *) = [](
void *handle) {
358 int (T::*fp)() = cmp->stopFpNoExc;
360 return (inst->*fp)();
364 int (*cDeinit)(
void *) = [](
void *handle) {
367 int (T::*fp)() = cmp->deinitFpNoExc;
369 return (inst->*fp)();
387 std::lock_guard<std::mutex> lock{mutex};
388 componentContexts.template emplace_back(std::move(context));
408 std::shared_ptr<I> svc{svcPtr, [](I*){}};
409 auto provide = std::make_shared<ProvidedService<T,I>>(cComponent(), serviceName, std::move(svc),
false);
410 std::lock_guard<std::mutex> lck{mutex};
411 providedServices.push_back(provide);
418 static_assert(std::is_base_of<I,T>::value,
"Component T must implement Interface I");
419 if (serviceName.empty()) {
420 serviceName = typeName<I>();
422 if (serviceName.empty()) {
423 std::cerr <<
"Cannot add interface, because type name could not be inferred. function: '" << __PRETTY_FUNCTION__ <<
"'\n";
426 I* svcPtr = &this->getInstance();
427 std::shared_ptr<I> svc{svcPtr, [](I*){}};
428 auto provide = std::make_shared<ProvidedService<T,I>>(cComponent(), serviceName, std::move(svc),
true);
429 auto svcVersion = celix::typeVersion<I>();
430 if (!svcVersion.empty()) {
433 std::lock_guard<std::mutex> lck{mutex};
434 providedServices.push_back(provide);
441 if (serviceName.empty()) {
442 serviceName = typeName<I>();
444 if (serviceName.empty()) {
445 std::cerr <<
"Cannot add interface, because type name could not be inferred. function: '" << __PRETTY_FUNCTION__ <<
"'\n";
448 auto provide = std::make_shared<ProvidedService<T,I>>(cComponent(), serviceName, std::move(svc),
true);
449 auto svcVersion = celix::typeVersion<I>();
450 if (!svcVersion.empty()) {
453 std::lock_guard<std::mutex> lck{mutex};
454 providedServices.push_back(provide);