WModuleInputData.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 WMODULEINPUTDATA_H
00026 #define WMODULEINPUTDATA_H
00027 
00028 #include <string>
00029 #include <sstream>
00030 
00031 #include <boost/shared_ptr.hpp>
00032 #include <boost/thread/locks.hpp>
00033 
00034 // this is necessary since we have some kind of cyclic includes
00035 template < typename T > class WModuleOutputData;
00036 #include "WModuleOutputData.h"
00037 #include "exceptions/WModuleConnectorUnconnected.h"
00038 #include "../common/WTransferable.h"
00039 #include "../common/WPrototyped.h"
00040 
00041 #include "WModuleInputConnector.h"
00042 #include "WModuleOutputConnector.h"
00043 
00044 /**
00045  * Class offering an instantiate-able data connection between modules.
00046  * Due to is template style it is possible to bind nearly arbitrary data.
00047  */
00048 template < typename T >
00049 class WModuleInputData: public WModuleInputConnector
00050 {
00051 public:
00052     /**
00053      * Pointer to this. For convenience.
00054      */
00055     typedef boost::shared_ptr< WModuleInputData< T > > PtrType;
00056 
00057     /**
00058      * Reference to this type.
00059      */
00060     typedef WModuleInputData< T >& RefType;
00061 
00062     /**
00063      * Type of the connector.
00064      */
00065     typedef WModuleInputData< T > Type;
00066 
00067     /**
00068      * Typedef to the contained transferable.
00069      */
00070     typedef T TransferType;
00071 
00072     /**
00073      * Convenience method to create a new instance of this in data connector with proper type.
00074      *
00075      * \param module    the module owning this instance
00076      * \param name      the name of this connector.
00077      * \param description the description of this connector.
00078      *
00079      * \return the pointer to the created connector.
00080      */
00081     static PtrType create( boost::shared_ptr< WModule > module, std::string name = "", std::string description = "" );
00082 
00083     /**
00084      * Convenience method to create a new instance of this in data connector with proper type and add it to the list of connectors of the
00085      * specified module.
00086      *
00087      * \param module    the module owning this instance
00088      * \param name      the name of this connector.
00089      * \param description the description of this connector.
00090      *
00091      * \return the pointer to the created connector.
00092      */
00093     static PtrType createAndAdd( boost::shared_ptr< WModule > module, std::string name = "", std::string description = "" );
00094 
00095     /**
00096      * Constructor.
00097      *
00098      * \param module the module which is owner of this connector.
00099      * \param name The name of this connector.
00100      * \param description Short description of this connector.
00101      */
00102     WModuleInputData( boost::shared_ptr< WModule > module, std::string name = "", std::string description = "" ):
00103         WModuleInputConnector( module, name, description ),
00104         m_disconnecting( false )
00105     {
00106     };
00107 
00108     /**
00109      * Destructor.
00110      */
00111     virtual ~WModuleInputData()
00112     {
00113     };
00114 
00115     /**
00116      * Disconnects this connector if connected. If it is not connected: nothing happens.
00117      *
00118      * \param con the connector to disconnect.
00119      * \param removeFromOwnList if true the specified connection is also removed from the own connection list. If false it won't.
00120      */
00121     virtual void disconnect( boost::shared_ptr<WModuleConnector> con, bool removeFromOwnList = true );
00122 
00123     /**
00124      * Gives the currently set data and resets the update flag.
00125      *
00126      * \param reset reset the flag of updated() if true (default).
00127      *
00128      * \return the data currently set. NULL if no data has been sent yet or the connector is unconnected.
00129      */
00130     const boost::shared_ptr< T > getData( bool reset = true )
00131     {
00132         // get a lock
00133         boost::shared_lock<boost::shared_mutex> lock = boost::shared_lock<boost::shared_mutex>( m_connectionListLock );
00134 
00135         // Only reset change flag of requested
00136         if( reset )
00137         {
00138             handledUpdate();
00139         }
00140 
00141         // is there something in the list?
00142         if( m_disconnecting || m_connected.empty() )
00143         {
00144             lock.unlock();
00145             return boost::shared_ptr< T >();
00146         }
00147 
00148         // get data
00149         boost::shared_ptr< T > dat = boost::shared_dynamic_cast< T >(
00150                 boost::shared_dynamic_cast< WModuleOutputConnector >( *m_connected.begin() )->getRawData()
00151         );
00152 
00153         // unlock and return
00154         lock.unlock();
00155 
00156         return dat;
00157     };
00158 
00159     /**
00160      * Checks whether the specified connector is an input connector and compatible with T.
00161      *
00162      * \param con the connector to check against.
00163      *
00164      * \return true if compatible.
00165      */
00166     virtual bool connectable( boost::shared_ptr<WModuleConnector> con )
00167     {
00168         // NOTE: please consider the following: the input only accepts data which is of type T or higher. So only up casts from
00169         // con's type T2 to T are needed/allowed what ever
00170 
00171         if( !WModuleInputConnector::connectable( con ) )
00172         {
00173             return false;
00174         }
00175 
00176         // this calls virtual function to achieve the prototype of the WTransferable created with the type specified in
00177         // WOutputData< XYZ >
00178         boost::shared_ptr< WPrototyped > tProto =
00179             dynamic_cast< WModuleOutputConnector* >( con.get() )->getTransferPrototype(); // NOLINT
00180 
00181         // NOTE: Check the type of the transfered object and whether the connector is an output
00182         return dynamic_cast< T* >( tProto.get() ); // NOLINT
00183     };
00184 
00185 protected:
00186 
00187 private:
00188 
00189     /**
00190      * If true, the returned data will be NULL. Needed because disconnection process is based on multiple steps.
00191      */
00192     bool m_disconnecting;
00193 };
00194 
00195 template < typename T >
00196 void WModuleInputData< T >::disconnect( boost::shared_ptr<WModuleConnector> con, bool removeFromOwnList )
00197 {
00198     m_disconnecting = true;
00199     WModuleInputConnector::disconnect( con, removeFromOwnList );
00200     m_disconnecting = false;
00201 }
00202 
00203 template < typename T >
00204 typename WModuleInputData< T >::PtrType WModuleInputData< T >::create( boost::shared_ptr< WModule > module, std::string name,
00205                                                                                                             std::string description )
00206 {
00207     typedef typename WModuleInputData< T >::PtrType PTR;
00208     typedef typename WModuleInputData< T >::Type TYPE;
00209     return PTR( new TYPE( module, name, description ) );
00210 }
00211 
00212 template < typename T >
00213 typename WModuleInputData< T >::PtrType WModuleInputData< T >::createAndAdd( boost::shared_ptr< WModule > module, std::string name,
00214                                                                                                                   std::string description )
00215 {
00216     typename WModuleInputData< T >::PtrType c = create( module, name, description );
00217     module->addConnector( c );
00218     return c;
00219 }
00220 
00221 #endif  // WMODULEINPUTDATA_H
00222 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends