OpenWalnut  1.4.0
WModuleInputConnector.cpp
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #include <string>
00026 
00027 // #include "WModule.h"
00028 #include "WModuleOutputConnector.h"
00029 #include "WModuleConnectorSignals.h"
00030 #include "../common/WCondition.h"
00031 
00032 #include "WModuleInputConnector.h"
00033 
00034 WModuleInputConnector::WModuleInputConnector( boost::shared_ptr< WModule > module, std::string name, std::string description ):
00035     WModuleConnector( module, name, description ),
00036     m_updated( false )
00037 {
00038     // initialize members
00039 
00040     // connect some signals
00041     // This signal is some kind of "forwarder" for the data_changed signal of an output connector.
00042     signal_DataChanged.connect( getSignalHandler( DATA_CHANGED ) );
00043 
00044     // setup conditions
00045     m_dataChangedCondition = boost::shared_ptr< WCondition >( new WCondition() );
00046 
00047     // if connection is closed, also fire "data change"
00048     signal_ConnectionClosed.connect( boost::bind( &WModuleInputConnector::setUpdated, this ) );
00049     signal_ConnectionClosed.connect( boost::bind( &WCondition::notify, m_dataChangedCondition ) );
00050 }
00051 
00052 WModuleInputConnector::~WModuleInputConnector()
00053 {
00054     // cleanup
00055     m_DataChangedConnection.disconnect();
00056     signal_ConnectionClosed.disconnect_all_slots();
00057 }
00058 
00059 bool WModuleInputConnector::connectable( boost::shared_ptr<WModuleConnector> con )
00060 {
00061     // output connectors are just allowed to get connected with input connectors
00062     if( dynamic_cast<WModuleOutputConnector*>( con.get() ) )   // NOLINT - since we really need them here
00063     {
00064         return true;
00065     }
00066     return false;
00067 }
00068 
00069 void WModuleInputConnector::connectSignals( boost::shared_ptr<WModuleConnector> con )
00070 {
00071     WModuleConnector::connectSignals( con );
00072 
00073     // connect dataChange signal with an internal handler to ensure we can add the "input" connector pointer, since the output
00074     // connector does not set this information.
00075     // NOTE: con will be a WModuleOutputConnector
00076     m_DataChangedConnection = con->subscribeSignal( DATA_CHANGED,
00077         boost::bind( &WModuleInputConnector::notifyDataChange, this, _1, _2 )
00078     );
00079 }
00080 
00081 void WModuleInputConnector::disconnectSignals( boost::shared_ptr<WModuleConnector> con )
00082 {
00083     m_DataChangedConnection.disconnect();
00084 
00085     WModuleConnector::disconnectSignals( con );
00086 }
00087 
00088 boost::signals2::connection WModuleInputConnector::subscribeSignal( MODULE_CONNECTOR_SIGNAL signal,
00089                                                                     t_GenericSignalHandlerType notifier )
00090 {
00091     // connect DataChanged signal
00092     switch( signal )
00093     {
00094         case DATA_CHANGED:
00095             return signal_DataChanged.connect( notifier );
00096         default:    // we do not know this signal: maybe the base class knows it
00097             return WModuleConnector::subscribeSignal( signal, notifier );
00098     }
00099 }
00100 
00101 void WModuleInputConnector::notifyDataChange( boost::shared_ptr<WModuleConnector> /*input*/,
00102                                               boost::shared_ptr<WModuleConnector> output )
00103 {
00104     setUpdated();
00105 
00106     // since the output connector is not able to fill the parameter "input" we need to forward this message and fill it with the
00107     // proper information
00108     signal_DataChanged( shared_from_this(), output );
00109     m_dataChangedCondition->notify();
00110 }
00111 
00112 boost::shared_ptr< WCondition > WModuleInputConnector::getDataChangedCondition()
00113 {
00114     return m_dataChangedCondition;
00115 }
00116 
00117 void WModuleInputConnector::notifyConnectionEstablished( boost::shared_ptr<WModuleConnector> here, boost::shared_ptr<WModuleConnector> there )
00118 {
00119     // since the output connector is not able to fill the parameter "input" we need to forward this message and fill it with the
00120     // proper information
00121     // NOTE: connection established also emits a data changed signal since the data available at the connector has changed.
00122     notifyDataChange( here, there );
00123 
00124     // forward
00125     WModuleConnector::notifyConnectionEstablished( here, there );
00126 }
00127 
00128 bool WModuleInputConnector::isInputConnector() const
00129 {
00130     return true;
00131 }
00132 
00133 bool WModuleInputConnector::isOutputConnector() const
00134 {
00135     return false;
00136 }
00137 
00138 bool WModuleInputConnector::updated()
00139 {
00140     boost::lock_guard<boost::shared_mutex> lock( m_updatedLock );
00141     return m_updated;
00142 }
00143 
00144 void WModuleInputConnector::setUpdated()
00145 {
00146     boost::lock_guard<boost::shared_mutex> lock( m_updatedLock );
00147     m_updated = true;
00148 }
00149 
00150 bool WModuleInputConnector::handledUpdate()
00151 {
00152     boost::lock_guard<boost::shared_mutex> lock( m_updatedLock );
00153     bool old = m_updated;
00154     m_updated = false;
00155     return old;
00156 }
00157