OutPort.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #ifndef __OutPort_hxx__
00023 #define __OutPort_hxx__
00024 
00025 #include "WritingRegion.hxx"
00026 #include <typeinfo>
00027 #include <list>
00028 #include <string>
00029 #include "InPort.hxx"
00030 #include "InPortPublisher.hxx"
00031 
00032 namespace CLAM
00033 {
00034 
00035 class Processing;
00036 
00037 class OutPortBase
00038 {
00039 public:
00040         typedef std::list<InPortBase*> InPortsList;
00041         OutPortBase( const std::string & name = "unnamed out port", Processing * proc = 0 );
00042         virtual ~OutPortBase();
00043         const std::string & GetName();
00044         Processing * GetProcessing();
00045         InPortsList::iterator BeginVisuallyConnectedInPorts();
00046         InPortsList::iterator EndVisuallyConnectedInPorts();
00047         
00048         virtual void ConnectToIn(InPortBase& in) = 0;
00049         virtual void DisconnectFromIn(InPortBase & in) = 0;
00050         virtual void DisconnectFromAll()=0;
00051         virtual bool IsVisuallyConnectedTo(InPortBase & in) = 0;
00052         virtual bool IsConnectableTo(InPortBase & ) = 0;
00053         virtual bool CanProduce()=0;
00054         virtual int GetSize()=0;
00055         virtual void SetSize(int newSize)=0;
00056         virtual int GetHop()=0;
00057         virtual void SetHop(int newHop)=0;
00058         bool HasConnections(){ return mVisuallyConnectedPorts.size()!=0; }
00059         virtual void CenterEvenRegions()=0;
00060         void SetPublisher( OutPortBase& publisher); 
00061         void UnsetPublisher(); 
00062         virtual bool IsPublisher() const { return false; }
00063         virtual void UnpublishOutPort() =0;
00064         virtual const std::type_info & GetTypeId() const = 0;
00065 protected:
00066         InPortsList mVisuallyConnectedPorts;    
00067         std::string mName;
00068         Processing * mProcessing;
00069         OutPortBase* mPublisher;
00070 };
00071 
00072 
00073 template<typename Token>
00074 class OutPort : public OutPortBase
00075 {
00076         typedef OutPort<Token> ProperOutPort;
00077         typedef InPort<Token> ProperInPort;
00078         typedef InPortPublisher<Token> ProperInPortPublisher;
00079         typedef WritingRegion<Token> ProperWritingRegion;
00080 public:
00081         OutPort( const std::string & name = "unnamed out port", Processing * proc = 0 );
00082         virtual ~OutPort();
00083 
00084         void DisconnectFromAll();
00085         void ConnectToIn( InPortBase& in);
00086         void ConnectToConcreteIn(InPort<Token>& in);
00087         void DisconnectFromIn( InPortBase& in);
00088         void DisconnectFromConcreteIn(InPort<Token>& in);
00089         bool IsConnectableTo(InPortBase & in);
00090         bool IsVisuallyConnectedTo(InPortBase & in);
00091         bool IsPhysicallyConnectedToIn(InPort<Token>& ); 
00092         InPortPublisher<Token>* GetPublisherContaining(InPort<Token>&);
00093 
00094         Token & GetData(int offset=0);  
00095         void SetSize( int newSize );
00096         int GetSize();
00097         int GetHop();
00098         void SetHop( int hop ); 
00099         void Produce();
00100         bool CanProduce();
00101         void CenterEvenRegions();
00102         
00103         void UnpublishOutPort() {} 
00104         virtual const std::type_info & GetTypeId() const
00105         {
00106                 return typeid(Token);
00107         };
00108 
00109         Token & GetLastWrittenData( int offset = 0 );
00110 protected:      
00111         bool ConnectToPublisher( ProperInPortPublisher & in );
00112 
00113         bool TryDisconnectFromPublisher( InPortBase & in );
00114         bool TryDisconnectFromConcreteIn( InPortBase & in );
00115 
00116         ProperWritingRegion mRegion;
00117 
00118 };
00119 
00120 template<class Token>
00121 OutPort<Token>::OutPort( const std::string & name, Processing * proc )
00122         : OutPortBase(name,proc)
00123 {
00124 }
00125 
00126 template<class Token>
00127 void OutPort<Token>::DisconnectFromAll()
00128 {
00129         InPortsList::iterator it = mVisuallyConnectedPorts.begin();
00130         for( it=BeginVisuallyConnectedInPorts(); it!=EndVisuallyConnectedInPorts(); it++ )      
00131         { 
00132                 (*it)->UnAttachRegion();
00133         }
00134         mVisuallyConnectedPorts.clear();
00135 }
00136 
00137 template<class Token>
00138 OutPort<Token>::~OutPort()
00139 {
00140         DisconnectFromAll();
00141 }
00142 
00143 
00144 template<class Token>
00145 bool OutPort<Token>::ConnectToPublisher( InPortPublisher<Token> & in )
00146 {
00147          
00148         InPortPublisher<Token> * publisher =  &in;
00149         
00150         mVisuallyConnectedPorts.push_back( &in );
00151         typename InPortPublisher<Token>::ProperInPortsList::iterator it;
00152         for( it=publisher->BeginPublishedInPortsList(); it!=publisher->EndPublishedInPortsList(); it++)
00153                 (*it)->AttachRegionToOutPort(this, mRegion );
00154 
00155         in.SetVisuallyConnectedOutPort(this);
00156 
00157         return true;
00158 }
00159 
00160 template<class Token>
00161 void OutPort<Token>::ConnectToIn( InPortBase& in)
00162 {
00163         CLAM_ASSERT( IsConnectableTo(in),
00164                      "OutPort<Token>::connectToIn coudn't connect to inPort "
00165                      "because was not templatized by the same Token type as outPort" );
00166         if (in.IsPublisher())
00167                 ConnectToPublisher( static_cast<ProperInPortPublisher&>(in) );
00168         else
00169                 ConnectToConcreteIn( static_cast<ProperInPort&>(in) );
00170 }
00171 
00172 template<class Token>
00173 void OutPort<Token>::ConnectToConcreteIn(InPort<Token>& in)
00174 {
00175         CLAM_ASSERT( !in.GetVisuallyConnectedOutPort(), "OutPort<Token>::ConnectToConcreteIn - Trying to connect an inport "
00176                                                     "already connected to another out port" );
00177         CLAM_ASSERT( !IsVisuallyConnectedTo(in), "OutPort<Token>::ConnectToConcreteIn - Trying to connect an in port "
00178                                         "already connected to this out port" );
00179         mVisuallyConnectedPorts.push_back(&in);
00180         in.AttachRegionToOutPort(this, mRegion );
00181 }
00182 
00183 template<class Token>
00184 void OutPort<Token>::DisconnectFromIn( InPortBase& in)
00185 {
00186         CLAM_ASSERT ( IsConnectableTo(in), 
00187                      "OutPort<Token>::DisconnectFromIn coudn't discconnect from inPort "
00188                      "because was not templatized by the same Token type as outPort" );
00189 
00190         if (in.IsPublisher()) 
00191                 TryDisconnectFromPublisher( in );
00192         else 
00193                 TryDisconnectFromConcreteIn( in );
00194 }
00195 
00196 template<class Token>
00197 bool OutPort<Token>::TryDisconnectFromConcreteIn( InPortBase & in )
00198 {
00199         CLAM_ASSERT( IsConnectableTo(in), "TryDisconnectFromConcreteIn: expect the same token template");
00200 
00201         ProperInPort * concreteIn = static_cast<ProperInPort*>(&in);
00202         DisconnectFromConcreteIn( *concreteIn );
00203         return true;
00204 }
00205 
00206 template<class Token>
00207 bool OutPort<Token>::TryDisconnectFromPublisher( InPortBase & in )
00208 {
00209         CLAM_ASSERT( IsConnectableTo(in), "TryDisconnectFromPublisher: expect the same token template");
00210 
00211         InPortPublisher<Token> *publisher = static_cast<InPortPublisher<Token> *>(&in);
00212         
00213         mVisuallyConnectedPorts.remove( &in );
00214         typename InPortPublisher<Token>::ProperInPortsList::iterator it;
00215         for( it=publisher->BeginPublishedInPortsList(); it!=publisher->EndPublishedInPortsList(); it++)
00216         {
00217                 if( (*it)->GetVisuallyConnectedOutPort())
00218                         (*it)->UnAttachRegion();
00219         }
00220         return true;
00221 }
00222 
00223 template<class Token>
00224 void OutPort<Token>::DisconnectFromConcreteIn(InPort<Token>& in)
00225 {
00226         CLAM_ASSERT( IsVisuallyConnectedTo(in) || IsPhysicallyConnectedToIn(in), 
00227                         "OutPort::DisconnectFromConcreteIn() in port is not directly neither physically connected" );
00228         if (IsVisuallyConnectedTo(in) )
00229         {
00230                 // is directly connected
00231                 mVisuallyConnectedPorts.remove(&in);
00232         }
00233         else // then IsPhysicallyConnected()
00234         {
00235                 InPortPublisher<Token> *pub = GetPublisherContaining(in);
00236                 CLAM_DEBUG_ASSERT(0!=pub, "in port should be published");
00237                 pub->UnPublishInPort(in);
00238         }
00239         in.UnAttachRegion();
00240 }
00241 
00242 template<class Token>
00243 Token & OutPort<Token>::GetData(int offset )
00244 {
00245         return mRegion[offset];
00246 }
00247 
00248 template<class Token>
00249 void OutPort<Token>::SetSize( int newSize )
00250 {
00251         mRegion.Size( newSize );
00252 }
00253 
00254 template<class Token>
00255 int OutPort<Token>::GetSize()
00256 {
00257         return mRegion.Size();
00258 }
00259 
00260 template<class Token>
00261 int OutPort<Token>::GetHop()
00262 {
00263         return mRegion.Hop();
00264 }
00265 
00266 template<class Token>
00267 void OutPort<Token>::SetHop( int hop )
00268 {
00269         mRegion.Hop(hop);
00270 }
00271 
00272 template<class Token>
00273 void OutPort<Token>::Produce()
00274 {
00275         mRegion.Produce();
00276 }
00277 
00278 template<class Token>
00279 bool OutPort<Token>::CanProduce()
00280 {
00281         return mRegion.CanProduce();
00282 }
00283 
00284 template<class Token>
00285 bool OutPort<Token>::IsConnectableTo(InPortBase & in)
00286 {       
00287         return SameType(in.GetTypeId(), GetTypeId());
00288 }
00289 
00290 template<class Token>
00291 bool OutPort<Token>::IsPhysicallyConnectedToIn(InPort<Token>& in)
00292 { 
00293         if (IsVisuallyConnectedTo(in))
00294                 return true;
00295         
00296         return ( 0!=GetPublisherContaining(in) );
00297         
00298 }
00299 
00300 template<class Token>
00301 InPortPublisher<Token>* OutPort<Token>::GetPublisherContaining(InPort<Token>& in)
00302 {
00303         
00304         InPortsList::iterator it;
00305         for( it=mVisuallyConnectedPorts.begin(); it!=mVisuallyConnectedPorts.end(); it++ )
00306                 if ( (*it)->IsPublisherOf(in) )
00307                         return static_cast<InPortPublisher<Token> *>(*it);
00308 
00309         return 0;
00310                 
00311 }
00312 
00313 template<class Token>
00314 bool OutPort<Token>::IsVisuallyConnectedTo(InPortBase & in)
00315 {
00316         InPortsList::iterator it;
00317         for( it=mVisuallyConnectedPorts.begin(); it!=mVisuallyConnectedPorts.end(); it++ )
00318                 if(*it == &in) return true;
00319         return false;
00320 }
00321         
00322 template<class Token>
00323 void OutPort<Token>::CenterEvenRegions()
00324 {
00325         mRegion.CenterEvenRegions();
00326 }
00327 
00328 template<class Token>
00329 Token & OutPort<Token>::GetLastWrittenData( int offset )
00330 {
00331         CLAM_DEBUG_ASSERT( 0 <= offset, "OutPort<Token>::GetLastWrittenData - Index under bounds" );
00332         CLAM_DEBUG_ASSERT( offset <= GetSize(), "OutPort<Token>::GetLastWrittenData - Index over bounds" );
00333         return mRegion.GetLastWrittenData( offset );
00334 }
00335 
00336 } // namespace CLAM
00337 
00338 #endif // __OutPort_hxx__
00339 
Generated by  doxygen 1.6.3