WModuleFactory.h 7.37 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

#ifndef WMODULEFACTORY_H
#define WMODULEFACTORY_H

28
#include <set>
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
29
#include <string>
30
#include <utility>
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
31
#include <vector>
32

33 34
#include <boost/shared_ptr.hpp>

35
#include "../common/WSharedAssociativeContainer.h"
36
#include "WModuleCombinerTypes.h"
37
#include "WModule.h"
38
#include "WModuleLoader.h"
39 40 41 42

/**
 * Class able to create a new copy of an arbitrary module. It uses the Factory and Prototype design pattern.
 */
43
class  WModuleFactory // NOLINT
44
{
45
friend class WModuleFactoryTest;
46
public:
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
    /**
     * For shortening: a type defining a shared set of WModule pointers.
     */
    typedef std::set< boost::shared_ptr< WModule > > PrototypeContainerType;

    /**
     * Const iterator for the prototype set.
     */
    typedef std::set< boost::shared_ptr< WModule > >::const_iterator PrototypeContainerConstIteratorType;

    /**
     * Iterator for the prototype set.
     */
    typedef std::set< boost::shared_ptr< WModule > >::iterator PrototypeContainerIteratorType;

    /**
     * The alias for a shared container.
     */
    typedef WSharedAssociativeContainer< PrototypeContainerType > PrototypeSharedContainerType;

67 68 69 70 71
    /**
     * Destructor.
     */
    virtual ~WModuleFactory();

72 73 74 75 76
    /**
     * Loads the modules and creates prototypes.
     */
    void load();

77 78
    /**
     * Create a new and initialized module using the specified prototype.
79
     *
80
     * \param prototype the prototype to clone.
81
     *
82 83 84 85 86 87
     * \return the module created using the prototype.
     */
    boost::shared_ptr< WModule > create( boost::shared_ptr< WModule > prototype );

    /**
     * Returns instance of the module factory to use to create modules.
88
     *
89 90 91 92
     * \return the running module factory.
     */
    static boost::shared_ptr< WModuleFactory > getModuleFactory();

93 94 95 96 97 98 99
    /**
     * Returns instance of the module loader.
     *
     * \return the running module loader.
     */
    static boost::shared_ptr< WModuleLoader > getModuleLoader();

100 101 102 103 104 105 106 107 108 109 110
    /**
     * Searches a prototype by name. It returns the prototype, or a NULL pointer if it is not found. The difference to
     * getPrototypeByName() is, that an unavailable prototype does not throw an exception. This is nice for checking whether a
     * prototype exists or not.
     *
     * \param name name of the prototype to search
     *
     * \return the prototype if it exists, or NULL if not.
     */
    const boost::shared_ptr< WModule > isPrototypeAvailable( std::string name );

111 112
    /**
     * Finds a prototype using the specified name.
113
     *
114
     * \param name the name.
115
     *
116 117 118 119 120 121
     * \return the prototype whose name is equal to the specified one.
     */
    const boost::shared_ptr< WModule > getPrototypeByName( std::string name );

    /**
     * Finds a prototype using an instance of a module. This uses the type_info to find a proper prototype.
122
     *
123
     * \param instance the instance to use.
124
     *
125 126 127 128 129
     * \return the prototype.
     * \throw WPrototypeUnknown if prototype can not be found.
     */
    const boost::shared_ptr< WModule > getPrototypeByInstance( boost::shared_ptr< WModule > instance );

130 131 132 133 134 135 136 137 138
    /**
     * Finds a prototype using an type.
     *
     * \param type the type of module.
     *
     * \return the prototypes as list.
     */
    std::vector< WModule::ConstSPtr > getPrototypesByType( MODULE_TYPE type );

139 140 141 142 143 144 145
    /**
     * This method gives read access to the list of all prototypes.
     *
     * \return the read ticket for the prototype list
     */
    PrototypeSharedContainerType::ReadTicket getPrototypes() const;

146 147
    /**
     * Checks whether the first instance can be casted to the second one.
148
     *
149
     * \param module the module to check.
150
     *
151
     * \return true if the dynamic_cast is successful
152 153 154 155
     */
    template <typename T>
    static bool isA( boost::shared_ptr< WModule > module );

156
    /**
157
     * Returns a set of module combiners with module combinations compatible with the specified one.
158
     *
159
     * \param module the module to find the compatibles for.
160
     *
161
     * \note as the default parameter denotes, providing a NULL pointer (or calling the method without a parameter) returns the list of modules
162 163
     * which are compatible to every other module. In other words, it returns all modules without input connectors. If the specified module is
     * not NULL, the modules without input are not listed.
164
     *
165
     * \return set of compatible combiners.
166
     */
167
    WCombinerTypes::WCompatiblesList getCompatiblePrototypes(
168 169
            boost::shared_ptr< WModule > module = boost::shared_ptr< WModule >()
    );
170

171 172 173 174 175 176 177
    /**
     * Creates a list of \ref WApplyCombiner for all modules known by the factory.
     *
     * \return list of apply combiner.
     */
    WCombinerTypes::WCompatiblesList getAllPrototypes();

178 179 180 181 182 183 184 185
    /**
     * This method uses a newly created instance of WModule and initializes it properly. After using this method, the module is
     * properly initialized and ready to be used.
     *
     * \param module the module to initialize.
     */
    static void initializeModule( boost::shared_ptr< WModule > module );

186 187 188 189 190 191 192 193 194
    /**
     * Checks whether the specified module is a prototype or an instantiated module.
     *
     * \param module the module to check
     *
     * \return true if it is a prototype
     */
    static bool isPrototype( boost::shared_ptr< WModule > module );

195
protected:
196 197 198 199
    /**
     * Constructors are protected because this is a Singleton.
     */
    WModuleFactory();
200

201 202 203
    /**
     * The module prototypes available.
     */
204
    PrototypeSharedContainerType m_prototypes;
205

206 207 208 209 210 211 212 213 214 215
    /**
     * Checks whether the specified module is a prototype or an instantiated module. Use isPrototype if no ticket acquired yet.
     *
     * \param module the module to check
     * \param ticket ticket which already has read lock.
     *
     * \return true if it is a prototype
     */
    bool checkPrototype( boost::shared_ptr< WModule > module, PrototypeSharedContainerType::ReadTicket ticket );

216
private:
217
    /**
218
     * Loader class managing dynamically loaded modules in OpenWalnut.
219
     */
220
    WModuleLoader::SPtr m_moduleLoader;
221

222 223 224 225 226 227
    /**
     * Singleton instance of WModuleFactory.
     */
    static boost::shared_ptr< WModuleFactory > m_instance;
};

228 229 230
template <typename T>
bool WModuleFactory::isA( boost::shared_ptr< WModule > module )
{
231
    // NOTE: this is RTTI. Everybody says: do not use it. We ignore them.
232 233 234
    return ( dynamic_cast< T* >( module.get() ) );  // NOLINT
}

235 236
#endif  // WMODULEFACTORY_H