Apache Celix  2.3.0
An implementation of the OSGi specification adapted to C and C++
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 "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 {
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 
132  void wait() const;
133 
139  void runBuild();
140 
141  friend std::ostream& operator<<(std::ostream& out, const BaseComponent& cmp);
142  protected:
143  celix_bundle_context_t* context;
144  celix_dependency_manager_t* cDepMan;
145  celix_dm_component_t *cCmp;
146  std::string cmpUUID{};
147  std::string cmpName{};
148 
149  std::atomic<bool> cmpAddedToDepMan{false};
150 
151  std::mutex mutex{}; //protects below
152  std::vector<std::shared_ptr<BaseServiceDependency>> dependencies{};
153  std::vector<std::shared_ptr<BaseProvidedService>> providedServices{};
154  std::vector<std::shared_ptr<void>> componentContexts{};
155  };
156 
160  inline std::ostream& operator<<(std::ostream& out, const BaseComponent& cmp);
161 
162  template<class T>
163  class Component : public BaseComponent {
164  using type = T;
165  private:
166  std::mutex instanceMutex{};
167  std::unique_ptr<T> instance {nullptr};
168  std::shared_ptr<T> sharedInstance {nullptr};
169  std::vector<T> valInstance {};
170 
171  void (T::*initFp)() = {};
172  void (T::*startFp)() = {};
173  void (T::*stopFp)() = {};
174  void (T::*deinitFp)() = {};
175 
176  int (T::*initFpNoExc)() = {};
177  int (T::*startFpNoExc)() = {};
178  int (T::*stopFpNoExc)() = {};
179  int (T::*deinitFpNoExc)() = {};
180 
187  Component(celix_bundle_context_t *context, celix_dependency_manager_t* cDepMan, std::string name, std::string uuid);
188  public:
189  ~Component() override;
190 
196  static std::shared_ptr<Component<T>> create(celix_bundle_context_t*, celix_dependency_manager_t* cDepMan, std::string name, std::string uuid);
197 
203  bool isValid() const;
204 
211  T& getInstance();
212 
218  Component<T>& setInstance(std::shared_ptr<T> inst);
219 
225  Component<T>& setInstance(std::unique_ptr<T>&& inst);
226 
233  Component<T>& setInstance(T&& inst);
234 
243  template<class I> Component<T>& addInterfaceWithName(const std::string &serviceName, const std::string &version = std::string{}, const Properties &properties = Properties{});
244 
253  template<class I> Component<T>& addInterface(const std::string &version = std::string{}, const Properties &properties = Properties{});
254 
263  template<class I> Component<T>& addCInterface(I* svc, const std::string &serviceName, const std::string &version = std::string{}, const Properties &properties = Properties{});
264 
265 
274  template<class I> ProvidedService<T,I>& createProvidedCService(I* svc, std::string serviceName);
275 
285  template<class I> ProvidedService<T,I>& createProvidedService(std::string serviceName = {});
286 
298  template<class I> ProvidedService<T,I>& createUnassociatedProvidedService(std::shared_ptr<I> svc, std::string serviceName = {});
299 
308  template<class I> Component<T>& removeCInterface(const I* svc);
309 
310 
316  template<class I>
317  ServiceDependency<T,I>& createServiceDependency(const std::string &name = std::string{});
318 
324  template<class I>
326 
332  template<typename I>
333  CServiceDependency<T,I>& createCServiceDependency(const std::string &name);
334 
340  template<typename I>
342 
354  void (T::*init)(),
355  void (T::*start)(),
356  void (T::*stop)(),
357  void (T::*deinit)()
358  );
359 
372  int (T::*init)(),
373  int (T::*start)(),
374  int (T::*stop)(),
375  int (T::*deinit)()
376  );
377 
384 
385 
390  Component<T>& addContext(std::shared_ptr<void>);
391 
404  Component<T>& build();
405 
412  private:
417  int invokeLifecycleMethod(const std::string& methodName, void (T::*lifecycleMethod)());
418  };
419 }}
420 
421 #include "celix/dm/Component_Impl.h"
celix::dm::ComponentState::INITIALIZING
@ INITIALIZING
celix::dm::ComponentState::STOPPING
@ STOPPING
CELIX_DM_CMP_STATE_INITIALIZED_AND_WAITING_FOR_REQUIRED
@ CELIX_DM_CMP_STATE_INITIALIZED_AND_WAITING_FOR_REQUIRED
Definition: celix_dm_component.h:42
celix::dm::ProvidedService
Definition: ProvidedService.h:57
celix::dm::CServiceDependency
A service dependency for a component.
Definition: ServiceDependency.h:134
celix::dm::ComponentState::WAITING_FOR_REQUIRED
@ WAITING_FOR_REQUIRED
celix::dm::BaseComponent::getName
const std::string & getName() const
Definition: Component.h:90
types.h
celix::dm::ComponentState::DEINITIALIZING
@ DEINITIALIZING
celix::dm::BaseComponent::~BaseComponent
virtual ~BaseComponent() noexcept
celix::dm::Component::build
Component< T > & build()
Definition: Component_Impl.h:393
celix
Definition: Bundle.h:26
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:39
celix::dm::ComponentState::SUSPENDING
@ SUSPENDING
CELIX_DM_CMP_STATE_SUSPENDING
@ CELIX_DM_CMP_STATE_SUSPENDING
Definition: celix_dm_component.h:46
CELIX_DM_CMP_STATE_TRACKING_OPTIONAL
@ CELIX_DM_CMP_STATE_TRACKING_OPTIONAL
Definition: celix_dm_component.h:45
celix::dm::operator<<
std::ostream & operator<<(std::ostream &out, const BaseComponent &cmp)
Definition: Component_Impl.h:54
celix_dmComponent_createWithUUID
celix_dm_component_t * celix_dmComponent_createWithUUID(celix_bundle_context_t *context, const char *name, const char *UUID)
celix::dm::BaseComponent::context
celix_bundle_context_t * context
Definition: Component.h:143
CELIX_DM_CMP_STATE_SUSPENDED
@ CELIX_DM_CMP_STATE_SUSPENDED
Definition: celix_dm_component.h:47
celix::dm::BaseComponent::cmpAddedToDepMan
std::atomic< bool > cmpAddedToDepMan
Definition: Component.h:149
celix::dm::Component::addInterface
Component< T > & addInterface(const std::string &version=std::string{}, const Properties &properties=Properties{})
Definition: Component_Impl.h:104
celix_dmComponent_currentState
celix_dm_component_state_t celix_dmComponent_currentState(celix_dm_component_t *cmp)
celix::dm::Component::createServiceDependency
ServiceDependency< T, I > & createServiceDependency(const std::string &name=std::string{})
Definition: Component_Impl.h:147
celix_dmComponent_setImplementation
celix_status_t celix_dmComponent_setImplementation(celix_dm_component_t *component, void *implementation)
celix::dm::BaseComponent::dependencies
std::vector< std::shared_ptr< BaseServiceDependency > > dependencies
Definition: Component.h:152
CELIX_DM_CMP_STATE_RESUMING
@ CELIX_DM_CMP_STATE_RESUMING
Definition: celix_dm_component.h:48
celix::dm::ComponentState::STARTING
@ STARTING
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::ComponentState
ComponentState
Definition: Component.h:43
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:43
celix::dm::BaseComponent::getState
ComponentState getState() const
Definition: Component.h:97
celix::dm::BaseComponent::cmpName
std::string cmpName
Definition: Component.h:147
celix::dm::BaseComponent::cmpUUID
std::string cmpUUID
Definition: Component.h:146
Component_Impl.h
celix::dm::ComponentState::SUSPENDED
@ SUSPENDED
celix::dm::ComponentState::INACTIVE
@ INACTIVE
celix::dm::Component
Definition: Component.h:163
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::INSTANTIATED_AND_WAITING_FOR_REQUIRED
@ INSTANTIATED_AND_WAITING_FOR_REQUIRED
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::dm::ComponentState::TRACKING_OPTIONAL
@ TRACKING_OPTIONAL
celix::dm::BaseComponent::componentContexts
std::vector< std::shared_ptr< void > > componentContexts
Definition: Component.h:154
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_dmComponent_getUUID
const char * celix_dmComponent_getUUID(celix_dm_component_t *cmp)
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:44
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:145
celix::dm::BaseComponent::providedServices
std::vector< std::shared_ptr< BaseProvidedService > > providedServices
Definition: Component.h:153
celix::dm::BaseComponent::wait
void wait() const
Definition: Component_Impl.h:50
celix_dmComponent_getName
const char * celix_dmComponent_getName(celix_dm_component_t *cmp)
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::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:144
celix::dm::Component::removeCallbacks
Component< T > & removeCallbacks()
Definition: Component_Impl.h:380
ServiceDependency.h
celix::dm::ComponentState::RESUMING
@ RESUMING
CELIX_DM_CMP_STATE_INITIALIZING
@ CELIX_DM_CMP_STATE_INITIALIZING
Definition: celix_dm_component.h:40
CELIX_DM_CMP_STATE_DEINITIALIZING
@ CELIX_DM_CMP_STATE_DEINITIALIZING
Definition: celix_dm_component.h:41
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:151
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