WModuleContainer.h 7.49 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 WMODULECONTAINER_H
#define WMODULECONTAINER_H

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

#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>

36 37 38 39
#include "WModuleSignals.h"

class WThreadedRunner;
class WBatchLoader;
40 41
class WModule;

42 43 44 45 46 47
/**
 * Class able to contain other modules. It manages several tasks like finding appropriate modules, managing data modules and
 * module initialization.
 *
 * \ingroup Kernel
 */
48
class WModuleContainer: public boost::enable_shared_from_this< WModuleContainer >
49 50 51 52
{
public:

    /**
53
     * Constructor. Initializes container.
54
     *
55 56
     * \param name  name of the container
     * \param description short description.
57
     */
58
    WModuleContainer( std::string name, std::string description );
59 60 61 62 63 64

    /**
     * Destructor.
     */
    virtual ~WModuleContainer();

65
    /**
66
     * Add a module to this container and start it. Please note, that a module can be added only once. If it already is
67
     * associated with this container nothing happens.
68
     *
69
     * \param module the module to add.
70
     * \param run true when the module should be run automatically after adding it.
71 72
     * \throw WModuleUninitialized thrown whenever someone wants to add a module not yet initialized.
     */
73
    virtual void add( boost::shared_ptr< WModule > module, bool run = true );
74 75 76

    /**
     * Remove the given module from this container if it is associated with it. TODO(ebaum): deep removal? flat removal?
77
     *
78 79 80 81
     * \param module the module to remove.
     */
    virtual void remove( boost::shared_ptr< WModule > module );

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
    /**
     * Stops all modules inside this container. Note that this function could take some time, since it waits until the last module
     * has quit.
     */
    virtual void stop();

    /**
     * Gives back the name of this module.
     * \return the module's name.
     */
    virtual const std::string getName() const;

    /**
     * Gives back a description of this module.
     * \return description to module.
     */
    virtual const std::string getDescription() const;

100
    /**
101
     * Add a specified notifier to the list of default notifiers which get connected to each added module.
102
     *
103 104
     * \param signal    the signal the notifier should get connected to
     * \param notifier  the notifier function
105
     */
106
    virtual void addDefaultNotifier( MODULE_SIGNAL signal, t_ModuleErrorSignalHandlerType notifier );
107 108 109 110 111 112 113

    /**
     * Add a specified notifier to the list of default notifiers which get connected to each added module.
     *
     * \param signal    the signal the notifier should get connected to
     * \param notifier  the notifier function
     */
114
    virtual void addDefaultNotifier( MODULE_SIGNAL signal, t_ModuleGenericSignalHandlerType notifier );
115

116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
    /**
     * Function combines to modules.
     *
     * \param applyOn the module which already has to be in the container and to apply the other one on.
     * \param what the prototype name of the module to apply on the other one specified.
     *
     * \return the newly created module connected with the one specified in applyOn.
     */
    virtual boost::shared_ptr< WModule > applyModule( boost::shared_ptr< WModule > applyOn, std::string what );

    /**
     * Function combines to modules.
     *
     * \param applyOn the module which already has to be in the container and to apply the other one on.
     * \param prototype the prototype of the module to apply on the other one specified.
     *
     * \return the newly created module connected with the one specified in applyOn.
     */
    virtual boost::shared_ptr< WModule > applyModule( boost::shared_ptr< WModule > applyOn, boost::shared_ptr< WModule > prototype );

136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
    /**
     * Load specified datasets. It immediately returns and starts another thread, which actually loads the data.
     *
     * \param fileNames list of filenames to load. The registered notification handler for the root container will get notified on
     * error and success.
     */
    boost::shared_ptr< WBatchLoader > loadDataSets( std::vector< std::string > fileNames );

    /**
     * Loads the specified files synchronously.
     *
     * \param fileNames list of filenames to load. The registered notification handler for the root container will get notified on
     * error and success.
     */
    void loadDataSetsSynchronously( std::vector< std::string > fileNames );

    /**
     * Add the specified thread to the list of pending jobs. Only this ensures, that ALL pending threads got stopped before the
     * container gets stopped.
     *
     * \note use this to register threads whenever you start threads belonging to this container. This avoids shutting down the
     * container while other threads depend upon them.
     *
     * \param thread the thread to add
     */
    void addPendingThread( boost::shared_ptr< WThreadedRunner > thread );

    /**
     * The specified thread has finished and does not longer depend upon this container instance.
     *
     * \param thread the thread.
     */
    void finishedPendingThread( boost::shared_ptr< WThreadedRunner > thread );

170 171
protected:

172 173 174 175 176 177 178 179 180 181
    /**
     * Lock for module set.
     */
    boost::shared_mutex m_moduleSetLock;

    /**
     * The modules associated with this container.
     */
    std::set< boost::shared_ptr< WModule > > m_modules;

182 183 184 185 186 187 188 189 190
    /**
     * Name of the module.
     */
    std::string m_name;

    /**
     * Description of the module.
     */
    std::string m_description;
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
191

192
    /**
193
     * Lock for error notifiers set.
194
     */
195
    boost::shared_mutex m_errorNotifiersLock;
196 197

    /**
198 199 200 201 202 203 204 205 206 207 208
     * The error notifiers connected to added modules by default.
     */
    std::list< t_ModuleErrorSignalHandlerType > m_errorNotifiers;

    /**
     * Lock for ready notifiers set.
     */
    boost::shared_mutex m_readyNotifiersLock;

    /**
     * The ready notifiers connected to added modules by default.
209
     */
210
    std::list< t_ModuleGenericSignalHandlerType > m_readyNotifiers;
211

212 213 214 215 216 217 218 219 220 221
    /**
     * Lock for associated notifiers set.
     */
    boost::shared_mutex m_associatedNotifiersLock;

    /**
     * The notifiers connected to added modules by default and fired whenever the module got associated.
     */
    std::list< t_ModuleGenericSignalHandlerType > m_associatedNotifiers;

222 223 224 225 226 227 228 229 230 231
    /**
     * Set of all threads that currently depend upon this container.
     */
    std::set< boost::shared_ptr< WThreadedRunner > > m_pendingThreads;

    /**
     * Lock for m_pendingThreads.
     */
    boost::shared_mutex m_pendingThreadsLock;

232 233 234 235 236
private:
};

#endif  // WMODULECONTAINER_H