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