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