OpenWalnut 1.3.1
WModule.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 WMODULE_H
00026 #define WMODULE_H
00027 
00028 #include <string>
00029 #include <typeinfo>
00030 #include <vector>
00031 
00032 #include <boost/enable_shared_from_this.hpp>
00033 #include <boost/filesystem.hpp>
00034 #include <boost/function.hpp>
00035 #include <boost/shared_ptr.hpp>
00036 #include <boost/signals2/signal.hpp>
00037 #include <boost/thread.hpp>
00038 
00039 #include "../common/WConditionSet.h"
00040 #include "../common/WLogger.h"
00041 #include "../common/WProgress.h"
00042 #include "../common/WProgressCombiner.h"
00043 #include "../common/WProperties.h"
00044 #include "../common/WPrototyped.h"
00045 #include "../common/WRequirement.h"
00046 #include "../common/WThreadedRunner.h"
00047 #include "../dataHandler/WDataSet.h"
00048 #include "../dataHandler/WDataSetSingle.h"
00049 #include "../dataHandler/WValueSet.h"
00050 
00051 #include "WModuleCombinerTypes.h"
00052 #include "WModuleConnectorSignals.h"
00053 #include "WModuleSignals.h"
00054 #include "WModuleTypes.h"
00055 #include "WModuleMetaInformation.h"
00056 
00057 class WModuleConnector;
00058 class WModuleContainer;
00059 class WModuleFactory;
00060 class WModuleLoader;
00061 class WModuleInputConnector;
00062 class WModuleOutputConnector;
00063 template < typename T > class WModuleInputData;
00064 template < typename T > class WModuleInputForwardData;
00065 template < typename T > class WModuleOutputData;
00066 
00067 /**
00068  * Class representing a single module of OpenWalnut.
00069  * \ingroup kernel
00070  */
00071 class  WModule: public WThreadedRunner,
00072                                public WPrototyped,
00073                                public boost::enable_shared_from_this< WModule >
00074 {
00075 friend class WModuleConnector;  // requires access to notify members
00076 template< typename T > friend class WModuleInputData;  // requires access for convenience functions to automatically add a created connector
00077 template< typename T > friend class WModuleInputForwardData;  // requires access for convenience functions to automatically add a created connector
00078 template< typename T > friend class WModuleOutputData;  // requires access for convenience functions to automatically add a created connector
00079 template< typename T > friend class WModuleOutputForwardData;  // requires access for convenience functions to automatically add a created connector
00080 friend class WModuleFactory;    // for proper creation of module instances, the factory needs access to protected functions.
00081                                 // (especially initialize)
00082 friend class WModuleContainer;  // for proper management of m_container WModuleContainer needs access.
00083 friend class WModuleLoader;     // needs to set several protected values like local path and library names.
00084 
00085 public:
00086     /**
00087      * Constructs a new WModule instance
00088      */
00089     WModule();
00090 
00091     /**
00092      * Destructor.
00093      */
00094     virtual ~WModule();
00095 
00096     /**
00097      * The type for the list of input connectors.
00098      */
00099     typedef std::vector< boost::shared_ptr< WModuleInputConnector > > InputConnectorList;
00100 
00101     /**
00102      * The type for the list of output connectors.
00103      */
00104     typedef std::vector< boost::shared_ptr< WModuleOutputConnector > > OutputConnectorList;
00105 
00106     /**
00107      * Shared pointer to a WModule.
00108      */
00109     typedef boost::shared_ptr< WModule > SPtr;
00110 
00111     /**
00112      * Shared pointer to a const WModule.
00113      */
00114     typedef boost::shared_ptr< const WModule > ConstSPtr;
00115 
00116     /**
00117      * Gives back input connectors.
00118      *
00119      * \return the input connectors.
00120      */
00121     const InputConnectorList& getInputConnectors() const;
00122 
00123     /**
00124      * Finds the named connector for the module.
00125      *
00126      * \param name the name. This can be a canonical name or the connector name.
00127      *
00128      * \return the connector.
00129      * \throw WModuleConnectorNotFound thrown whenever the module does not provide the specified connector.
00130      */
00131     boost::shared_ptr< WModuleInputConnector > getInputConnector( std::string name );
00132 
00133     /**
00134      * Finds the named connector for the module. This is similar to getInputConnector but it does not throw an exception if the connector could
00135      * not be found.
00136      *
00137      * \param name the name. This can be a canonical name or the connector name.
00138      *
00139      * \return the connector or NULL if not found
00140      */
00141     boost::shared_ptr< WModuleInputConnector > findInputConnector( std::string name );
00142 
00143     /**
00144      * Gives back output connectors.
00145      *
00146      * \return the output connectors.
00147      */
00148     const OutputConnectorList& getOutputConnectors() const;
00149 
00150     /**
00151      * Finds the named connector for the module.
00152      *
00153      * \param name the name. This can be a canonical name or the connector name.
00154      *
00155      * \return the connector.
00156      * \throw WModuleConnectorNotFound thrown whenever the module does not provide the specified connector.
00157      */
00158     boost::shared_ptr< WModuleOutputConnector > getOutputConnector( std::string name );
00159 
00160     /**
00161      * Finds the named connector for the module. This is similar to getOutputConnector but it does not throw an exception if the connector could
00162      * not be found.
00163      *
00164      * \param name the name. This can be a canonical name or the connector name.
00165      *
00166      * \return the connector or NULL if not found.
00167      */
00168     boost::shared_ptr< WModuleOutputConnector > findOutputConnector( std::string name );
00169 
00170     /**
00171      * Finds the named connector for the module. This searches for inputs and outputs.
00172      *
00173      * \param name the name. This can be a canonical name or the connector name.
00174      *
00175      * \return the connector.
00176      * \throw WModuleConnectorNotFound thrown whenever the module does not provide the specified connector.
00177      */
00178     boost::shared_ptr< WModuleConnector > getConnector( std::string name );
00179 
00180     /**
00181      * Finds the named connector for the module. This searches for inputs and outputs. This is similar to getConnector but it does not throw an
00182      * exception if the connector could not be found.
00183      *
00184      * \param name the name. This can be a canonical name or the connector name.
00185      *
00186      * \return the connector or NULL if not found.
00187      */
00188     boost::shared_ptr< WModuleConnector > findConnector( std::string name );
00189 
00190     /**
00191      * Return a pointer to the properties object of the module.
00192      *
00193      * \return the properties.
00194      */
00195     boost::shared_ptr< WProperties > getProperties() const;
00196 
00197     /**
00198      * Return a pointer to the information properties object of the module. The module intends these properties to not be modified.
00199      *
00200      * \return the properties.
00201      */
00202     boost::shared_ptr< WProperties > getInformationProperties() const;
00203 
00204     /**
00205      * Determines whether the module instance is properly initialized.
00206      *
00207      * \return true if properly initialized.
00208      */
00209     const WBoolFlag& isInitialized() const;
00210 
00211     /**
00212      * Checks whether the module instance is ready to be used. This is the case if isInitialized && isAssociated.
00213      *
00214      * \return isInitialized && isAssociated
00215      */
00216     const WBoolFlag&  isUseable() const;
00217 
00218      /**
00219       * Checks whether this module is associated with an container.
00220       *
00221       * \return true if associated.
00222       */
00223     const WBoolFlag&  isAssociated() const;
00224 
00225      /**
00226       * Checks whether this module is ready.
00227       *
00228       * \return true if ready.
00229       */
00230     const WBoolFlag&  isReady() const;
00231 
00232     /**
00233      * This is the logical or of isReady and isCrashed. You should use this condition if you need to wait for a module to get ready. If it
00234      * crashed before ready() got called, you most probably would wait endlessly.
00235      *
00236      * \return isReady || isCrashed.
00237      */
00238     const WBoolFlag& isReadyOrCrashed() const;
00239 
00240     /**
00241      * Returns a flag denoting whether the thread currently is running or nor. It is also useful to get a callback whenever a module stops.
00242      *
00243      * \return the flag
00244      */
00245     const WBoolFlag& isRunning() const;
00246 
00247      /**
00248       * The container this module is associated with.
00249       *
00250       * \return the container.
00251       */
00252     boost::shared_ptr< WModuleContainer > getAssociatedContainer() const;
00253 
00254     /**
00255      * Due to the prototype design pattern used to build modules, this method returns a new instance of this module. NOTE: it
00256      * should never be initialized or modified in some other way.
00257      *
00258      * \return the prototype used to create every module in OpenWalnut.
00259      */
00260     virtual boost::shared_ptr< WModule > factory() const = 0;
00261 
00262     /**
00263      * Connects a specified notify function with a signal this module instance is offering.
00264      *
00265      * \exception WModuleSignalSubscriptionFailed thrown if the signal can't be connected.
00266      *
00267      * \param signal the signal to connect to.
00268      * \param notifier the notifier function to bind.
00269      *
00270      * \return connection descriptor.
00271      */
00272     virtual boost::signals2::connection subscribeSignal( MODULE_SIGNAL signal, t_ModuleGenericSignalHandlerType notifier );
00273 
00274     /**
00275      * Connects a specified notify function with a signal this module instance is offering. Please note that there also is a
00276      * WThreadedRunner::subscribeSignal which allows error callbacks. The difference to this one is that the WThreadedRunner's version does not
00277      * provide the sender information (shared_ptr).
00278      *
00279      * \exception WModuleSignalSubscriptionFailed thrown if the signal can't be connected.
00280      *
00281      * \param signal the signal to connect to.
00282      * \param notifier the notifier function to bind.
00283      *
00284      * \return connection descriptor.
00285      */
00286     virtual boost::signals2::connection subscribeSignal( MODULE_SIGNAL signal, t_ModuleErrorSignalHandlerType notifier );
00287 
00288     /**
00289      * Gets the modules base progress. This is actually a progress combiner, which bundles all progresses.
00290      *
00291      * \return the progress combiner for this module.
00292      */
00293     virtual boost::shared_ptr< WProgressCombiner > getRootProgressCombiner();
00294 
00295     /**
00296      * Get the icon for this module in XPM format.
00297      * \return The icon.
00298      */
00299     virtual const char** getXPMIcon() const;
00300 
00301     /**
00302      * Gets the type of the module. This is useful for FAST differentiation between several modules like standard modules and data
00303      * modules which play a special role in OpenWalnut/Kernel.
00304      *
00305      * \return the Type. If you do not overwrite this method, it will return MODULE_ARBITRARY.
00306      */
00307     virtual MODULE_TYPE getType() const;
00308 
00309     /**
00310      * Completely disconnects all connected connectors of this module. This is useful to isolate a module (for deletion, removal from a container
00311      * and so on.)
00312      */
00313     void disconnect();
00314 
00315     /**
00316      * Gives a list of all WDisconnectCombiners possible. Please note that while the list exists, connections might change.
00317      *
00318      * \return the list of possible disconnect operations
00319      */
00320     WCombinerTypes::WDisconnectList getPossibleDisconnections();
00321 
00322     /**
00323      * Returns the local path of the module. Whenever you try to load local resources, use this path. It is especially useful for shader loading.
00324      *
00325      * \return the local module path.
00326      */
00327     boost::filesystem::path getLocalPath() const;
00328 
00329     /**
00330      * Returns the absolute path to the library containing this module.
00331      *
00332      * \return the path.
00333      */
00334     boost::filesystem::path getLibPath() const;
00335 
00336     /**
00337      * Returns the name of the package the module belongs to, The package name basically is the name of the
00338      * library containing this and maybe other modules. Your build system manages this. The package name is used to identify the resources for
00339      * the modules in the library (a.k.a package).
00340      *
00341      * \return the name
00342      */
00343     std::string getPackageName() const;
00344 
00345     /**
00346      * Checks whether the module was marked as deprecated.
00347      *
00348      * \return true if deprecated
00349      */
00350     bool isDeprecated() const;
00351 
00352     /**
00353      * Queries the deprecation message of a module if specified. If not specified, an empty string is returned. Check \ref isDeprecated first.
00354      *
00355      * \return deprecation message
00356      */
00357     std::string getDeprecationMessage() const;
00358 
00359     /**
00360      * The meta information of this module. This contains several information like name, description, icons, help links and so on. It, at least,
00361      * contains the name.
00362      *
00363      * \return the meta info object for this module.
00364      */
00365     virtual WModuleMetaInformation::ConstSPtr getMetaInformation() const;
00366 
00367 protected:
00368     /**
00369      * Entry point after loading the module. Runs in separate thread.
00370      */
00371     virtual void moduleMain() = 0;
00372 
00373     /**
00374      * Thread entry point. Calls moduleMain and sends error notification if needed.
00375      */
00376     void threadMain();
00377 
00378     /**
00379      * This method is called if an exception was caught, which came from the custom thread code. This method is virtual and allows you to
00380      * overwrite the default behaviour. If you overwrite this method, you should call \ref WThreadedRunner::handleDeadlyException or
00381      * WThreadedRunner::onThreadException if you are finished with your customized code.
00382      *
00383      * \param e the exception that was caught.
00384      */
00385     virtual void onThreadException( const WException& e );
00386 
00387      /**
00388       * Sets the container this module is associated with.
00389       *
00390       * \param container the container to associate with.
00391       */
00392     void setAssociatedContainer( boost::shared_ptr< WModuleContainer > container );
00393 
00394     // **************************************************************************************************************************
00395     //
00396     // Connector Management
00397     //
00398     // **************************************************************************************************************************
00399 
00400     /**
00401      * Initialize connectors in this function. This function must not be called multiple times for one module instance.
00402      * The module container manages calling those functions -> so just implement it.
00403      */
00404     virtual void connectors();
00405 
00406     /**
00407      * Initialize properties in this function. This function must not be called multiple times for one module instance.
00408      * The module container manages calling those functions -> so just implement it. Once initialized the number and type
00409      * of all properties should be set.
00410      */
00411     virtual void properties();
00412 
00413     /**
00414      * Initialize requirements in this function. This function must not be called multiple times for one module instance.
00415      * The module should always implement this. Using this method, a module can tell the kernel what it needs to run properly. For example, it
00416      * can require a running graphics engine or, in the case of module containers, other modules.
00417      */
00418     virtual void requirements();
00419 
00420     /**
00421      * This function allows module programmers to mark their modules deprecated in a user-friendly way. If you implement this function, you need
00422      * to specify an text which should mention an alternative module.
00423      *
00424      * \note do not add sentences like "this module is deprecated" or similar, since the GUI the user is using already shows this message. The
00425      * message should say WHY it is deprecated and what alternative module is available.
00426      * \return deprecation message
00427      */
00428     virtual std::string deprecated() const;
00429 
00430     /**
00431      * Manages connector initialization. Gets called by module container.
00432      *
00433      * \throw WModuleConnectorInitFailed if called multiple times.
00434      */
00435     void initialize();
00436 
00437     /**
00438      * Called whenever the module should shutdown.
00439      */
00440     virtual void cleanup();
00441 
00442     /**
00443      * Adds the specified connector to the list of inputs.
00444      *
00445      * \param con the connector.
00446      */
00447     void addConnector( boost::shared_ptr<WModuleInputConnector> con );
00448 
00449     /**
00450      * Adds the specified connector to the list of outputs.
00451      *
00452      * \param con the connector.
00453      */
00454     void addConnector( boost::shared_ptr<WModuleOutputConnector> con );
00455 
00456     /**
00457      * Removes all connectors properly. It disconnects the connectors and cleans the connectors list.
00458      */
00459     void removeConnectors();
00460 
00461     /**
00462      * Callback for m_active. Overwrite this in your modules to handle m_active changes separately.
00463      */
00464     virtual void activate();
00465 
00466     // **************************************************************************************************************************
00467     //
00468     // Signal handlers that HAVE to be in every module. By default they do nothing. You should overwrite them to get notified
00469     // with the corresponding signal
00470     //
00471     // **************************************************************************************************************************
00472 
00473     /**
00474      * Gives the signal handler function responsible for a given signal. Modules defining own signal handlers should overwrite
00475      * this function. This function is protected since boost::functions are callable, which is what is not wanted here. Just
00476      * signals should call them.
00477      *
00478      * \param signal the signal to get the handler for.
00479      *
00480      * \return the signal handler for "signal".
00481      */
00482     virtual const t_GenericSignalHandlerType getSignalHandler( MODULE_CONNECTOR_SIGNAL signal );
00483 
00484     /**
00485      * Gets called whenever a connector gets connected to the specified input.
00486      *
00487      * \param here the connector of THIS module that got connected to "there"
00488      * \param there the connector that has been connected with the connector "here" of this module.
00489      */
00490     virtual void notifyConnectionEstablished( boost::shared_ptr<WModuleConnector> here,
00491                                               boost::shared_ptr<WModuleConnector> there );
00492     /**
00493      * Gets called whenever a connection between a remote and local connector gets closed.
00494      *
00495      * \param here the connector of THIS module getting disconnected.
00496      * \param there the connector of the other module getting disconnected.
00497      */
00498     virtual void notifyConnectionClosed( boost::shared_ptr<WModuleConnector> here, boost::shared_ptr<WModuleConnector> there );
00499 
00500     /**
00501      * Gets called when the data on one input connector changed.
00502      *
00503      * \param input the input connector receiving the change.
00504      * \param output the output connector sending the change notification.
00505      */
00506     virtual void notifyDataChange( boost::shared_ptr<WModuleConnector> input,
00507                                    boost::shared_ptr<WModuleConnector> output );
00508 
00509     /**
00510      * Call this whenever your module is ready and can react on property changes.
00511      */
00512     void ready();
00513 
00514     /**
00515      * Logger instance for comfortable info logging. Simply use logInfo() << "my info".
00516      *
00517      * \return the logger stream.
00518      */
00519     wlog::WStreamedLogger infoLog() const;
00520 
00521     /**
00522      * Logger instance for comfortable debug logging. Simply use logDebug() << "my debug".
00523      *
00524      * \return the logger stream.
00525      */
00526     wlog::WStreamedLogger debugLog() const;
00527 
00528     /**
00529      * Logger instance for comfortable warning- logs. Simply use logWarning() << "my warning".
00530      *
00531      * \return the logger stream.
00532      */
00533     wlog::WStreamedLogger warnLog() const;
00534 
00535     /**
00536      * Logger instance for comfortable error logging. Simply use logError() << "my error".
00537      *
00538      * \return the logger stream.
00539      */
00540     wlog::WStreamedLogger errorLog() const;
00541 
00542     // **************************************************************************************************************************
00543     //
00544     // Loading Management
00545     //
00546     // **************************************************************************************************************************
00547 
00548     /**
00549      * Sets the local module path. This gets called by the module loader.
00550      *
00551      * \param path the local path.
00552      */
00553     void setLocalPath( boost::filesystem::path path );
00554 
00555     /**
00556      * Set the path to the library which contains this module. This is usually set by \ref WModuleLoader.
00557      *
00558      * \param path the path to the library. Needs to be absolute.
00559      */
00560     void setLibPath( boost::filesystem::path path );
00561 
00562     /**
00563      * Set the package name. This basically is the library name of the lib containing this module. The package name is used to identify resources
00564      * and other things which belong to a library (a.k.a. package).
00565      *
00566      * \param name the name to set
00567      */
00568     void setPackageName( std::string name );
00569 
00570     // **************************************************************************************************************************
00571     //
00572     // Members
00573     //
00574     // **************************************************************************************************************************
00575 
00576     /**
00577      * The property object for the module.
00578      */
00579     boost::shared_ptr< WProperties > m_properties;
00580 
00581     /**
00582      * The property object for the module containing only module whose purpose is "PV_PURPOSE_INFORMNATION". It is useful to define some property
00583      * to only be of informational nature. The GUI does not modify them. As it is a WProperties instance, you can use it the same way as
00584      * m_properties.
00585      */
00586     boost::shared_ptr< WProperties > m_infoProperties;
00587 
00588     /**
00589      * Progress indicator used as parent for all progress' of this module.
00590      */
00591     boost::shared_ptr< WProgressCombiner > m_progress;
00592 
00593     /**
00594      * True if everything is initialized and ready to be used.
00595      */
00596     WBoolFlag m_initialized;
00597 
00598     /**
00599      * True if container got associated with this flag.
00600      */
00601     WBoolFlag m_isAssociated;
00602 
00603     /**
00604      * True if associated && initialized.
00605      */
00606     WBoolFlag m_isUsable;
00607 
00608     /**
00609      * True if ready() was called.
00610      */
00611     WBoolFlag m_isReady;
00612 
00613     /**
00614      * It is true whenever m_isReady or WThreadedRunner::m_isCrashed is true. This is mostly useful for functions
00615      * which need to wait for a module to get ready.
00616      */
00617     WBoolFlag m_isReadyOrCrashed;
00618 
00619     /**
00620      * True if the module currently is running.
00621      */
00622     WBoolFlag m_isRunning;
00623 
00624     /**
00625      * Progress indicator for the "ready" state.
00626      */
00627     boost::shared_ptr< WProgress > m_readyProgress;
00628 
00629     /**
00630      * The internal state of the module. This is, by default, simply the exit flag from WThreadedRunner.
00631      */
00632     WConditionSet m_moduleState;
00633 
00634     /**
00635      * The container this module belongs to.
00636      */
00637     boost::shared_ptr< WModuleContainer > m_container;
00638 
00639     /**
00640      * Set of input connectors associated with this module.
00641      */
00642     InputConnectorList m_inputConnectors;
00643 
00644     /**
00645      * Set of output connectors associated with this module.
00646      */
00647     OutputConnectorList m_outputConnectors;
00648 
00649     /**
00650      * True whenever the module should be active
00651      */
00652     WPropBool m_active;
00653 
00654     /**
00655      * This property holds a user specified name for the current module instance.
00656      */
00657     WPropString m_runtimeName;
00658 
00659     /**
00660      * The path where the module binary resides in. This path should be used whenever the module needs to load resources. It gets set by the
00661      * module loader. Use this to load shaders and so on.
00662      */
00663     boost::filesystem::path m_localPath;
00664 
00665     /**
00666      * The absolute path to the library containing this module.
00667      */
00668     boost::filesystem::path m_libPath;
00669 
00670     /**
00671      * The name of the lib/the package containing this module.
00672      */
00673     std::string m_packageName;
00674 
00675     /**
00676      * The type of the requirement list.
00677      */
00678     typedef std::vector< WRequirement* > Requirements;
00679 
00680     /**
00681      * The list of requirements.
00682      */
00683     Requirements m_requirements;
00684 
00685 private:
00686      /**
00687      * Lock for m_inputConnectors.
00688      */
00689     // boost::shared_mutex m_inputConnectorsLock;
00690 
00691     /**
00692      * Lock for m_outputConnectors.
00693      */
00694     // boost::shared_mutex m_outputConnectorsLock;
00695 
00696     /**
00697      * Module meta information. Set by the factory creating the module instance.
00698      */
00699     WModuleMetaInformation::SPtr m_meta;
00700 
00701     /**
00702      * Signal fired whenever a module main thread is ready.
00703      */
00704     t_ModuleGenericSignalType signal_ready;
00705 
00706     /**
00707      * Signal fired whenever a module main thread throws an exception/error.
00708      */
00709     t_ModuleErrorSignalType signal_error;
00710 
00711     /**
00712      * This method checks whether all the requirements of the module are complied.
00713      *
00714      * \return the requirement that has failed.
00715      */
00716     const WRequirement* checkRequirements() const;
00717 };
00718 
00719 /**
00720  * Simply a list of modules. The type is used by the following macros and typedefs
00721  */
00722 typedef std::vector< boost::shared_ptr< WModule > > WModuleList;
00723 
00724 /**
00725  * The signature used for the module loading entry point
00726  */
00727 typedef void ( *W_LOADABLE_MODULE_SIGNATURE )( WModuleList& );
00728 
00729 /**
00730  * The following macro is used by modules so the factory can acquire a prototype instance from a shared library using the symbol.
00731  * You can write this symbol for your own if you need to add multiple modules to the list. This one is for convenience.
00732  *
00733  * \note we need the module instance to be created using a shared_ptr as WModule is derived from enable_shared_from_this. Removing the shared
00734  *       pointer causes segmentation faults during load.
00735  */
00736 #define W_LOADABLE_MODULE( MODULECLASS ) \
00737 extern "C"                       void WLoadModule( WModuleList& m ) { m.push_back( boost::shared_ptr< WModule >( new MODULECLASS ) ); }  // NOLINT
00738 
00739 /**
00740  * The corresponding symbol name.
00741  */
00742 #define W_LOADABLE_MODULE_SYMBOL "WLoadModule"
00743 
00744 /**
00745  * \defgroup modules Modules
00746  *
00747  * \brief
00748  * This group contains modules of OpenWalnut.
00749  * The term modules can be understood as "plugin" or "algorithm" in this context.
00750  */
00751 #endif  // WMODULE_H
00752