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 #include <boost/shared_ptr.hpp>
31 #include <boost/thread/locks.hpp>
32 
33 // this is necessary since we have some kind of cyclic includes
34 template < typename T > class WModuleOutputData;
35 #include "WModuleOutputData.h"
36 #include "exceptions/WModuleConnectorUnconnected.h"
37 #include "../common/WTransferable.h"
38 #include "../common/WPrototyped.h"
39 
40 #include "WModuleInputConnector.h"
41 #include "WModuleOutputConnector.h"
42 
43 /**
44  * Class offering an instantiate-able data connection between modules.
45  * Due to is template style it is possible to bind nearly arbitrary data.
46  */
47 template < typename T >
49 {
50 public:
51  /**
52  * Pointer to this. For convenience.
53  */
54  typedef boost::shared_ptr< WModuleInputData< T > > PtrType;
55 
56  /**
57  * Pointer to this. For convenience.
58  */
59  typedef boost::shared_ptr< WModuleInputData< T > > SPtr;
60 
61  /**
62  * Pointer to this. For convenience.
63  */
64  typedef boost::shared_ptr< const WModuleInputData< T > > ConstSPtr;
65 
66  /**
67  * Reference to this type.
68  */
70 
71  /**
72  * Type of the connector.
73  */
75 
76  /**
77  * Typedef to the contained transferable.
78  */
79  typedef T TransferType;
80 
81  /**
82  * Convenience method to create a new instance of this in data connector with proper type.
83  *
84  * \param module the module owning this instance
85  * \param name the name of this connector.
86  * \param description the description of this connector.
87  *
88  * \return the pointer to the created connector.
89  */
90  static PtrType create( boost::shared_ptr< WModule > module, std::string name = "", std::string description = "" );
91 
92  /**
93  * 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
94  * specified module.
95  *
96  * \param module the module owning this instance
97  * \param name the name of this connector.
98  * \param description the description of this connector.
99  *
100  * \return the pointer to the created connector.
101  */
102  static PtrType createAndAdd( boost::shared_ptr< WModule > module, std::string name = "", std::string description = "" );
103 
104  /**
105  * Constructor.
106  *
107  * \param module the module which is owner of this connector.
108  * \param name The name of this connector.
109  * \param description Short description of this connector.
110  */
111  WModuleInputData( boost::shared_ptr< WModule > module, std::string name = "", std::string description = "" ):
112  WModuleInputConnector( module, name, description ),
113  m_disconnecting( false )
114  {
115  };
116 
117  /**
118  * Destructor.
119  */
121  {
122  };
123 
124  /**
125  * Disconnects this connector if connected. If it is not connected: nothing happens.
126  *
127  * \param con the connector to disconnect.
128  * \param removeFromOwnList if true the specified connection is also removed from the own connection list. If false it won't.
129  */
130  virtual void disconnect( boost::shared_ptr<WModuleConnector> con, bool removeFromOwnList = true );
131 
132  /**
133  * Gives the currently set data and resets the update flag.
134  *
135  * \param reset reset the flag of updated() if true (default).
136  *
137  * \return the data currently set. NULL if no data has been sent yet or the connector is unconnected.
138  */
139  const boost::shared_ptr< T > getData( bool reset = true )
140  {
141  // get a lock
142  boost::shared_lock<boost::shared_mutex> lock = boost::shared_lock<boost::shared_mutex>( m_connectionListLock );
143 
144  // Only reset change flag of requested
145  if( reset )
146  {
147  handledUpdate();
148  }
149 
150  // is there something in the list?
151  if( m_disconnecting || m_connected.empty() )
152  {
153  lock.unlock();
154  return boost::shared_ptr< T >();
155  }
156 
157  // get data
158  boost::shared_ptr< T > dat = boost::dynamic_pointer_cast< T >(
159  boost::dynamic_pointer_cast< WModuleOutputConnector >( *m_connected.begin() )->getRawData()
160  );
161 
162  // unlock and return
163  lock.unlock();
164 
165  return dat;
166  };
167 
168  /**
169  * Checks whether the specified connector is an input connector and compatible with T.
170  *
171  * \param con the connector to check against.
172  *
173  * \return true if compatible.
174  */
175  virtual bool connectable( boost::shared_ptr<WModuleConnector> con )
176  {
177  // NOTE: please consider the following: the input only accepts data which is of type T or higher. So only up casts from
178  // con's type T2 to T are needed/allowed what ever
179 
181  {
182  return false;
183  }
184 
185  // this calls virtual function to achieve the prototype of the WTransferable created with the type specified in
186  // WOutputData< XYZ >
187  boost::shared_ptr< WPrototyped > tProto =
188  dynamic_cast< WModuleOutputConnector* >( con.get() )->getTransferPrototype(); // NOLINT
189 
190  // NOTE: Check the type of the transfered object and whether the connector is an output
191  return dynamic_cast< T* >( tProto.get() ); // NOLINT
192  };
193 
194 protected:
195 private:
196  /**
197  * If true, the returned data will be NULL. Needed because disconnection process is based on multiple steps.
198  */
199  bool m_disconnecting;
200 };
201 
202 template < typename T >
203 void WModuleInputData< T >::disconnect( boost::shared_ptr<WModuleConnector> con, bool removeFromOwnList )
204 {
205  m_disconnecting = true;
206  WModuleInputConnector::disconnect( con, removeFromOwnList );
207  m_disconnecting = false;
208 }
209 
210 template < typename T >
211 typename WModuleInputData< T >::PtrType WModuleInputData< T >::create( boost::shared_ptr< WModule > module, std::string name,
212  std::string description )
213 {
214  typedef typename WModuleInputData< T >::PtrType PTR;
215  typedef typename WModuleInputData< T >::Type TYPE;
216  return PTR( new TYPE( module, name, description ) );
217 }
218 
219 template < typename T >
220 typename WModuleInputData< T >::PtrType WModuleInputData< T >::createAndAdd( boost::shared_ptr< WModule > module, std::string name,
221  std::string description )
222 {
223  typename WModuleInputData< T >::PtrType c = create( module, name, description );
224  module->addConnector( c );
225  return c;
226 }
227 
228 #endif // WMODULEINPUTDATA_H
229 
virtual void disconnect(boost::shared_ptr< WModuleConnector > con, bool removeFromOwnList=true)
Disconnects this connector if connected.
Class offering an instantiate-able data connection between modules.
Definition: WModule.h:63
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 bool connectable(boost::shared_ptr< WModuleConnector > con)
Checks whether the specified connector is an input connector and compatible with T.
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.
virtual ~WModuleInputData()
Destructor.
const boost::shared_ptr< T > getData(bool reset=true)
Gives the currently set data and resets the update flag.
virtual bool connectable(boost::shared_ptr< WModuleConnector > con)
Checks whether the specified connector is an output connector.
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 ...
T TransferType
Typedef to the contained transferable.
boost::shared_ptr< const WModuleInputData< T > > ConstSPtr
Pointer to this.
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.
WModuleInputData< T > Type
Type of the connector.
Class implementing input connection functionality between modules.
Class offering an instantiate-able data connection between modules.
Definition: WModule.h:65
WModuleInputData(boost::shared_ptr< WModule > module, std::string name="", std::string description="")
Constructor.
bool m_disconnecting
If true, the returned data will be NULL.
std::set< boost::shared_ptr< WModuleConnector > > m_connected
List of connectors connected to this connector.
WModuleInputData< T > & RefType
Reference to this type.
boost::shared_ptr< WModuleInputData< T > > SPtr
Pointer to this.