OpenWalnut 1.2.5
|
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 00031 #include "WModuleInputConnector.h" 00032 00033 WModuleInputConnector::WModuleInputConnector( boost::shared_ptr< WModule > module, std::string name, std::string description ): 00034 WModuleConnector( module, name, description ), 00035 m_updated( false ) 00036 { 00037 // initialize members 00038 00039 // connect some signals 00040 // This signal is some kind of "forwarder" for the data_changed signal of an output connector. 00041 signal_DataChanged.connect( getSignalHandler( DATA_CHANGED ) ); 00042 00043 // setup conditions 00044 m_dataChangedCondition = boost::shared_ptr< WCondition >( new WCondition() ); 00045 00046 // if connection is closed, also fire "data change" 00047 signal_ConnectionClosed.connect( boost::bind( &WModuleInputConnector::setUpdated, this ) ); 00048 signal_ConnectionClosed.connect( boost::bind( &WCondition::notify, m_dataChangedCondition ) ); 00049 } 00050 00051 WModuleInputConnector::~WModuleInputConnector() 00052 { 00053 // cleanup 00054 m_DataChangedConnection.disconnect(); 00055 signal_ConnectionClosed.disconnect_all_slots(); 00056 } 00057 00058 bool WModuleInputConnector::connectable( boost::shared_ptr<WModuleConnector> con ) 00059 { 00060 // output connectors are just allowed to get connected with input connectors 00061 if( dynamic_cast<WModuleOutputConnector*>( con.get() ) ) // NOLINT - since we really need them here 00062 { 00063 return true; 00064 } 00065 return false; 00066 } 00067 00068 void WModuleInputConnector::connectSignals( boost::shared_ptr<WModuleConnector> con ) 00069 { 00070 WModuleConnector::connectSignals( con ); 00071 00072 // connect dataChange signal with an internal handler to ensure we can add the "input" connector pointer, since the output 00073 // connector does not set this information. 00074 // NOTE: con will be a WModuleOutputConnector 00075 m_DataChangedConnection = con->subscribeSignal( DATA_CHANGED, 00076 boost::bind( &WModuleInputConnector::notifyDataChange, this, _1, _2 ) 00077 ); 00078 } 00079 00080 void WModuleInputConnector::disconnectSignals( boost::shared_ptr<WModuleConnector> con ) 00081 { 00082 m_DataChangedConnection.disconnect(); 00083 00084 WModuleConnector::disconnectSignals( con ); 00085 } 00086 00087 boost::signals2::connection WModuleInputConnector::subscribeSignal( MODULE_CONNECTOR_SIGNAL signal, 00088 t_GenericSignalHandlerType notifier ) 00089 { 00090 // connect DataChanged signal 00091 switch ( signal ) 00092 { 00093 case DATA_CHANGED: 00094 return signal_DataChanged.connect( notifier ); 00095 default: // we do not know this signal: maybe the base class knows it 00096 return WModuleConnector::subscribeSignal( signal, notifier ); 00097 } 00098 } 00099 00100 void WModuleInputConnector::notifyDataChange( boost::shared_ptr<WModuleConnector> /*input*/, 00101 boost::shared_ptr<WModuleConnector> output ) 00102 { 00103 setUpdated(); 00104 00105 // since the output connector is not able to fill the parameter "input" we need to forward this message and fill it with the 00106 // proper information 00107 signal_DataChanged( shared_from_this(), output ); 00108 m_dataChangedCondition->notify(); 00109 } 00110 00111 boost::shared_ptr< WCondition > WModuleInputConnector::getDataChangedCondition() 00112 { 00113 return m_dataChangedCondition; 00114 } 00115 00116 void WModuleInputConnector::notifyConnectionEstablished( boost::shared_ptr<WModuleConnector> here, boost::shared_ptr<WModuleConnector> there ) 00117 { 00118 // since the output connector is not able to fill the parameter "input" we need to forward this message and fill it with the 00119 // proper information 00120 // NOTE: connection established also emits a data changed signal since the data available at the connector has changed. 00121 notifyDataChange( here, there ); 00122 00123 // forward 00124 WModuleConnector::notifyConnectionEstablished( here, there ); 00125 } 00126 00127 bool WModuleInputConnector::isInputConnector() const 00128 { 00129 return true; 00130 } 00131 00132 bool WModuleInputConnector::isOutputConnector() const 00133 { 00134 return false; 00135 } 00136 00137 bool WModuleInputConnector::updated() 00138 { 00139 boost::lock_guard<boost::shared_mutex> lock( m_updatedLock ); 00140 return m_updated; 00141 } 00142 00143 void WModuleInputConnector::setUpdated() 00144 { 00145 boost::lock_guard<boost::shared_mutex> lock( m_updatedLock ); 00146 m_updated = true; 00147 } 00148 00149 bool WModuleInputConnector::handledUpdate() 00150 { 00151 boost::lock_guard<boost::shared_mutex> lock( m_updatedLock ); 00152 bool old = m_updated; 00153 m_updated = false; 00154 return old; 00155 } 00156