OpenWalnut  1.3.1
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 <set>
29 #include <string>
30 #include <utility>
31 #include <vector>
32 
33 #include <boost/shared_ptr.hpp>
34 #include <boost/thread.hpp>
35 
36 #include "../common/WSharedAssociativeContainer.h"
37 #include "WModuleCombinerTypes.h"
38 #include "WModule.h"
39 #include "WModuleLoader.h"
40 
41 
42 
43 /**
44  * Class able to create a new copy of an arbitrary module. It uses the Factory and Prototype design pattern.
45  */
46 class WModuleFactory // NOLINT
47 {
48 friend class WModuleFactoryTest;
49 public:
50  /**
51  * For shortening: a type defining a shared set of WModule pointers.
52  */
53  typedef std::set< boost::shared_ptr< WModule > > PrototypeContainerType;
54 
55  /**
56  * Const iterator for the prototype set.
57  */
58  typedef std::set< boost::shared_ptr< WModule > >::const_iterator PrototypeContainerConstIteratorType;
59 
60  /**
61  * Iterator for the prototype set.
62  */
63  typedef std::set< boost::shared_ptr< WModule > >::iterator PrototypeContainerIteratorType;
64 
65  /**
66  * The alias for a shared container.
67  */
69 
70  /**
71  * Destructor.
72  */
73  virtual ~WModuleFactory();
74 
75  /**
76  * Loads the modules and creates prototypes.
77  */
78  void load();
79 
80  /**
81  * Create a new and initialized module using the specified prototype.
82  *
83  * \param prototype the prototype to clone.
84  *
85  * \return the module created using the prototype.
86  */
87  boost::shared_ptr< WModule > create( boost::shared_ptr< WModule > prototype );
88 
89  /**
90  * Returns instance of the module factory to use to create modules.
91  *
92  * \return the running module factory.
93  */
94  static boost::shared_ptr< WModuleFactory > getModuleFactory();
95 
96  /**
97  * Searches a prototype by name. It returns the prototype, or a NULL pointer if it is not found. The difference to
98  * getPrototypeByName() is, that an unavailable prototype does not throw an exception. This is nice for checking whether a
99  * prototype exists or not.
100  *
101  * \param name name of the prototype to search
102  *
103  * \return the prototype if it exists, or NULL if not.
104  */
105  const boost::shared_ptr< WModule > isPrototypeAvailable( std::string name );
106 
107  /**
108  * Finds a prototype using the specified name.
109  *
110  * \param name the name.
111  *
112  * \return the prototype whose name is equal to the specified one.
113  */
114  const boost::shared_ptr< WModule > getPrototypeByName( std::string name );
115 
116  /**
117  * Finds a prototype using an instance of a module. This uses the type_info to find a proper prototype.
118  *
119  * \param instance the instance to use.
120  *
121  * \return the prototype.
122  * \throw WPrototypeUnknown if prototype can not be found.
123  */
124  const boost::shared_ptr< WModule > getPrototypeByInstance( boost::shared_ptr< WModule > instance );
125 
126  /**
127  * Finds a prototype using an type.
128  *
129  * \param type the type of module.
130  *
131  * \return the prototypes as list.
132  */
133  std::vector< WModule::ConstSPtr > getPrototypesByType( MODULE_TYPE type );
134 
135  /**
136  * This method gives read access to the list of all prototypes.
137  *
138  * \return the read ticket for the prototype list
139  */
141 
142  /**
143  * Checks whether the first instance can be casted to the second one.
144  *
145  * \param module the module to check.
146  *
147  * \return true if the dynamic_cast is successful
148  */
149  template <typename T>
150  static bool isA( boost::shared_ptr< WModule > module );
151 
152  /**
153  * Returns a set of module combiners with module combinations compatible with the specified one.
154  *
155  * \param module the module to find the compatibles for.
156  *
157  * \note as the default parameter denotes, providing a NULL pointer (or calling the method without a parameter) returns the list of modules
158  * which are compatible to every other module. In other words, it returns all modules without input connectors. If the specified module is
159  * not NULL, the modules without input are not listed.
160  *
161  * \return set of compatible combiners.
162  */
163  WCombinerTypes::WCompatiblesList getCompatiblePrototypes(
164  boost::shared_ptr< WModule > module = boost::shared_ptr< WModule >()
165  );
166 
167  /**
168  * Creates a list of \ref WApplyCombiner for all modules known by the factory.
169  *
170  * \return list of apply combiner.
171  */
172  WCombinerTypes::WCompatiblesList getAllPrototypes();
173 
174  /**
175  * This method uses a newly created instance of WModule and initializes it properly. After using this method, the module is
176  * properly initialized and ready to be used.
177  *
178  * \param module the module to initialize.
179  */
180  static void initializeModule( boost::shared_ptr< WModule > module );
181 
182  /**
183  * Checks whether the specified module is a prototype or an instantiated module.
184  *
185  * \param module the module to check
186  *
187  * \return true if it is a prototype
188  */
189  static bool isPrototype( boost::shared_ptr< WModule > module );
190 
191 protected:
192  /**
193  * Constructors are protected because this is a Singleton.
194  */
195  WModuleFactory();
196 
197  /**
198  * The module prototypes available.
199  */
201 
202  /**
203  * Checks whether the specified module is a prototype or an instantiated module. Use isPrototype if no ticket acquired yet.
204  *
205  * \param module the module to check
206  * \param ticket ticket which already has read lock.
207  *
208  * \return true if it is a prototype
209  */
210  bool checkPrototype( boost::shared_ptr< WModule > module, PrototypeSharedContainerType::ReadTicket ticket );
211 
212 private:
213  /**
214  * Loader class managing dynamically loaded modules in OpenWalnut.
215  */
217 
218  /**
219  * Singleton instance of WModuleFactory.
220  */
221  static boost::shared_ptr< WModuleFactory > m_instance;
222 };
223 
224 template <typename T>
225 bool WModuleFactory::isA( boost::shared_ptr< WModule > module )
226 {
227  // NOTE: this is RTTI. Everybody says: do not use it. We ignore them.
228  return ( dynamic_cast< T* >( module.get() ) ); // NOLINT
229 }
230 
231 #endif // WMODULEFACTORY_H
232