Caffa  1.1.0
C++ Application Framework for Embedded Systems with introspection
cafRestServiceFactory.h
1 // ##################################################################################################
2 //
3 // Custom Visualization Core library
4 // Copyright (C) 2011-2013 Ceetron AS
5 // Changes since 2024:
6 // Copyright (C) 2024- Kontur AS
7 //
8 // GNU Lesser General Public License Usage
9 // This library is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU Lesser General Public License as published by
11 // the Free Software Foundation; either version 2.1 of the License, or
12 // (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful, but WITHOUT ANY
15 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 // FITNESS FOR A PARTICULAR PURPOSE.
17 //
18 // See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
19 // for more details.
20 //
21 // ##################################################################################################
22 
23 #pragma once
24 
25 #include "cafAssert.h"
26 
27 #include <cstddef>
28 #include <map>
29 #include <memory>
30 #include <vector>
31 
32 // Taken from gtest.h
33 //
34 // Due to C++ preprocessor weirdness, we need double indirection to
35 // concatenate two tokens when one of them is __LINE__. Writing
36 //
37 // foo ## __LINE__
38 //
39 // will result in the token foo__LINE__, instead of foo followed by
40 // the current line number. For more details, see
41 // http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
42 #define CAFFA_FACTORY_CONCATENATE_STRINGS( foo, bar ) CAFFA_FACTORY_CONCATENATE_STRINGS_IMPL_( foo, bar )
43 #define CAFFA_FACTORY_CONCATENATE_STRINGS_IMPL_( foo, bar ) foo##bar
44 
45 #define CAFFA_UNIQUE_COMPILE_UNIT_VAR_NAME( foo ) CAFFA_FACTORY_CONCATENATE_STRINGS( foo, __LINE__ )
46 
49 
50 #define CAFFA_FACTORY_REGISTER( BaseType, TypeToCreate, KeyType, key ) \
51  static bool CAFFA_UNIQUE_COMPILE_UNIT_VAR_NAME( my##TypeToCreate ) = \
52  caffa::RestServiceFactory<BaseType, KeyType>::instance() -> registerCreator<TypeToCreate>( key )
53 #define CAFFA_FACTORY_REGISTER2( BaseType, TypeToCreate, KeyType, key ) \
54  static bool CAFFA_UNIQUE_COMPILE_UNIT_VAR_NAME( my2##TypeToCreate ) = \
55  caffa::RestServiceFactory<BaseType, KeyType>::instance() -> registerCreator<TypeToCreate>( key )
56 
57 namespace caffa
58 {
59 template <typename BaseType, typename KeyType>
61 {
62  class ObjectCreatorBase;
63 
64 public:
65  static RestServiceFactory<BaseType, KeyType>* instance()
66  {
68  return fact;
69  }
70 
71  template <typename TypeToCreate>
72  bool registerCreator( const KeyType& key )
73  {
74  auto entryIt = m_factoryMap.find( key );
75  if ( entryIt == m_factoryMap.end() )
76  {
77  m_factoryMap[key] = std::make_unique<ObjectCreator<TypeToCreate>>();
78  return true;
79  }
80  return false;
81  }
82 
83  std::shared_ptr<BaseType> create( const KeyType& key )
84  {
85  auto entryIt = m_factoryMap.find( key );
86  if ( entryIt != m_factoryMap.end() )
87  {
88  return entryIt->second->create();
89  }
90  else
91  {
92  return nullptr;
93  }
94  }
95 
96  std::vector<KeyType> allKeys()
97  {
98  std::vector<KeyType> keys;
99 
100  for ( auto entryIt = m_factoryMap.begin(); entryIt != m_factoryMap.end(); ++entryIt )
101  {
102  keys.push_back( entryIt->first );
103  }
104 
105  return keys;
106  }
107 
108 private:
109  RestServiceFactory() {}
110  ~RestServiceFactory() = default;
111 
112  // Internal helper classes
113 
114  class ObjectCreatorBase
115  {
116  public:
117  ObjectCreatorBase() {}
118  virtual ~ObjectCreatorBase() {}
119  virtual std::shared_ptr<BaseType> create() = 0;
120  };
121 
122  template <typename TypeToCreate>
123  class ObjectCreator : public ObjectCreatorBase
124  {
125  public:
126  std::shared_ptr<BaseType> create() override { return std::make_shared<TypeToCreate>(); }
127  };
128 
129  // Map to store factory
130  std::map<KeyType, std::unique_ptr<ObjectCreatorBase>> m_factoryMap;
131 };
132 
133 } // End of namespace caffa
Definition: cafRestServiceFactory.h:60
Main Caffa namespace.
Definition: cafApplication.h:30