OpenWalnut  1.5.0dev
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 <memory>
26 #include <string>
27 
28 #include "../common/WCondition.h"
29 #include "WModuleConnectorSignals.h"
30 #include "WModuleInputConnector.h"
31 #include "WModuleOutputConnector.h"
32 
33 WModuleInputConnector::WModuleInputConnector( std::shared_ptr< WModule > module, std::string name, std::string description ):
34  WModuleConnector( module, name, description ),
35  m_updated( false )
36 {
37  // connect some signals
38  // This signal is some kind of "forwarder" for the data_changed signal of an output connector.
39  signal_DataChanged.connect( getSignalHandler( DATA_CHANGED ) );
40 
41  // if connection is closed, also fire "data change"
42  signal_ConnectionClosed.connect( boost::bind( &WModuleInputConnector::setUpdated, this ) );
44 }
45 
47 {
48  // cleanup
49  m_DataChangedConnection.disconnect();
50  signal_ConnectionClosed.disconnect_all_slots();
51 }
52 
53 bool WModuleInputConnector::connectable( std::shared_ptr<WModuleConnector> con )
54 {
55  // output connectors are just allowed to get connected with input connectors
56  if( dynamic_cast<WModuleOutputConnector*>( con.get() ) ) // NOLINT - since we really need them here
57  {
58  return true;
59  }
60  return false;
61 }
62 
63 bool WModuleInputConnector::lazyConnectable( std::shared_ptr<WModuleConnector> con )
64 {
65  // output connectors are just allowed to get connected with input connectors
66  if( dynamic_cast<WModuleOutputConnector*>( con.get() ) ) // NOLINT - since we really need them here
67  {
68  return true;
69  }
70  return false;
71 }
72 
73 void WModuleInputConnector::connectSignals( std::shared_ptr<WModuleConnector> con )
74 {
76 
77  // connect dataChange signal with an internal handler to ensure we can add the "input" connector pointer, since the output
78  // connector does not set this information.
79  // NOTE: con will be a WModuleOutputConnector
80  m_DataChangedConnection = con->subscribeSignal( DATA_CHANGED,
81  boost::bind( &WModuleInputConnector::notifyDataChange, this, boost::placeholders::_1, boost::placeholders::_2 )
82  );
83 }
84 
85 void WModuleInputConnector::disconnectSignals( std::shared_ptr<WModuleConnector> con )
86 {
87  m_DataChangedConnection.disconnect();
88 
90 }
91 
92 boost::signals2::connection WModuleInputConnector::subscribeSignal( MODULE_CONNECTOR_SIGNAL signal,
93  t_GenericSignalHandlerType notifier )
94 {
95  // connect DataChanged signal
96  switch( signal )
97  {
98  case DATA_CHANGED:
99  return signal_DataChanged.connect( notifier );
100  default: // we do not know this signal: maybe the base class knows it
101  return WModuleConnector::subscribeSignal( signal, notifier );
102  }
103 }
104 
105 void WModuleInputConnector::notifyDataChange( std::shared_ptr<WModuleConnector> /*input*/,
106  std::shared_ptr<WModuleConnector> output )
107 {
108  setUpdated();
109 
110  // since the output connector is not able to fill the parameter "input" we need to forward this message and fill it with the
111  // proper information
112  signal_DataChanged( shared_from_this(), output );
113  m_dataChangedCondition->notify();
114 }
115 
116 void WModuleInputConnector::notifyConnectionEstablished( std::shared_ptr<WModuleConnector> here, std::shared_ptr<WModuleConnector> there )
117 {
118  // since the output connector is not able to fill the parameter "input" we need to forward this message and fill it with the
119  // proper information
120  // NOTE: connection established also emits a data changed signal since the data available at the connector has changed.
121  notifyDataChange( here, there );
122 
123  // forward
125 }
126 
128 {
129  return true;
130 }
131 
133 {
134  return false;
135 }
136 
138 {
139  boost::lock_guard<std::shared_mutex> lock( m_updatedLock );
140  return m_updated;
141 }
142 
144 {
145  boost::lock_guard<std::shared_mutex> lock( m_updatedLock );
146  m_updated = true;
147 }
148 
150 {
151  boost::lock_guard<std::shared_mutex> lock( m_updatedLock );
152  bool old = m_updated;
153  m_updated = false;
154  return old;
155 }
virtual void notify()
Notifies all waiting threads.
Definition: WCondition.cpp:44
Base class for modelling connections between kernel modules.
virtual const t_GenericSignalHandlerType getSignalHandler(MODULE_CONNECTOR_SIGNAL signal)
Gives the signal handler function responsible for a given signal.
virtual void connectSignals(std::shared_ptr< WModuleConnector > con)
Connect additional signals.
t_GenericSignalType signal_ConnectionClosed
Signal emitted whenever connection has been closed.
virtual void disconnectSignals(std::shared_ptr< WModuleConnector > con)
Disconnect all signals subscribed by this connector from "con".
virtual boost::signals2::connection subscribeSignal(MODULE_CONNECTOR_SIGNAL signal, t_GenericSignalHandlerType notifier)
Connects a specified notify function with a signal this module instance is offering.
virtual void notifyConnectionEstablished(std::shared_ptr< WModuleConnector > here, std::shared_ptr< WModuleConnector > there)
Gets called whenever a connector gets connected to the specified input.
std::shared_ptr< WCondition > m_dataChangedCondition
Condition fired whenever data changes.
virtual bool connectable(std::shared_ptr< WModuleConnector > con)
Checks whether the specified connector is an output connector.
virtual void disconnectSignals(std::shared_ptr< WModuleConnector > con)
Disconnect all signals subscribed by this connector from "con".
virtual bool isInputConnector() const
Returns true if this instance is an WModuleInputConnector.
virtual bool isOutputConnector() const
Returns true if this instance is an WModuleOutputConnector.
std::shared_mutex m_updatedLock
This lock protects the m_updated flag.
virtual bool updated()
Denotes whether the connected output was updated.
virtual bool handledUpdate()
Resets the updated-flag.
t_GenericSignalType signal_DataChanged
Signal for "DATA_CHANGED" Events.
virtual void setUpdated()
Sets the update flag (use updated() to query it)to true.
boost::signals2::connection subscribeSignal(MODULE_CONNECTOR_SIGNAL signal, t_GenericSignalHandlerType notifier)
Connects (subscribes) a specified notify function with a signal this module instance is offering.
virtual void connectSignals(std::shared_ptr< WModuleConnector > con)
Connect additional signals.
WModuleInputConnector(std::shared_ptr< WModule > module, std::string name="", std::string description="")
Constructor.
virtual bool lazyConnectable(std::shared_ptr< WModuleConnector > con)
Checks whether the specified connector is connectable to this one, but ignores compatibility the type...
virtual void notifyDataChange(std::shared_ptr< WModuleConnector > input, std::shared_ptr< WModuleConnector > output)
Gets called when the data on this input connector changed.
virtual void notifyConnectionEstablished(std::shared_ptr< WModuleConnector > here, std::shared_ptr< WModuleConnector > there)
Gets called whenever a connector gets connected to the specified input.
virtual ~WModuleInputConnector()
Destructor.
boost::signals2::connection m_DataChangedConnection
Connection for Data Changed signal of the connected output connector.
bool m_updated
A flag denoting that an update was received.
Class implementing output connection functionality between modules.