OutPort.hxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 = ∈
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
00231 mVisuallyConnectedPorts.remove(&in);
00232 }
00233 else
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 }
00337
00338 #endif // __OutPort_hxx__
00339