Apache Celix  2.4.0
Apache Celix is a framework for C, C++14 and C++17 to develop dynamic modular software applications using component and in-process service-oriented programming.
Component.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #pragma once
21 
22 #include <map>
23 #include <string>
24 #include <vector>
25 #include <atomic>
26 #include <mutex>
27 #include <memory>
28 #include <iostream>
29 #include <type_traits>
30 #include <algorithm>
31 #include <cstdio>
32 
33 #include "celix_dm_component.h"
34 #include "celix/dm/types.h"
37 #include "celix_dependency_manager.h"
38 
39 
40 
41 namespace celix { namespace dm {
42 
43  enum class ComponentState : std::uint8_t {
44  INACTIVE = 1,
46  INITIALIZING = 3,
47  DEINITIALIZING = 4,
49  STARTING = 6,
50  STOPPING = 7,
52  SUSPENDING = 9,
53  SUSPENDED = 10,
54  RESUMING = 11,
55  };
56 
57  class BaseComponent {
58  public:
59  BaseComponent(celix_bundle_context_t *con, celix_dependency_manager_t* cdm, std::string name, std::string uuid) : context{con}, cDepMan{cdm}, cCmp{nullptr} {
60  this->cCmp = celix_dmComponent_createWithUUID(this->context, name.c_str(), uuid.empty() ? nullptr : uuid.c_str());
62  cmpUUID = std::string{celix_dmComponent_getUUID(this->cCmp)};
63  cmpName = std::string{celix_dmComponent_getName(this->cCmp)};
64  }
65  virtual ~BaseComponent() noexcept;
66 
67  BaseComponent(const BaseComponent&) = delete;
68  BaseComponent& operator=(const BaseComponent&) = delete;
69 
73  celix_dm_component_t* cComponent() const { return this->cCmp; }
74 
78  celix_bundle_context_t* bundleContext() const { return this->context; }
79 
83  const std::string& getUUID() const {
84  return cmpUUID;
85  }
86 
90  const std::string& getName() const {
91  return cmpName;
92  }
93 
98  auto cState = celix_dmComponent_currentState(cCmp);
99  switch (cState) {
120  default:
122  }
123  }
124 
134  void wait() const;
135 
141  void runBuild();
142 
143  friend std::ostream& operator<<(std::ostream& out, const BaseComponent& cmp);
144  protected:
145  celix_bundle_context_t* context;
146  celix_dependency_manager_t* cDepMan;
147  celix_dm_component_t *cCmp;
148  std::string cmpUUID{};
149  std::string cmpName{};
150 
151  std::atomic<bool> cmpAddedToDepMan{false};
152 
153  std::mutex mutex{}; //protects below
154  std::vector<std::shared_ptr<BaseServiceDependency>> dependencies{};
155  std::vector<std::shared_ptr<BaseProvidedService>> providedServices{};
156  std::vector<std::shared_ptr<void>> componentContexts{};
157  };
158 
162  inline std::ostream& operator<<(std::ostream& out, const BaseComponent& cmp);
163 
164  template<class T>
165  class Component : public BaseComponent {
166  using type = T;
167  private:
168  std::mutex instanceMutex{};
169  std::unique_ptr<T> instance {nullptr};
170  std::shared_ptr<T> sharedInstance {nullptr};
171  std::vector<T> valInstance {};
172 
173  void (T::*initFp)() = {};
174  void (T::*startFp)() = {};
175  void (T::*stopFp)() = {};
176  void (T::*deinitFp)() = {};
177 
178  int (T::*initFpNoExc)() = {};
179  int (T::*startFpNoExc)() = {};
180  int (T::*stopFpNoExc)() = {};
181  int (T::*deinitFpNoExc)() = {};
182 
189  Component(celix_bundle_context_t *context, celix_dependency_manager_t* cDepMan, std::string name, std::string uuid);
190  public:
191  ~Component() override;
192 
198  static std::shared_ptr<Component<T>> create(celix_bundle_context_t*, celix_dependency_manager_t* cDepMan, std::string name, std::string uuid);
199 
205  bool isValid() const;
206 
213  T& getInstance();
214 
220  Component<T>& setInstance(std::shared_ptr<T> inst);
221 
227  Component<T>& setInstance(std::unique_ptr<T>&& inst);
228 
235  Component<T>& setInstance(T&& inst);
236 
245  template<class I> Component<T>& addInterfaceWithName(const std::string &serviceName, const std::string &version = std::string{}, const Properties &properties = Properties{});
246 
255  template<class I> Component<T>& addInterface(const std::string &version = std::string{}, const Properties &properties = Properties{});
256 
265  template<class I> Component<T>& addCInterface(I* svc, const std::string &serviceName, const std::string &version = std::string{}, const Properties &properties = Properties{});
266 
267 
276  template<class I> ProvidedService<T,I>& createProvidedCService(I* svc, std::string serviceName);
277 
287  template<class I> ProvidedService<T,I>& createProvidedService(std::string serviceName = {});
288 
300  template<class I> ProvidedService<T,I>& createUnassociatedProvidedService(std::shared_ptr<I> svc, std::string serviceName = {});
301 
310  template<class I> Component<T>& removeCInterface(const I* svc);
311 
312 
318  template<class I>
319  ServiceDependency<T,I>& createServiceDependency(const std::string &name = std::string{});
320 
326  template<class I>
328 
334  template<typename I>
335  CServiceDependency<T,I>& createCServiceDependency(const std::string &name);
336 
342  template<typename I>
344 
356  void (T::*init)(),
357  void (T::*start)(),
358  void (T::*stop)(),
359  void (T::*deinit)()
360  );
361 
374  int (T::*init)(),
375  int (T::*start)(),
376  int (T::*stop)(),
377  int (T::*deinit)()
378  );
379 
386 
387 
392  Component<T>& addContext(std::shared_ptr<void>);
393 
406  Component<T>& build();
407 
414  private:
419  int invokeLifecycleMethod(const std::string& methodName, void (T::*lifecycleMethod)());
420  };
421 }}
422 
423 #include "celix/dm/Component_Impl.h"
CELIX_DM_CMP_STATE_INITIALIZED_AND_WAITING_FOR_REQUIRED
@ CELIX_DM_CMP_STATE_INITIALIZED_AND_WAITING_FOR_REQUIRED
Definition: celix_dm_component.h:43
celix::dm::ProvidedService
Definition: ProvidedService.h:57
celix::dm::CServiceDependency
A service dependency for a component.
Definition: ServiceDependency.h:134
celix::dm::ComponentState::STOPPING
@ STOPPING
celix::dm::BaseComponent::getName
const std::string & getName() const
Definition: Component.h:90
celix_dmComponent_setImplementation
CELIX_FRAMEWORK_EXPORT celix_status_t celix_dmComponent_setImplementation(celix_dm_component_t *component, void *implementation)
celix::dm::ComponentState::DEINITIALIZING
@ DEINITIALIZING
celix::dm::ComponentState::INACTIVE
@ INACTIVE
types.h
celix::dm::ComponentState::INITIALIZING
@ INITIALIZING
celix::dm::BaseComponent::~BaseComponent
virtual ~BaseComponent() noexcept
celix::dm::Component::build
Component< T > & build()
Definition: Component_Impl.h:393
celix
Definition: Bundle.h:27
celix::dm::BaseComponent::bundleContext
celix_bundle_context_t * bundleContext() const
Definition: Component.h:78
celix::dm::Component::createProvidedService
ProvidedService< T, I > & createProvidedService(std::string serviceName={})
Creates a provided C++ services for the component.
Definition: Component_Impl.h:417
celix::dm::Component::addCInterface
Component< T > & addCInterface(I *svc, const std::string &serviceName, const std::string &version=std::string{}, const Properties &properties=Properties{})
Definition: Component_Impl.h:120
CELIX_DM_CMP_STATE_WAITING_FOR_REQUIRED
@ CELIX_DM_CMP_STATE_WAITING_FOR_REQUIRED
Definition: celix_dm_component.h:40
CELIX_DM_CMP_STATE_SUSPENDING
@ CELIX_DM_CMP_STATE_SUSPENDING
Definition: celix_dm_component.h:47
CELIX_DM_CMP_STATE_TRACKING_OPTIONAL
@ CELIX_DM_CMP_STATE_TRACKING_OPTIONAL
Definition: celix_dm_component.h:46
celix::dm::operator<<
std::ostream & operator<<(std::ostream &out, const BaseComponent &cmp)
Definition: Component_Impl.h:54
celix::dm::ComponentState::STARTING
@ STARTING
celix::dm::BaseComponent::context
celix_bundle_context_t * context
Definition: Component.h:145
CELIX_DM_CMP_STATE_SUSPENDED
@ CELIX_DM_CMP_STATE_SUSPENDED
Definition: celix_dm_component.h:48
celix::dm::BaseComponent::cmpAddedToDepMan
std::atomic< bool > cmpAddedToDepMan
Definition: Component.h:151
celix::dm::Component::addInterface
Component< T > & addInterface(const std::string &version=std::string{}, const Properties &properties=Properties{})
Definition: Component_Impl.h:104
celix::dm::Component::createServiceDependency
ServiceDependency< T, I > & createServiceDependency(const std::string &name=std::string{})
Definition: Component_Impl.h:147
celix::dm::ComponentState::TRACKING_OPTIONAL
@ TRACKING_OPTIONAL
celix::dm::BaseComponent::dependencies
std::vector< std::shared_ptr< BaseServiceDependency > > dependencies
Definition: Component.h:154
CELIX_DM_CMP_STATE_RESUMING
@ CELIX_DM_CMP_STATE_RESUMING
Definition: celix_dm_component.h:49
celix_dmComponent_getUUID
const CELIX_FRAMEWORK_EXPORT char * celix_dmComponent_getUUID(celix_dm_component_t *cmp)
celix::dm::Component::removeCInterface
Component< T > & removeCInterface(const I *svc)
Definition: Component_Impl.h:132
celix::dm::Component::buildAsync
Component< T > & buildAsync()
Definition: Component_Impl.h:400
celix::dm::Component::~Component
~Component() override
celix::dm::BaseComponent::runBuild
void runBuild()
Definition: Component_Impl.h:22
CELIX_DM_CMP_STATE_STARTING
@ CELIX_DM_CMP_STATE_STARTING
Definition: celix_dm_component.h:44
celix::dm::BaseComponent::getState
ComponentState getState() const
Definition: Component.h:97
celix::dm::BaseComponent::cmpName
std::string cmpName
Definition: Component.h:149
celix::dm::BaseComponent::cmpUUID
std::string cmpUUID
Definition: Component.h:148
celix::dm::ComponentState::RESUMING
@ RESUMING
Component_Impl.h
celix::dm::Component
Definition: Component.h:165
celix::dm::Component::create
static std::shared_ptr< Component< T > > create(celix_bundle_context_t *, celix_dependency_manager_t *cDepMan, std::string name, std::string uuid)
Definition: Component_Impl.h:184
celix::dm::ComponentState::SUSPENDING
@ SUSPENDING
celix::dm::BaseComponent::cComponent
celix_dm_component_t * cComponent() const
Definition: Component.h:73
celix::dm::Component::createCServiceDependency
CServiceDependency< T, I > & createCServiceDependency(const std::string &name)
Definition: Component_Impl.h:166
celix_dmComponent_currentState
CELIX_FRAMEWORK_EXPORT celix_dm_component_state_t celix_dmComponent_currentState(celix_dm_component_t *cmp)
celix::dm::BaseComponent::componentContexts
std::vector< std::shared_ptr< void > > componentContexts
Definition: Component.h:156
celix::dm::Component::addContext
Component< T > & addContext(std::shared_ptr< void >)
Add context to the component. This can be used to ensure a object lifespan at least matches that of t...
Definition: Component_Impl.h:386
celix::dm::Component::createUnassociatedProvidedService
ProvidedService< T, I > & createUnassociatedProvidedService(std::shared_ptr< I > svc, std::string serviceName={})
Creates a unassociated provided services for the component.
Definition: Component_Impl.h:440
celix::dm::BaseComponent::getUUID
const std::string & getUUID() const
Definition: Component.h:83
CELIX_DM_CMP_STATE_STOPPING
@ CELIX_DM_CMP_STATE_STOPPING
Definition: celix_dm_component.h:45
celix::dm::BaseComponent::operator<<
friend std::ostream & operator<<(std::ostream &out, const BaseComponent &cmp)
celix::dm::BaseComponent::cCmp
celix_dm_component_t * cCmp
Definition: Component.h:147
celix::dm::BaseComponent::providedServices
std::vector< std::shared_ptr< BaseProvidedService > > providedServices
Definition: Component.h:155
celix_dmComponent_getName
const CELIX_FRAMEWORK_EXPORT char * celix_dmComponent_getName(celix_dm_component_t *cmp)
celix::dm::ComponentState::INSTANTIATED_AND_WAITING_FOR_REQUIRED
@ INSTANTIATED_AND_WAITING_FOR_REQUIRED
celix_dm_component.h
celix::dm::BaseComponent::wait
void wait() const
Definition: Component_Impl.h:50
celix::dm::Component::remove
Component< T > & remove(ServiceDependency< T, I > &dep)
Definition: Component_Impl.h:157
ProvidedService.h
celix::dm::Component::setCallbacks
Component< T > & setCallbacks(void(T::*init)(), void(T::*start)(), void(T::*stop)(), void(T::*deinit)())
Definition: Component_Impl.h:291
celix_dmComponent_createWithUUID
CELIX_FRAMEWORK_EXPORT celix_dm_component_t * celix_dmComponent_createWithUUID(celix_bundle_context_t *context, const char *name, const char *UUID)
celix::dm::Component::createProvidedCService
ProvidedService< T, I > & createProvidedCService(I *svc, std::string serviceName)
Creates a provided C services the component.
Definition: Component_Impl.h:407
celix::dm::BaseComponent::cDepMan
celix_dependency_manager_t * cDepMan
Definition: Component.h:146
celix::dm::Component::removeCallbacks
Component< T > & removeCallbacks()
Definition: Component_Impl.h:380
celix::dm::ComponentState
ComponentState
Definition: Component.h:43
ServiceDependency.h
CELIX_DM_CMP_STATE_INITIALIZING
@ CELIX_DM_CMP_STATE_INITIALIZING
Definition: celix_dm_component.h:41
CELIX_DM_CMP_STATE_DEINITIALIZING
@ CELIX_DM_CMP_STATE_DEINITIALIZING
Definition: celix_dm_component.h:42
celix::dm::ComponentState::WAITING_FOR_REQUIRED
@ WAITING_FOR_REQUIRED
celix::dm::Properties
celix::Properties Properties
Definition: Properties.h:25
celix::dm::BaseComponent::BaseComponent
BaseComponent(celix_bundle_context_t *con, celix_dependency_manager_t *cdm, std::string name, std::string uuid)
Definition: Component.h:59
celix::dm::BaseComponent
Definition: Component.h:57
celix::dm::ServiceDependency
A service dependency for a component.
Definition: ServiceDependency.h:266
celix::dm::BaseComponent::mutex
std::mutex mutex
Definition: Component.h:153
celix::dm::Component::getInstance
T & getInstance()
Definition: Component_Impl.h:223
celix::dm::Component::addInterfaceWithName
Component< T > & addInterfaceWithName(const std::string &serviceName, const std::string &version=std::string{}, const Properties &properties=Properties{})
Definition: Component_Impl.h:84
celix::dm::Component::setInstance
Component< T > & setInstance(std::shared_ptr< T > inst)
Definition: Component_Impl.h:239
celix::dm::Component::isValid
bool isValid() const
Definition: Component_Impl.h:203
celix::dm::ComponentState::SUSPENDED
@ SUSPENDED