OpenWalnut 1.2.5

WModuleFactory.h

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 <set>
00029 #include <string>
00030 #include <utility>
00031 #include <vector>
00032 
00033 #include <boost/shared_ptr.hpp>
00034 #include <boost/thread.hpp>
00035 
00036 #include "../common/WSharedAssociativeContainer.h"
00037 #include "WModuleCombinerTypes.h"
00038 #include "WModule.h"
00039 #include "WModuleLoader.h"
00040 
00041 #include "WExportKernel.h"
00042 
00043 /**
00044  * Class able to create a new copy of an arbitrary module. It uses the Factory and Prototype design pattern.
00045  */
00046 class OWKERNEL_EXPORT WModuleFactory // NOLINT
00047 {
00048 friend class WModuleFactoryTest;
00049 public:
00050 
00051     /**
00052      * For shortening: a type defining a shared set of WModule pointers.
00053      */
00054     typedef std::set< boost::shared_ptr< WModule > > PrototypeContainerType;
00055 
00056     /**
00057      * Const iterator for the prototype set.
00058      */
00059     typedef std::set< boost::shared_ptr< WModule > >::const_iterator PrototypeContainerConstIteratorType;
00060 
00061     /**
00062      * Iterator for the prototype set.
00063      */
00064     typedef std::set< boost::shared_ptr< WModule > >::iterator PrototypeContainerIteratorType;
00065 
00066     /**
00067      * The alias for a shared container.
00068      */
00069     typedef WSharedAssociativeContainer< PrototypeContainerType > PrototypeSharedContainerType;
00070 
00071     /**
00072      * Destructor.
00073      */
00074     virtual ~WModuleFactory();
00075 
00076     /**
00077      * Loads the modules and creates prototypes.
00078      */
00079     void load();
00080 
00081     /**
00082      * Create a new and initialized module using the specified prototype.
00083      *
00084      * \param prototype the prototype to clone.
00085      *
00086      * \return the module created using the prototype.
00087      */
00088     boost::shared_ptr< WModule > create( boost::shared_ptr< WModule > prototype );
00089 
00090     /**
00091      * Returns instance of the module factory to use to create modules.
00092      *
00093      * \return the running module factory.
00094      */
00095     static boost::shared_ptr< WModuleFactory > getModuleFactory();
00096 
00097     /**
00098      * Searches a prototype by name. It returns the prototype, or a NULL pointer if it is not found. The difference to
00099      * getPrototypeByName() is, that an unavailable prototype does not throw an exception. This is nice for checking whether a
00100      * prototype exists or not.
00101      *
00102      * \param name name of the prototype to search
00103      *
00104      * \return the prototype if it exists, or NULL if not.
00105      */
00106     const boost::shared_ptr< WModule > isPrototypeAvailable( std::string name );
00107 
00108     /**
00109      * Finds a prototype using the specified name.
00110      *
00111      * \param name the name.
00112      *
00113      * \return the prototype whose name is equal to the specified one.
00114      */
00115     const boost::shared_ptr< WModule > getPrototypeByName( std::string name );
00116 
00117     /**
00118      * Finds a prototype using an instance of a module. This uses the type_info to find a proper prototype.
00119      *
00120      * \param instance the instance to use.
00121      *
00122      * \return the prototype.
00123      * \throw WPrototypeUnknown if prototype can not be found.
00124      */
00125     const boost::shared_ptr< WModule > getPrototypeByInstance( boost::shared_ptr< WModule > instance );
00126 
00127     /**
00128      * Finds a prototype using an type.
00129      *
00130      * \param type the type of module.
00131      *
00132      * \return the prototypes as list.
00133      */
00134     std::vector< WModule::ConstSPtr > getPrototypesByType( MODULE_TYPE type );
00135 
00136     /**
00137      * This method gives read access to the list of all prototypes.
00138      *
00139      * \return the read ticket for the prototype list
00140      */
00141     PrototypeSharedContainerType::ReadTicket getPrototypes() const;
00142 
00143     /**
00144      * Checks whether the first instance can be casted to the second one.
00145      *
00146      * \param module the module to check.
00147      *
00148      * \return true if the dynamic_cast is successful
00149      */
00150     template <typename T>
00151     static bool isA( boost::shared_ptr< WModule > module );
00152 
00153     /**
00154      * Returns a set of module combiners with module combinations compatible with the specified one.
00155      *
00156      * \param module the module to find the compatibles for.
00157      *
00158      * \note as the default parameter denotes, providing a NULL pointer (or calling the method without a parameter) returns the list of modules
00159      * which are compatible to every other module. In other words, it returns all modules without input connectors.
00160      *
00161      * \return set of compatible combiners.
00162      */
00163     WCombinerTypes::WCompatiblesList getCompatiblePrototypes(
00164             boost::shared_ptr< WModule > module = boost::shared_ptr< WModule >()
00165     );
00166 
00167     /**
00168      * This method uses a newly created instance of WModule and initializes it properly. After using this method, the module is
00169      * properly initialized and ready to be used.
00170      *
00171      * \param module the module to initialize.
00172      */
00173     static void initializeModule( boost::shared_ptr< WModule > module );
00174 
00175     /**
00176      * Checks whether the specified module is a prototype or an instantiated module.
00177      *
00178      * \param module the module to check
00179      *
00180      * \return true if it is a prototype
00181      */
00182     static bool isPrototype( boost::shared_ptr< WModule > module );
00183 
00184 protected:
00185     /**
00186      * Constructors are protected because this is a Singleton.
00187      */
00188     WModuleFactory();
00189 
00190     /**
00191      * The module prototypes available.
00192      */
00193     PrototypeSharedContainerType m_prototypes;
00194 
00195     /**
00196      * Checks whether the specified module is a prototype or an instantiated module. Use isPrototype if no ticket acquired yet.
00197      *
00198      * \param module the module to check
00199      * \param ticket ticket which already has read lock.
00200      *
00201      * \return true if it is a prototype
00202      */
00203     bool checkPrototype( boost::shared_ptr< WModule > module, PrototypeSharedContainerType::ReadTicket ticket );
00204 
00205 private:
00206 
00207     /**
00208      * Loader class managing dynamically loaded modules in OpenWalnut.
00209      */
00210     WModuleLoader m_moduleLoader;
00211 
00212     /**
00213      * Singleton instance of WModuleFactory.
00214      */
00215     static boost::shared_ptr< WModuleFactory > m_instance;
00216 };
00217 
00218 template <typename T>
00219 bool WModuleFactory::isA( boost::shared_ptr< WModule > module )
00220 {
00221     // NOTE: this is RTTI. Everybody says: do not use it. We ignore them.
00222     return ( dynamic_cast< T* >( module.get() ) );  // NOLINT
00223 }
00224 
00225 #endif  // WMODULEFACTORY_H
00226 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends