OpenWalnut
1.4.0
|
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