OpenWalnut  1.4.0
WModuleInputData.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WMODULEINPUTDATA_H
26 #define WMODULEINPUTDATA_H
27 
28 #include <string>
29 
30 #ifndef Q_MOC_RUN
31 #include <boost/shared_ptr.hpp>
32 #endif
33 #ifndef Q_MOC_RUN
34 #include <boost/thread/locks.hpp>
35 #endif
36 
37 // this is necessary since we have some kind of cyclic includes
38 template < typename T > class WModuleOutputData;
39 #include "WModuleOutputData.h"
40 #include "exceptions/WModuleConnectorUnconnected.h"
41 #include "../common/WTransferable.h"
42 #include "../common/WPrototyped.h"
43 
44 #include "WModuleInputConnector.h"
45 #include "WModuleOutputConnector.h"
46 
47 /**
48  * Class offering an instantiate-able data connection between modules.
49  * Due to is template style it is possible to bind nearly arbitrary data.
50  */
51 template < typename T >
53 {
54 public:
55  /**
56  * Pointer to this. For convenience.
57  */
58  typedef boost::shared_ptr< WModuleInputData< T > > PtrType;
59 
60  /**
61  * Pointer to this. For convenience.
62  */
63  typedef boost::shared_ptr< WModuleInputData< T > > SPtr;
64 
65  /**
66  * Pointer to this. For convenience.
67  */
68  typedef boost::shared_ptr< const WModuleInputData< T > > ConstSPtr;
69 
70  /**
71  * Reference to this type.
72  */
74 
75  /**
76  * Type of the connector.
77  */
79 
80  /**
81  * Typedef to the contained transferable.
82  */
83  typedef T TransferType;
84 
85  /**
86  * Convenience method to create a new instance of this in data connector with proper type.
87  *
88  * \param module the module owning this instance
89  * \param name the name of this connector.
90  * \param description the description of this connector.
91  *
92  * \return the pointer to the created connector.
93  */
94  static PtrType create( boost::shared_ptr< WModule > module, std::string name = "", std::string description = "" );
95 
96  /**
97  * 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
98  * specified module.
99  *
100  * \param module the module owning this instance
101  * \param name the name of this connector.
102  * \param description the description of this connector.
103  *
104  * \return the pointer to the created connector.
105  */
106  static PtrType createAndAdd( boost::shared_ptr< WModule > module, std::string name = "", std::string description = "" );
107 
108  /**
109  * Constructor.
110  *
111  * \param module the module which is owner of this connector.
112  * \param name The name of this connector.
113  * \param description Short description of this connector.
114  */
115  WModuleInputData( boost::shared_ptr< WModule > module, std::string name = "", std::string description = "" ):
116  WModuleInputConnector( module, name, description ),
117  m_disconnecting( false )
118  {
119  };
120 
121  /**
122  * Destructor.
123  */
125  {
126  };
127 
128  /**
129  * Disconnects this connector if connected. If it is not connected: nothing happens.
130  *
131  * \param con the connector to disconnect.
132  * \param removeFromOwnList if true the specified connection is also removed from the own connection list. If false it won't.
133  */
134  virtual void disconnect( boost::shared_ptr<WModuleConnector> con, bool removeFromOwnList = true );
135 
136  /**
137  * Gives the currently set data and resets the update flag.
138  *
139  * \param reset reset the flag of updated() if true (default).
140  *
141  * \return the data currently set. NULL if no data has been sent yet or the connector is unconnected.
142  */
143  const boost::shared_ptr< T > getData( bool reset = true )
144  {
145  // get a lock
146  boost::shared_lock<boost::shared_mutex> lock = boost::shared_lock<boost::shared_mutex>( m_connectionListLock );
147 
148  // Only reset change flag of requested
149  if( reset )
150  {
151  handledUpdate();
152  }
153 
154  // is there something in the list?
155  if( m_disconnecting || m_connected.empty() )
156  {
157  lock.unlock();
158  return boost::shared_ptr< T >();
159  }
160 
161  // get data
162  boost::shared_ptr< T > dat = boost::dynamic_pointer_cast< T >(
163  boost::dynamic_pointer_cast< WModuleOutputConnector >( *m_connected.begin() )->getRawData()
164  );
165 
166  // unlock and return
167  lock.unlock();
168 
169  return dat;
170  };
171 
172  /**
173  * Checks whether the specified connector is an input connector and compatible with T.
174  *
175  * \param con the connector to check against.
176  *
177  * \return true if compatible.
178  */
179  virtual bool connectable( boost::shared_ptr<WModuleConnector> con )
180  {
181  // NOTE: please consider the following: the input only accepts data which is of type T or higher. So only up casts from
182  // con's type T2 to T are needed/allowed what ever
183 
185  {
186  return false;
187  }
188 
189  // this calls virtual function to achieve the prototype of the WTransferable created with the type specified in
190  // WOutputData< XYZ >
191  boost::shared_ptr< WPrototyped > tProto =
192  dynamic_cast< WModuleOutputConnector* >( con.get() )->getTransferPrototype(); // NOLINT
193 
194  // NOTE: Check the type of the transfered object and whether the connector is an output
195  return dynamic_cast< T* >( tProto.get() ); // NOLINT
196  };
197 
198 protected:
199 private:
200  /**
201  * If true, the returned data will be NULL. Needed because disconnection process is based on multiple steps.
202  */
203  bool m_disconnecting;
204 };
205 
206 template < typename T >
207 void WModuleInputData< T >::disconnect( boost::shared_ptr<WModuleConnector> con, bool removeFromOwnList )
208 {
209  m_disconnecting = true;
210  WModuleInputConnector::disconnect( con, removeFromOwnList );
211  m_disconnecting = false;
212 }
213 
214 template < typename T >
215 typename WModuleInputData< T >::PtrType WModuleInputData< T >::create( boost::shared_ptr< WModule > module, std::string name,
216  std::string description )
217 {
218  typedef typename WModuleInputData< T >::PtrType PTR;
219  typedef typename WModuleInputData< T >::Type TYPE;
220  return PTR( new TYPE( module, name, description ) );
221 }
222 
223 template < typename T >
224 typename WModuleInputData< T >::PtrType WModuleInputData< T >::createAndAdd( boost::shared_ptr< WModule > module, std::string name,
225  std::string description )
226 {
227  typename WModuleInputData< T >::PtrType c = create( module, name, description );
228  module->addConnector( c );
229  return c;
230 }
231 
232 #endif // WMODULEINPUTDATA_H
233 
WModuleInputData(boost::shared_ptr< WModule > module, std::string name="", std::string description="")
Constructor.
boost::shared_ptr< const WModuleInputData< T > > ConstSPtr
Pointer to this.
static PtrType create(boost::shared_ptr< WModule > module, std::string name="", std::string description="")
Convenience method to create a new instance of this in data connector with proper type...
virtual void disconnect(boost::shared_ptr< WModuleConnector > con, bool removeFromOwnList=true)
Disconnects this connector if connected.
boost::shared_ptr< WModuleInputData< T > > PtrType
Pointer to this.
WModuleInputData< T > & RefType
Reference to this type.
Class offering an instantiate-able data connection between modules.
Definition: WModule.h:75
Class offering an instantiate-able data connection between modules.
Definition: WModule.h:77
bool m_disconnecting
If true, the returned data will be NULL.
virtual ~WModuleInputData()
Destructor.
virtual void disconnect(boost::shared_ptr< WModuleConnector > con, bool removeFromOwnList=true)
Disconnects this connector if connected.
virtual bool connectable(boost::shared_ptr< WModuleConnector > con)
Checks whether the specified connector is an output connector.
T TransferType
Typedef to the contained transferable.
static PtrType createAndAdd(boost::shared_ptr< WModule > module, std::string name="", std::string description="")
Convenience method to create a new instance of this in data connector with proper type and add it to ...
Class implementing output connection functionality between modules.
boost::shared_mutex m_connectionListLock
Lock for avoiding concurrent write to m_Connected (multiple reader, single writer lock)...
virtual bool handledUpdate()
Resets the updated-flag.
Class implementing input connection functionality between modules.
virtual bool connectable(boost::shared_ptr< WModuleConnector > con)
Checks whether the specified connector is an input connector and compatible with T.
std::set< boost::shared_ptr< WModuleConnector > > m_connected
List of connectors connected to this connector.
boost::shared_ptr< WModuleInputData< T > > SPtr
Pointer to this.
WModuleInputData< T > Type
Type of the connector.
const boost::shared_ptr< T > getData(bool reset=true)
Gives the currently set data and resets the update flag.