CLAM-Development  1.4.0
OutPort.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #ifndef __OutPort_hxx__
23 #define __OutPort_hxx__
24 
25 #include "WritingRegion.hxx"
26 #include <typeinfo>
27 #include <list>
28 #include <string>
29 #include "InPort.hxx"
30 #include "InPortPublisher.hxx"
31 
32 namespace CLAM
33 {
34 
35 class Processing;
36 
38 {
39 public:
40  typedef std::list<InPortBase*> InPortsList;
41  OutPortBase( const std::string & name = "unnamed out port", Processing * proc = 0 );
42  virtual ~OutPortBase();
43  const std::string & GetName();
45  InPortsList::iterator BeginVisuallyConnectedInPorts();
46  InPortsList::iterator EndVisuallyConnectedInPorts();
47 
48  virtual void ConnectToIn(InPortBase& in) = 0;
49  virtual void DisconnectFromIn(InPortBase & in) = 0;
50  virtual void DisconnectFromAll()=0;
51  virtual bool IsVisuallyConnectedTo(InPortBase & in) = 0;
52  virtual bool IsConnectableTo(InPortBase & ) = 0;
53  virtual bool CanProduce()=0;
54  virtual int GetSize()=0;
55  virtual void SetSize(int newSize)=0;
56  virtual int GetHop()=0;
57  virtual void SetHop(int newHop)=0;
58  bool HasConnections(){ return mVisuallyConnectedPorts.size()!=0; }
59  virtual void CenterEvenRegions()=0;
60  void SetPublisher( OutPortBase& publisher);
61  void UnsetPublisher();
62  virtual bool IsPublisher() const { return false; }
63  virtual void UnpublishOutPort() =0;
64  virtual const std::type_info & GetTypeId() const = 0;
65 protected:
67  std::string mName;
70 };
71 
72 
73 template<typename Token>
74 class OutPort : public OutPortBase
75 {
80 public:
81  OutPort( const std::string & name = "unnamed out port", Processing * proc = 0 );
82  virtual ~OutPort();
83 
84  void DisconnectFromAll();
85  void ConnectToIn( InPortBase& in);
87  void DisconnectFromIn( InPortBase& in);
89  bool IsConnectableTo(InPortBase & in);
93 
94  Token & GetData(int offset=0);
95  void SetSize( int newSize );
96  int GetSize();
97  int GetHop();
98  void SetHop( int hop );
99  void Produce();
100  bool CanProduce();
101  void CenterEvenRegions();
102 
103  void UnpublishOutPort() {}
104  virtual const std::type_info & GetTypeId() const
105  {
106  return typeid(Token);
107  };
108 
109  Token & GetLastWrittenData( int offset = 0 );
110 protected:
111  bool ConnectToPublisher( ProperInPortPublisher & in );
112 
115 
117 
118 };
119 
120 template<class Token>
121 OutPort<Token>::OutPort( const std::string & name, Processing * proc )
122  : OutPortBase(name,proc)
123 {
124 }
125 
126 template<class Token>
128 {
129  InPortsList::iterator it = mVisuallyConnectedPorts.begin();
130  for( it=BeginVisuallyConnectedInPorts(); it!=EndVisuallyConnectedInPorts(); it++ )
131  {
132  (*it)->UnAttachRegion();
133  }
134  mVisuallyConnectedPorts.clear();
135 }
136 
137 template<class Token>
139 {
140  DisconnectFromAll();
141 }
142 
143 
144 template<class Token>
146 {
147 
148  InPortPublisher<Token> * publisher = &in;
149 
150  mVisuallyConnectedPorts.push_back( &in );
152  for( it=publisher->BeginPublishedInPortsList(); it!=publisher->EndPublishedInPortsList(); it++)
153  (*it)->AttachRegionToOutPort(this, mRegion );
154 
156 
157  return true;
158 }
159 
160 template<class Token>
162 {
163  CLAM_ASSERT( IsConnectableTo(in),
164  "OutPort<Token>::connectToIn coudn't connect to inPort "
165  "because was not templatized by the same Token type as outPort" );
166  if (in.IsPublisher())
167  ConnectToPublisher( static_cast<ProperInPortPublisher&>(in) );
168  else
169  ConnectToConcreteIn( static_cast<ProperInPort&>(in) );
170 }
171 
172 template<class Token>
174 {
175  CLAM_ASSERT( !in.GetVisuallyConnectedOutPort(), "OutPort<Token>::ConnectToConcreteIn - Trying to connect an inport "
176  "already connected to another out port" );
177  CLAM_ASSERT( !IsVisuallyConnectedTo(in), "OutPort<Token>::ConnectToConcreteIn - Trying to connect an in port "
178  "already connected to this out port" );
179  mVisuallyConnectedPorts.push_back(&in);
180  in.AttachRegionToOutPort(this, mRegion );
181 }
182 
183 template<class Token>
185 {
186  CLAM_ASSERT ( IsConnectableTo(in),
187  "OutPort<Token>::DisconnectFromIn coudn't discconnect from inPort "
188  "because was not templatized by the same Token type as outPort" );
189 
190  if (in.IsPublisher())
191  TryDisconnectFromPublisher( in );
192  else
193  TryDisconnectFromConcreteIn( in );
194 }
195 
196 template<class Token>
198 {
199  CLAM_ASSERT( IsConnectableTo(in), "TryDisconnectFromConcreteIn: expect the same token template");
200 
201  ProperInPort * concreteIn = static_cast<ProperInPort*>(&in);
202  DisconnectFromConcreteIn( *concreteIn );
203  return true;
204 }
205 
206 template<class Token>
208 {
209  CLAM_ASSERT( IsConnectableTo(in), "TryDisconnectFromPublisher: expect the same token template");
210 
211  InPortPublisher<Token> *publisher = static_cast<InPortPublisher<Token> *>(&in);
212 
213  mVisuallyConnectedPorts.remove( &in );
215  for( it=publisher->BeginPublishedInPortsList(); it!=publisher->EndPublishedInPortsList(); it++)
216  {
217  if( (*it)->GetVisuallyConnectedOutPort())
218  (*it)->UnAttachRegion();
219  }
220  return true;
221 }
222 
223 template<class Token>
225 {
226  CLAM_ASSERT( IsVisuallyConnectedTo(in) || IsPhysicallyConnectedToIn(in),
227  "OutPort::DisconnectFromConcreteIn() in port is not directly neither physically connected" );
228  if (IsVisuallyConnectedTo(in) )
229  {
230  // is directly connected
231  mVisuallyConnectedPorts.remove(&in);
232  }
233  else // then IsPhysicallyConnected()
234  {
235  InPortPublisher<Token> *pub = GetPublisherContaining(in);
236  CLAM_DEBUG_ASSERT(0!=pub, "in port should be published");
237  pub->UnPublishInPort(in);
238  }
239  in.UnAttachRegion();
240 }
241 
242 template<class Token>
243 Token & OutPort<Token>::GetData(int offset )
244 {
245  return mRegion[offset];
246 }
247 
248 template<class Token>
249 void OutPort<Token>::SetSize( int newSize )
250 {
251  mRegion.Size( newSize );
252 }
253 
254 template<class Token>
256 {
257  return mRegion.Size();
258 }
259 
260 template<class Token>
262 {
263  return mRegion.Hop();
264 }
265 
266 template<class Token>
267 void OutPort<Token>::SetHop( int hop )
268 {
269  mRegion.Hop(hop);
270 }
271 
272 template<class Token>
274 {
275  mRegion.Produce();
276 }
277 
278 template<class Token>
280 {
281  return mRegion.CanProduce();
282 }
283 
284 template<class Token>
286 {
287  return SameType(in.GetTypeId(), GetTypeId());
288 }
289 
290 template<class Token>
292 {
293  if (IsVisuallyConnectedTo(in))
294  return true;
295 
296  return ( 0!=GetPublisherContaining(in) );
297 
298 }
299 
300 template<class Token>
302 {
303 
304  InPortsList::iterator it;
305  for( it=mVisuallyConnectedPorts.begin(); it!=mVisuallyConnectedPorts.end(); it++ )
306  if ( (*it)->IsPublisherOf(in) )
307  return static_cast<InPortPublisher<Token> *>(*it);
308 
309  return 0;
310 
311 }
312 
313 template<class Token>
315 {
316  InPortsList::iterator it;
317  for( it=mVisuallyConnectedPorts.begin(); it!=mVisuallyConnectedPorts.end(); it++ )
318  if(*it == &in) return true;
319  return false;
320 }
321 
322 template<class Token>
324 {
325  mRegion.CenterEvenRegions();
326 }
327 
328 template<class Token>
330 {
331  CLAM_DEBUG_ASSERT( 0 <= offset, "OutPort<Token>::GetLastWrittenData - Index under bounds" );
332  CLAM_DEBUG_ASSERT( offset <= GetSize(), "OutPort<Token>::GetLastWrittenData - Index over bounds" );
333  return mRegion.GetLastWrittenData( offset );
334 }
335 
336 } // namespace CLAM
337 
338 #endif // __OutPort_hxx__
339