OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WMODULEFACTORY_H 00026 #define WMODULEFACTORY_H 00027 00028 #include <map> 00029 #include <set> 00030 #include <string> 00031 #include <utility> 00032 #include <vector> 00033 00034 #include <boost/shared_ptr.hpp> 00035 #include <boost/weak_ptr.hpp> 00036 00037 #include "../common/WSharedAssociativeContainer.h" 00038 #include "WModuleCombinerTypes.h" 00039 #include "WModule.h" 00040 #include "WModuleLoader.h" 00041 00042 /** 00043 * Class able to create a new copy of an arbitrary module. It uses the Factory and Prototype design pattern. 00044 */ 00045 class WModuleFactory // NOLINT 00046 { 00047 friend class WModuleFactoryTest; 00048 public: 00049 /** 00050 * Shared pointer to a WModule. 00051 */ 00052 typedef boost::shared_ptr< WModuleFactory > SPtr; 00053 00054 /** 00055 * Shared pointer to a const WModule. 00056 */ 00057 typedef boost::shared_ptr< const WModuleFactory > ConstSPtr; 00058 00059 /** 00060 * For shortening: a type defining a shared set of WModule pointers. 00061 */ 00062 typedef std::set< boost::shared_ptr< WModule > > PrototypeContainerType; 00063 00064 /** 00065 * Const iterator for the prototype set. 00066 */ 00067 typedef std::set< boost::shared_ptr< WModule > >::const_iterator PrototypeContainerConstIteratorType; 00068 00069 /** 00070 * Iterator for the prototype set. 00071 */ 00072 typedef std::set< boost::shared_ptr< WModule > >::iterator PrototypeContainerIteratorType; 00073 00074 /** 00075 * The alias for a shared container. 00076 */ 00077 typedef WSharedAssociativeContainer< PrototypeContainerType > PrototypeSharedContainerType; 00078 00079 /** 00080 * Destructor. 00081 */ 00082 virtual ~WModuleFactory(); 00083 00084 /** 00085 * Loads the modules and creates prototypes. 00086 */ 00087 void load(); 00088 00089 /** 00090 * Create a new and initialized module using the specified prototype. 00091 * 00092 * \param prototype the prototype to clone. 00093 * \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 00094 * useful for the project loader. 00095 * 00096 * \return the module created using the prototype. 00097 */ 00098 boost::shared_ptr< WModule > create( boost::shared_ptr< WModule > prototype, std::string uuid = "" ); 00099 00100 /** 00101 * Returns instance of the module factory to use to create modules. 00102 * 00103 * \return the running module factory. 00104 */ 00105 static SPtr getModuleFactory(); 00106 00107 /** 00108 * Returns instance of the module loader. 00109 * 00110 * \return the running module loader. 00111 */ 00112 static boost::shared_ptr< WModuleLoader > getModuleLoader(); 00113 00114 /** 00115 * Searches a prototype by name. It returns the prototype, or a NULL pointer if it is not found. The difference to 00116 * getPrototypeByName() is, that an unavailable prototype does not throw an exception. This is nice for checking whether a 00117 * prototype exists or not. 00118 * 00119 * \param name name of the prototype to search 00120 * 00121 * \return the prototype if it exists, or NULL if not. 00122 */ 00123 const boost::shared_ptr< WModule > isPrototypeAvailable( std::string name ); 00124 00125 /** 00126 * Finds a prototype using the specified name. 00127 * 00128 * \param name the name. 00129 * 00130 * \return the prototype whose name is equal to the specified one. 00131 */ 00132 const boost::shared_ptr< WModule > getPrototypeByName( std::string name ); 00133 00134 /** 00135 * Finds a prototype using an instance of a module. This uses the type_info to find a proper prototype. 00136 * 00137 * \param instance the instance to use. 00138 * 00139 * \return the prototype. 00140 * \throw WPrototypeUnknown if prototype can not be found. 00141 */ 00142 const boost::shared_ptr< WModule > getPrototypeByInstance( boost::shared_ptr< WModule > instance ); 00143 00144 /** 00145 * Finds a prototype using an type. 00146 * 00147 * \param type the type of module. 00148 * 00149 * \return the prototypes as list. 00150 */ 00151 std::vector< WModule::ConstSPtr > getPrototypesByType( MODULE_TYPE type ); 00152 00153 /** 00154 * This method gives read access to the list of all prototypes. 00155 * 00156 * \return the read ticket for the prototype list 00157 */ 00158 PrototypeSharedContainerType::ReadTicket getPrototypes() const; 00159 00160 /** 00161 * Checks whether the first instance can be casted to the second one. 00162 * 00163 * \param module the module to check. 00164 * 00165 * \return true if the dynamic_cast is successful 00166 */ 00167 template <typename T> 00168 static bool isA( boost::shared_ptr< WModule > module ); 00169 00170 /** 00171 * Returns a set of module combiners with module combinations compatible with the specified one. 00172 * 00173 * \param module the module to find the compatibles for. 00174 * 00175 * \note as the default parameter denotes, providing a NULL pointer (or calling the method without a parameter) returns the list of modules 00176 * which are compatible to every other module. In other words, it returns all modules without input connectors. If the specified module is 00177 * not NULL, the modules without input are not listed. 00178 * 00179 * \return set of compatible combiners. 00180 */ 00181 WCombinerTypes::WCompatiblesList getCompatiblePrototypes( 00182 boost::shared_ptr< WModule > module = boost::shared_ptr< WModule >() 00183 ); 00184 00185 /** 00186 * Creates a list of \ref WApplyCombiner for all modules known by the factory. 00187 * 00188 * \return list of apply combiner. 00189 */ 00190 WCombinerTypes::WCompatiblesList getAllPrototypes(); 00191 00192 /** 00193 * This method uses a newly created instance of WModule and initializes it properly. After using this method, the module is 00194 * properly initialized and ready to be used. 00195 * 00196 * \param module the module to initialize. 00197 */ 00198 static void initializeModule( boost::shared_ptr< WModule > module ); 00199 00200 /** 00201 * Checks whether the specified module is a prototype or an instantiated module. 00202 * 00203 * \param module the module to check 00204 * 00205 * \return true if it is a prototype 00206 */ 00207 static bool isPrototype( boost::shared_ptr< WModule > module ); 00208 00209 /** 00210 * Find a module instance by UUID. 00211 * 00212 * \param uuid the uuid to search for. 00213 * 00214 * \return the module, or NULL if not found 00215 */ 00216 static WModule::SPtr findByUUID( std::string uuid ); 00217 00218 protected: 00219 /** 00220 * Constructors are protected because this is a Singleton. 00221 */ 00222 WModuleFactory(); 00223 00224 /** 00225 * The module prototypes available. 00226 */ 00227 PrototypeSharedContainerType m_prototypes; 00228 00229 /** 00230 * Checks whether the specified module is a prototype or an instantiated module. Use isPrototype if no ticket acquired yet. 00231 * 00232 * \param module the module to check 00233 * \param ticket ticket which already has read lock. 00234 * 00235 * \return true if it is a prototype 00236 */ 00237 bool checkPrototype( boost::shared_ptr< WModule > module, PrototypeSharedContainerType::ReadTicket ticket ); 00238 00239 private: 00240 /** 00241 * Loader class managing dynamically loaded modules in OpenWalnut. 00242 */ 00243 WModuleLoader::SPtr m_moduleLoader; 00244 00245 /** 00246 * Singleton instance of WModuleFactory. 00247 */ 00248 static boost::shared_ptr< WModuleFactory > m_instance; 00249 00250 /** 00251 * Mapping between a UUID and a module. 00252 */ 00253 typedef std::map< std::string, boost::weak_ptr< WModule > > UuidModuleMap; 00254 00255 /** 00256 * Keep track of uuids of each created module. This is needed to find module pointers using uuid. 00257 */ 00258 WSharedAssociativeContainer< UuidModuleMap > m_uuidModuleMap; 00259 }; 00260 00261 template <typename T> 00262 bool WModuleFactory::isA( boost::shared_ptr< WModule > module ) 00263 { 00264 // NOTE: this is RTTI. Everybody says: do not use it. We ignore them. 00265 return ( dynamic_cast< T* >( module.get() ) ); // NOLINT 00266 } 00267 00268 #endif // WMODULEFACTORY_H 00269