OpenWalnut  1.3.1
WModuleInputConnector.cpp
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 #include <string>
26 
27 // #include "WModule.h"
28 #include "WModuleOutputConnector.h"
29 #include "WModuleConnectorSignals.h"
30 #include "../common/WCondition.h"
31 
32 #include "WModuleInputConnector.h"
33 
34 WModuleInputConnector::WModuleInputConnector( boost::shared_ptr< WModule > module, std::string name, std::string description ):
35  WModuleConnector( module, name, description ),
36  m_updated( false )
37 {
38  // initialize members
39 
40  // connect some signals
41  // This signal is some kind of "forwarder" for the data_changed signal of an output connector.
42  signal_DataChanged.connect( getSignalHandler( DATA_CHANGED ) );
43 
44  // setup conditions
45  m_dataChangedCondition = boost::shared_ptr< WCondition >( new WCondition() );
46 
47  // if connection is closed, also fire "data change"
48  signal_ConnectionClosed.connect( boost::bind( &WModuleInputConnector::setUpdated, this ) );
50 }
51 
53 {
54  // cleanup
55  m_DataChangedConnection.disconnect();
56  signal_ConnectionClosed.disconnect_all_slots();
57 }
58 
59 bool WModuleInputConnector::connectable( boost::shared_ptr<WModuleConnector> con )
60 {
61  // output connectors are just allowed to get connected with input connectors
62  if( dynamic_cast<WModuleOutputConnector*>( con.get() ) ) // NOLINT - since we really need them here
63  {
64  return true;
65  }
66  return false;
67 }
68 
69 void WModuleInputConnector::connectSignals( boost::shared_ptr<WModuleConnector> con )
70 {
72 
73  // connect dataChange signal with an internal handler to ensure we can add the "input" connector pointer, since the output
74  // connector does not set this information.
75  // NOTE: con will be a WModuleOutputConnector
76  m_DataChangedConnection = con->subscribeSignal( DATA_CHANGED,
77  boost::bind( &WModuleInputConnector::notifyDataChange, this, _1, _2 )
78  );
79 }
80 
81 void WModuleInputConnector::disconnectSignals( boost::shared_ptr<WModuleConnector> con )
82 {
83  m_DataChangedConnection.disconnect();
84 
86 }
87 
88 boost::signals2::connection WModuleInputConnector::subscribeSignal( MODULE_CONNECTOR_SIGNAL signal,
89  t_GenericSignalHandlerType notifier )
90 {
91  // connect DataChanged signal
92  switch( signal )
93  {
94  case DATA_CHANGED:
95  return signal_DataChanged.connect( notifier );
96  default: // we do not know this signal: maybe the base class knows it
97  return WModuleConnector::subscribeSignal( signal, notifier );
98  }
99 }
100 
101 void WModuleInputConnector::notifyDataChange( boost::shared_ptr<WModuleConnector> /*input*/,
102  boost::shared_ptr<WModuleConnector> output )
103 {
104  setUpdated();
105 
106  // since the output connector is not able to fill the parameter "input" we need to forward this message and fill it with the
107  // proper information
108  signal_DataChanged( shared_from_this(), output );
109  m_dataChangedCondition->notify();
110 }
111 
112 boost::shared_ptr< WCondition > WModuleInputConnector::getDataChangedCondition()
113 {
114  return m_dataChangedCondition;
115 }
116 
117 void WModuleInputConnector::notifyConnectionEstablished( boost::shared_ptr<WModuleConnector> here, boost::shared_ptr<WModuleConnector> there )
118 {
119  // since the output connector is not able to fill the parameter "input" we need to forward this message and fill it with the
120  // proper information
121  // NOTE: connection established also emits a data changed signal since the data available at the connector has changed.
122  notifyDataChange( here, there );
123 
124  // forward
126 }
127 
129 {
130  return true;
131 }
132 
134 {
135  return false;
136 }
137 
139 {
140  boost::lock_guard<boost::shared_mutex> lock( m_updatedLock );
141  return m_updated;
142 }
143 
145 {
146  boost::lock_guard<boost::shared_mutex> lock( m_updatedLock );
147  m_updated = true;
148 }
149 
151 {
152  boost::lock_guard<boost::shared_mutex> lock( m_updatedLock );
153  bool old = m_updated;
154  m_updated = false;
155  return old;
156 }
157