OpenWalnut  1.4.0
WModuleFactory.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WMODULEFACTORY_H
26 #define WMODULEFACTORY_H
27 
28 #include <map>
29 #include <set>
30 #include <string>
31 #include <utility>
32 #include <vector>
33 
34 #include <boost/shared_ptr.hpp>
35 #include <boost/weak_ptr.hpp>
36 
37 #include "../common/WSharedAssociativeContainer.h"
38 #include "WModuleCombinerTypes.h"
39 #include "WModule.h"
40 #include "WModuleLoader.h"
41 
42 /**
43  * Class able to create a new copy of an arbitrary module. It uses the Factory and Prototype design pattern.
44  */
45 class WModuleFactory // NOLINT
46 {
47 friend class WModuleFactoryTest;
48 public:
49  /**
50  * Shared pointer to a WModule.
51  */
52  typedef boost::shared_ptr< WModuleFactory > SPtr;
53 
54  /**
55  * Shared pointer to a const WModule.
56  */
57  typedef boost::shared_ptr< const WModuleFactory > ConstSPtr;
58 
59  /**
60  * For shortening: a type defining a shared set of WModule pointers.
61  */
62  typedef std::set< boost::shared_ptr< WModule > > PrototypeContainerType;
63 
64  /**
65  * Const iterator for the prototype set.
66  */
67  typedef std::set< boost::shared_ptr< WModule > >::const_iterator PrototypeContainerConstIteratorType;
68 
69  /**
70  * Iterator for the prototype set.
71  */
72  typedef std::set< boost::shared_ptr< WModule > >::iterator PrototypeContainerIteratorType;
73 
74  /**
75  * The alias for a shared container.
76  */
78 
79  /**
80  * Destructor.
81  */
82  virtual ~WModuleFactory();
83 
84  /**
85  * Loads the modules and creates prototypes.
86  */
87  void load();
88 
89  /**
90  * Create a new and initialized module using the specified prototype.
91  *
92  * \param prototype the prototype to clone.
93  * \param uuid the uuid to use for the created module. If you specify an empty string (default), a uuid will be created. This parameter is
94  * useful for the project loader.
95  *
96  * \return the module created using the prototype.
97  */
98  boost::shared_ptr< WModule > create( boost::shared_ptr< WModule > prototype, std::string uuid = "" );
99 
100  /**
101  * Returns instance of the module factory to use to create modules.
102  *
103  * \return the running module factory.
104  */
105  static SPtr getModuleFactory();
106 
107  /**
108  * Returns instance of the module loader.
109  *
110  * \return the running module loader.
111  */
112  static boost::shared_ptr< WModuleLoader > getModuleLoader();
113 
114  /**
115  * Searches a prototype by name. It returns the prototype, or a NULL pointer if it is not found. The difference to
116  * getPrototypeByName() is, that an unavailable prototype does not throw an exception. This is nice for checking whether a
117  * prototype exists or not.
118  *
119  * \param name name of the prototype to search
120  *
121  * \return the prototype if it exists, or NULL if not.
122  */
123  const boost::shared_ptr< WModule > isPrototypeAvailable( std::string name );
124 
125  /**
126  * Finds a prototype using the specified name.
127  *
128  * \param name the name.
129  *
130  * \return the prototype whose name is equal to the specified one.
131  */
132  const boost::shared_ptr< WModule > getPrototypeByName( std::string name );
133 
134  /**
135  * Finds a prototype using an instance of a module. This uses the type_info to find a proper prototype.
136  *
137  * \param instance the instance to use.
138  *
139  * \return the prototype.
140  * \throw WPrototypeUnknown if prototype can not be found.
141  */
142  const boost::shared_ptr< WModule > getPrototypeByInstance( boost::shared_ptr< WModule > instance );
143 
144  /**
145  * Finds a prototype using an type.
146  *
147  * \param type the type of module.
148  *
149  * \return the prototypes as list.
150  */
151  std::vector< WModule::ConstSPtr > getPrototypesByType( MODULE_TYPE type );
152 
153  /**
154  * This method gives read access to the list of all prototypes.
155  *
156  * \return the read ticket for the prototype list
157  */
159 
160  /**
161  * Checks whether the first instance can be casted to the second one.
162  *
163  * \param module the module to check.
164  *
165  * \return true if the dynamic_cast is successful
166  */
167  template <typename T>
168  static bool isA( boost::shared_ptr< WModule > module );
169 
170  /**
171  * Returns a set of module combiners with module combinations compatible with the specified one.
172  *
173  * \param module the module to find the compatibles for.
174  *
175  * \note as the default parameter denotes, providing a NULL pointer (or calling the method without a parameter) returns the list of modules
176  * which are compatible to every other module. In other words, it returns all modules without input connectors. If the specified module is
177  * not NULL, the modules without input are not listed.
178  *
179  * \return set of compatible combiners.
180  */
181  WCombinerTypes::WCompatiblesList getCompatiblePrototypes(
182  boost::shared_ptr< WModule > module = boost::shared_ptr< WModule >()
183  );
184 
185  /**
186  * Creates a list of \ref WApplyCombiner for all modules known by the factory.
187  *
188  * \return list of apply combiner.
189  */
190  WCombinerTypes::WCompatiblesList getAllPrototypes();
191 
192  /**
193  * This method uses a newly created instance of WModule and initializes it properly. After using this method, the module is
194  * properly initialized and ready to be used.
195  *
196  * \param module the module to initialize.
197  */
198  static void initializeModule( boost::shared_ptr< WModule > module );
199 
200  /**
201  * Checks whether the specified module is a prototype or an instantiated module.
202  *
203  * \param module the module to check
204  *
205  * \return true if it is a prototype
206  */
207  static bool isPrototype( boost::shared_ptr< WModule > module );
208 
209  /**
210  * Find a module instance by UUID.
211  *
212  * \param uuid the uuid to search for.
213  *
214  * \return the module, or NULL if not found
215  */
216  static WModule::SPtr findByUUID( std::string uuid );
217 
218 protected:
219  /**
220  * Constructors are protected because this is a Singleton.
221  */
222  WModuleFactory();
223 
224  /**
225  * The module prototypes available.
226  */
227  PrototypeSharedContainerType m_prototypes;
228 
229  /**
230  * Checks whether the specified module is a prototype or an instantiated module. Use isPrototype if no ticket acquired yet.
231  *
232  * \param module the module to check
233  * \param ticket ticket which already has read lock.
234  *
235  * \return true if it is a prototype
236  */
237  bool checkPrototype( boost::shared_ptr< WModule > module, PrototypeSharedContainerType::ReadTicket ticket );
238 
239 private:
240  /**
241  * Loader class managing dynamically loaded modules in OpenWalnut.
242  */
244 
245  /**
246  * Singleton instance of WModuleFactory.
247  */
248  static boost::shared_ptr< WModuleFactory > m_instance;
249 
250  /**
251  * Mapping between a UUID and a module.
252  */
253  typedef std::map< std::string, boost::weak_ptr< WModule > > UuidModuleMap;
254 
255  /**
256  * Keep track of uuids of each created module. This is needed to find module pointers using uuid.
257  */
259 };
260 
261 template <typename T>
262 bool WModuleFactory::isA( boost::shared_ptr< WModule > module )
263 {
264  // NOTE: this is RTTI. Everybody says: do not use it. We ignore them.
265  return ( dynamic_cast< T* >( module.get() ) ); // NOLINT
266 }
267 
268 #endif // WMODULEFACTORY_H
269 
std::set< boost::shared_ptr< WModule > > PrototypeContainerType
For shortening: a type defining a shared set of WModule pointers.
const boost::shared_ptr< WModule > getPrototypeByInstance(boost::shared_ptr< WModule > instance)
Finds a prototype using an instance of a module.
const boost::shared_ptr< WModule > getPrototypeByName(std::string name)
Finds a prototype using the specified name.
WCombinerTypes::WCompatiblesList getAllPrototypes()
Creates a list of WApplyCombiner for all modules known by the factory.
Class able to create a new copy of an arbitrary module.
static bool isA(boost::shared_ptr< WModule > module)
Checks whether the first instance can be casted to the second one.
std::set< boost::shared_ptr< WModule > >::iterator PrototypeContainerIteratorType
Iterator for the prototype set.
WSharedAssociativeContainer< PrototypeContainerType > PrototypeSharedContainerType
The alias for a shared container.
static boost::shared_ptr< WModuleFactory > m_instance
Singleton instance of WModuleFactory.
boost::shared_ptr< const WModuleFactory > ConstSPtr
Shared pointer to a const WModule.
boost::shared_ptr< WModule > create(boost::shared_ptr< WModule > prototype, std::string uuid="")
Create a new and initialized module using the specified prototype.
static bool isPrototype(boost::shared_ptr< WModule > module)
Checks whether the specified module is a prototype or an instantiated module.
WModuleLoader::SPtr m_moduleLoader
Loader class managing dynamically loaded modules in OpenWalnut.
static boost::shared_ptr< WModuleLoader > getModuleLoader()
Returns instance of the module loader.
static WModule::SPtr findByUUID(std::string uuid)
Find a module instance by UUID.
boost::shared_ptr< WModuleFactory > SPtr
Shared pointer to a WModule.
PrototypeSharedContainerType::ReadTicket getPrototypes() const
This method gives read access to the list of all prototypes.
virtual ~WModuleFactory()
Destructor.
WModuleFactory()
Constructors are protected because this is a Singleton.
boost::shared_ptr< WModule > SPtr
Shared pointer to a WModule.
Definition: WModule.h:109
static SPtr getModuleFactory()
Returns instance of the module factory to use to create modules.
static void initializeModule(boost::shared_ptr< WModule > module)
This method uses a newly created instance of WModule and initializes it properly. ...
std::vector< WModule::ConstSPtr > getPrototypesByType(MODULE_TYPE type)
Finds a prototype using an type.
std::set< boost::shared_ptr< WModule > >::const_iterator PrototypeContainerConstIteratorType
Const iterator for the prototype set.
WSharedAssociativeContainer< UuidModuleMap > m_uuidModuleMap
Keep track of uuids of each created module.
boost::shared_ptr< WModuleLoader > SPtr
Shared pointer abbreviation.
Definition: WModuleLoader.h:49
void load()
Loads the modules and creates prototypes.
PrototypeSharedContainerType m_prototypes
The module prototypes available.
const boost::shared_ptr< WModule > isPrototypeAvailable(std::string name)
Searches a prototype by name.
std::map< std::string, boost::weak_ptr< WModule > > UuidModuleMap
Mapping between a UUID and a module.
bool checkPrototype(boost::shared_ptr< WModule > module, PrototypeSharedContainerType::ReadTicket ticket)
Checks whether the specified module is a prototype or an instantiated module.
boost::shared_ptr< WSharedObjectTicketRead< PrototypeContainerType > > ReadTicket
Type for read tickets.
Definition: WSharedObject.h:62
WCombinerTypes::WCompatiblesList getCompatiblePrototypes(boost::shared_ptr< WModule > module=boost::shared_ptr< WModule >())
Returns a set of module combiners with module combinations compatible with the specified one...