OpenWalnut
1.2.5
|
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