Apache Celix  latest
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 <cstdint>
27 #include <mutex>
28 #include <memory>
29 #include <iostream>
30 #include <type_traits>
31 #include <algorithm>
32 #include <cstdio>
33 
34 #include "celix_dm_component.h"
35 #include "celix/dm/types.h"
38 #include "celix_dependency_manager.h"
39 
40 
41 
42 namespace celix { namespace dm {
43 
44  enum class ComponentState : std::uint8_t {
45  INACTIVE = 1,
47  INITIALIZING = 3,
48  DEINITIALIZING = 4,
50  STARTING = 6,
51  STOPPING = 7,
53  SUSPENDING = 9,
54  SUSPENDED = 10,
55  RESUMING = 11,
56  };
57 
58  class BaseComponent {
59  public:
60  BaseComponent(celix_bundle_context_t *con, celix_dependency_manager_t* cdm, std::string name, std::string uuid) : context{con}, cDepMan{cdm}, cCmp{nullptr} {
61  this->cCmp = celix_dmComponent_createWithUUID(this->context, name.c_str(), uuid.empty() ? nullptr : uuid.c_str());
63  cmpUUID = std::string{celix_dmComponent_getUUID(this->cCmp)};
64  cmpName = std::string{celix_dmComponent_getName(this->cCmp)};
65  }
66  virtual ~BaseComponent() noexcept;
67 
68  BaseComponent(const BaseComponent&) = delete;
69  BaseComponent& operator=(const BaseComponent&) = delete;
70 
74  celix_dm_component_t* cComponent() const { return this->cCmp; }
75 
79  celix_bundle_context_t* bundleContext() const { return this->context; }
80 
84  const std::string& getUUID() const {
85  return cmpUUID;
86  }
87 
91  const std::string& getName() const {
92  return cmpName;
93  }
94 
99  auto cState = celix_dmComponent_currentState(cCmp);
100  switch (cState) {
121  default:
123  }
124  }
125 
135  void wait() const;
136 
142  void runBuild();
143 
144  friend std::ostream& operator<<(std::ostream& out, const BaseComponent& cmp);
145  protected:
146  celix_bundle_context_t* context;
147  celix_dependency_manager_t* cDepMan;
148  celix_dm_component_t *cCmp;
149  std::string cmpUUID{};
150  std::string cmpName{};
151 
152  std::atomic<bool> cmpAddedToDepMan{false};
153 
154  std::mutex mutex{}; //protects below
155  std::vector<std::shared_ptr<BaseServiceDependency>> dependencies{};
156  std::vector<std::shared_ptr<BaseProvidedService>> providedServices{};
157  std::vector<std::shared_ptr<void>> componentContexts{};
158  };
159 
163  inline std::ostream& operator<<(std::ostream& out, const BaseComponent& cmp);
164 
165  template<class T>
166  class Component : public BaseComponent {
167  using type = T;
168  private:
169  std::mutex instanceMutex{};
170  std::unique_ptr<T> instance {nullptr};
171  std::shared_ptr<T> sharedInstance {nullptr};
172  std::vector<T> valInstance {};
173 
174  void (T::*initFp)() = {};
175  void (T::*startFp)() = {};
176  void (T::*stopFp)() = {};
177  void (T::*deinitFp)() = {};
178 
179  int (T::*initFpNoExc)() = {};
180  int (T::*startFpNoExc)() = {};
181  int (T::*stopFpNoExc)() = {};
182  int (T::*deinitFpNoExc)() = {};
183 
190  Component(celix_bundle_context_t *context, celix_dependency_manager_t* cDepMan, std::string name, std::string uuid);
191  public:
192  ~Component() override;
193 
199  static std::shared_ptr<Component<T>> create(celix_bundle_context_t*, celix_dependency_manager_t* cDepMan, std::string name, std::string uuid);
200 
206  bool isValid() const;
207 
214  T& getInstance();
215 
221  Component<T>& setInstance(std::shared_ptr<T> inst);
222 
228  Component<T>& setInstance(std::unique_ptr<T>&& inst);
229 
236  Component<T>& setInstance(T&& inst);
237 
246  template<class I> Component<T>& addInterfaceWithName(const std::string &serviceName, const std::string &version = std::string{}, const Properties &properties = Properties{});
247 
256  template<class I> Component<T>& addInterface(const std::string &version = std::string{}, const Properties &properties = Properties{});
257 
266  template<class I> Component<T>& addCInterface(I* svc, const std::string &serviceName, const std::string &version = std::string{}, const Properties &properties = Properties{});
267 
268 
277  template<class I> ProvidedService<T,I>& createProvidedCService(I* svc, std::string serviceName);
278 
288  template<class I> ProvidedService<T,I>& createProvidedService(std::string serviceName = {});
289 
301  template<class I> ProvidedService<T,I>& createUnassociatedProvidedService(std::shared_ptr<I> svc, std::string serviceName = {});
302 
311  template<class I> Component<T>& removeCInterface(const I* svc);
312 
313 
319  template<class I>
320  ServiceDependency<T,I>& createServiceDependency(const std::string &name = std::string{});
321 
327  template<class I>
329 
335  template<typename I>
336  CServiceDependency<T,I>& createCServiceDependency(const std::string &name);
337 
343  template<typename I>
345 
357  void (T::*init)(),
358  void (T::*start)(),
359  void (T::*stop)(),
360  void (T::*deinit)()
361  );
362 
375  int (T::*init)(),
376  int (T::*start)(),
377  int (T::*stop)(),
378  int (T::*deinit)()
379  );
380 
387 
388 
393  Component<T>& addContext(std::shared_ptr<void>);
394 
407  Component<T>& build();
408 
415  private:
420  int invokeLifecycleMethod(const std::string& methodName, void (T::*lifecycleMethod)());
421  };
422 }}
423 
424 #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:44
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:91
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:28
celix::dm::BaseComponent::bundleContext
celix_bundle_context_t * bundleContext() const
Definition: Component.h:79
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:41
CELIX_DM_CMP_STATE_SUSPENDING
@ CELIX_DM_CMP_STATE_SUSPENDING
Definition: celix_dm_component.h:48
CELIX_DM_CMP_STATE_TRACKING_OPTIONAL
@ CELIX_DM_CMP_STATE_TRACKING_OPTIONAL
Definition: celix_dm_component.h:47
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:146
CELIX_DM_CMP_STATE_SUSPENDED
@ CELIX_DM_CMP_STATE_SUSPENDED
Definition: celix_dm_component.h:49
celix::dm::BaseComponent::cmpAddedToDepMan
std::atomic< bool > cmpAddedToDepMan
Definition: Component.h:152
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:155
CELIX_DM_CMP_STATE_RESUMING
@ CELIX_DM_CMP_STATE_RESUMING
Definition: celix_dm_component.h:50
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:45
celix::dm::BaseComponent::getState
ComponentState getState() const
Definition: Component.h:98
celix::dm::BaseComponent::cmpName
std::string cmpName
Definition: Component.h:150
celix::dm::BaseComponent::cmpUUID
std::string cmpUUID
Definition: Component.h:149
celix::dm::ComponentState::RESUMING
@ RESUMING
Component_Impl.h
celix::dm::Component
Definition: Component.h:166
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:74
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:157
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:84
CELIX_DM_CMP_STATE_STOPPING
@ CELIX_DM_CMP_STATE_STOPPING
Definition: celix_dm_component.h:46
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:148
celix::dm::BaseComponent::providedServices
std::vector< std::shared_ptr< BaseProvidedService > > providedServices
Definition: Component.h:156
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:147
celix::dm::Component::removeCallbacks
Component< T > & removeCallbacks()
Definition: Component_Impl.h:380
celix::dm::ComponentState
ComponentState
Definition: Component.h:44
ServiceDependency.h
CELIX_DM_CMP_STATE_INITIALIZING
@ CELIX_DM_CMP_STATE_INITIALIZING
Definition: celix_dm_component.h:42
CELIX_DM_CMP_STATE_DEINITIALIZING
@ CELIX_DM_CMP_STATE_DEINITIALIZING
Definition: celix_dm_component.h:43
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:60
celix::dm::BaseComponent
Definition: Component.h:58
celix::dm::ServiceDependency
A service dependency for a component.
Definition: ServiceDependency.h:260
celix::dm::BaseComponent::mutex
std::mutex mutex
Definition: Component.h:154
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