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