]> Creatis software - bbtk.git/blob - kernel/src/bbtkConnection.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkConnection.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkConnection.cxx,v $
4   Language:  C++
5   Date:      $Date: 2008/12/11 09:50:35 $
6   Version:   $Revision: 1.19 $
7 =========================================================================*/
8
9 /* ---------------------------------------------------------------------
10
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
13 *
14 *  This software is governed by the CeCILL-B license under French law and 
15 *  abiding by the rules of distribution of free software. You can  use, 
16 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
17 *  license as circulated by CEA, CNRS and INRIA at the following URL 
18 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
19 *  or in the file LICENSE.txt.
20 *
21 *  As a counterpart to the access to the source code and  rights to copy,
22 *  modify and redistribute granted by the license, users are provided only
23 *  with a limited warranty  and the software's author,  the holder of the
24 *  economic rights,  and the successive licensors  have only  limited
25 *  liability. 
26 *
27 *  The fact that you are presently reading this means that you have had
28 *  knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */                                                                         
30
31 /**
32  *\file
33  *\brief Class bbtk::Connection
34  */
35
36 #include "bbtkConnection.h"
37 #include "bbtkFactory.h"
38 #include "bbtkBlackBox.h"
39 #include "bbtkMessageManager.h"
40 #include "bbtkBlackBoxOutputConnector.h"
41
42 namespace bbtk
43 {
44   const std::string IOSTATUS_STRING[3] = 
45     {"Up-to-date","Modified","Out-of-date"}; 
46   
47   const std::string& GetIOStatusString(IOStatus s)
48   { return IOSTATUS_STRING[s]; }
49
50   //==================================================================
51   Connection::Pointer Connection::New(BlackBox::Pointer from, 
52                                       const std::string& output,
53                                       BlackBox::Pointer to, 
54                                       const std::string& input ,
55                                       const Factory::Pointer f  )
56   {
57     bbtkDebugMessage("object",1,"##> Connection::Connection(\""
58                      <<from->bbGetName()<<"\",\""<<output<<"\",\""
59                      <<to->bbGetName()<<"\",\""<<input<<"\")"
60                      <<std::endl);
61     Connection::Pointer p = 
62       MakePointer(new Connection(from,output,to,input,f));
63     bbtkDebugMessage("object",1,"<## Connection::Connection(\""
64                      <<from->bbGetName()<<"\",\""<<output<<"\",\""
65                      <<to->bbGetName()<<"\",\""<<input<<"\")"
66                      <<std::endl);
67     return p;
68   }
69   //==================================================================
70
71   //==================================================================
72   /// Ctor with the black box from and to and their input and output.
73 /// Check the input and output compatibility
74 Connection::Connection(BlackBox::Pointer from, const std::string& output,
75                        BlackBox::Pointer to, const std::string& input ,
76                        const Factory::Pointer f  )
77     : mAdaptor(),
78       mFactory(f),
79       mFromAny(false),
80       mToAny(false)
81   {
82     bbtkDebugMessage("object",2,"==> Connection::Connection(\""
83                      <<from->bbGetName()<<"\",\""<<output<<"\",\""
84                      <<to->bbGetName()<<"\",\""<<input<<"\")"
85                      <<std::endl);    
86
87     bbtkDebugMessage("connection",1,"==> Connection::Connection(\""
88                      <<from->bbGetFullName()<<"\",\""<<output<<"\",\""
89                      <<to->bbGetFullName()<<"\",\""<<input<<"\")"
90                      <<std::endl);    
91
92     
93
94     if (! from->bbHasOutput(output) )
95       {
96         bbtkError("The box \""<<from->bbGetTypeName()<<
97                   "\" has no output \""<<output<<"\"");
98       }
99     if (! to->bbHasInput(input) )
100       {
101         bbtkError("The box \""<<to->bbGetTypeName()<<
102                   "\" has no input \""<<input<<"\"");
103       } 
104
105     if (to->bbGetInputConnectorMap().find(input)->second->IsConnected())
106       {
107         bbtkError("The input \""<<input<<"\" of the box \""<<to->bbGetName()
108                   <<"\" is already connected");
109       }
110     
111     //  std::string t1 ( from->bbGetOutputType(output).name() );
112     //   std::string t2 ( to->bbGetInputType(input).name() );
113     // if  //( t1 != t2 ) 
114     if ( from->bbGetOutputType(output) !=
115          to->bbGetInputType(input) )
116       {
117         if ( from->bbGetOutputType(output) == typeid(Data) )
118           {
119             bbtkWarning("Connection '"
120                         <<GetFullName()
121                         <<"' : '"<<from->bbGetName()<<"."<<output
122                         <<"' is of type <"
123                         <<HumanTypeName<Data>()
124                         <<"> : type compatibility with '"
125                         <<to->bbGetName()<<"."<<input
126                         <<"' will be resolved at run time"
127                         );
128             mFromAny = true;
129           }
130         else if (  to->bbGetInputType(input) == typeid(Data) )
131           {   
132             bbtkDebugMessage("Kernel",8," -> '"<<input<<"' type is "
133                              <<TypeName<Data>()<<" : can receive any data"
134                              <<std::endl);
135             mToAny = true;
136           }
137         else 
138           {
139             //   std::cout << "Adaptive connection "<<std::endl;
140             std::string name;
141             name = from->bbGetName() + "." + output + "-" 
142               + to->bbGetName() + "." + input; 
143             mAdaptor = mFactory.lock()
144               ->NewAdaptor(from->bbGetOutputType(output),
145                            to->bbGetInputType(input),
146                            name);
147             if (!mAdaptor)  
148               {  
149                 bbtkError("did not find any <"
150                           <<TypeName(from->bbGetOutputType(output))
151                           <<"> to <"
152                           <<TypeName(to->bbGetInputType(input))
153                           <<"> adaptor");
154               } 
155           }
156       }
157
158
159     mFrom = from;
160     mOriginalFrom = from;
161     mTo = to;
162     mOriginalTo = to;
163     mInput = mOriginalInput = input;
164     mOutput = mOriginalOutput = output;
165
166      // Lock this pointer !!!
167     //Pointer p = MakePointer(this,true);
168     from->bbConnectOutput(output,this);
169     to->bbConnectInput(input,this);
170  
171     from->bbGetOutputConnector(output).AddChangeObserver(boost::bind(&bbtk::Connection::OnOutputChange,this, _1, _2, _3));
172
173     
174     bbtkDebugMessage("connection",1,"<== Connection::Connection(\""
175                      <<from->bbGetFullName()<<"\",\""<<output<<"\",\""
176                      <<to->bbGetFullName()<<"\",\""<<input<<"\")"
177                      <<std::endl);    
178
179     bbtkDebugMessage("object",2,"==> Connection::Connection(\""
180                      <<from->bbGetName()<<"\",\""<<output<<"\",\""
181                      <<to->bbGetName()<<"\",\""<<input<<"\")"
182                      <<std::endl);    
183   }
184  //==================================================================
185  
186   //==================================================================
187   Connection::Pointer Connection::New(BlackBox::Pointer from, 
188                                       const std::string& output,
189                                       BlackBox::Pointer to, 
190                                       const std::string& input )
191   {
192     bbtkDebugMessage("object",1,"##> Connection::Connection(\""
193                      <<from->bbGetName()<<"\",\""<<output<<"\",\""
194                      <<to->bbGetName()<<"\",\""<<input<<"\")"
195                      <<std::endl);
196     Connection::Pointer p = 
197       MakePointer(new Connection(from,output,to,input));
198     bbtkDebugMessage("object",1,"<## Connection::Connection(\""
199                      <<from->bbGetName()<<"\",\""<<output<<"\",\""
200                      <<to->bbGetName()<<"\",\""<<input<<"\")"
201                      <<std::endl);
202     return p;
203   }
204   //==================================================================
205
206   //==================================================================
207   /// Ctor with the black box from and to and their input and output.
208 /// Check the input and output compatibility
209 Connection::Connection(BlackBox::Pointer from, const std::string& output,
210                        BlackBox::Pointer to, const std::string& input )
211   : mAdaptor(),
212       mFactory(),
213       mFromAny(false),
214       mToAny(false)
215   {
216     bbtkDebugMessage("object",2,"==> Connection::Connection(\""
217                      <<from->bbGetName()<<"\",\""<<output<<"\",\""
218                      <<to->bbGetName()<<"\",\""<<input<<"\")"
219                      <<std::endl);    
220
221     bbtkDebugMessage("connection",1,"==> Connection::Connection(\""
222                      <<from->bbGetFullName()<<"\",\""<<output<<"\",\""
223                      <<to->bbGetFullName()<<"\",\""<<input<<"\")"
224                      <<std::endl);    
225
226     
227
228     if (! from->bbHasOutput(output) )
229       {
230         bbtkError("The box \""<<from->bbGetTypeName()<<
231                   "\" has no output \""<<output<<"\"");
232       }
233     if (! to->bbHasInput(input) )
234       {
235         bbtkError("The box \""<<to->bbGetTypeName()<<
236                   "\" has no input \""<<input<<"\"");
237       } 
238
239     if (to->bbGetInputConnectorMap().find(input)->second->IsConnected())
240       {
241         bbtkError("The input \""<<input<<"\" of the box \""<<to->bbGetName()
242                   <<"\" is already connected");
243       }
244     
245     //  std::string t1 ( from->bbGetOutputType(output).name() );
246     //   std::string t2 ( to->bbGetInputType(input).name() );
247     // if  //( t1 != t2 ) 
248     if ( from->bbGetOutputType(output) !=
249          to->bbGetInputType(input) )
250       {
251         if ( from->bbGetOutputType(output) == typeid(Data) )
252           {
253             bbtkWarning("Connection '"
254                         <<GetFullName()
255                         <<"' : '"<<from->bbGetName()<<"."<<output
256                         <<"' is of type <"
257                         <<HumanTypeName<Data>()
258                         <<"> : type compatibility with '"
259                         <<to->bbGetName()<<"."<<input
260                         <<"' will be resolved at run time"
261                         );
262             mFromAny = true;
263           }
264         else if (  to->bbGetInputType(input) == typeid(Data) )
265           {   
266             bbtkDebugMessage("Kernel",8," -> '"<<input<<"' type is "
267                              <<TypeName<Data>()<<" : can receive any data"
268                              <<std::endl);
269             mToAny = true;
270           }
271         else 
272           {
273             bbtkError("Connection created between different types without Factory provided");
274           }
275       }
276
277
278     mFrom = from;
279     mOriginalFrom = from;
280     mTo = to;
281     mOriginalTo = to;
282     mInput = mOriginalInput = input;
283     mOutput = mOriginalOutput = output;
284
285      // Lock this pointer !!!
286     //Pointer p = MakePointer(this,true);
287     from->bbConnectOutput(output,this);
288     to->bbConnectInput(input,this);
289
290     from->bbGetOutputConnector(output).AddChangeObserver(boost::bind(&bbtk::Connection::OnOutputChange,this, _1, _2, _3));
291     
292     bbtkDebugMessage("connection",1,"<== Connection::Connection(\""
293                      <<from->bbGetFullName()<<"\",\""<<output<<"\",\""
294                      <<to->bbGetFullName()<<"\",\""<<input<<"\")"
295                      <<std::endl);    
296
297     bbtkDebugMessage("object",2,"==> Connection::Connection(\""
298                      <<from->bbGetName()<<"\",\""<<output<<"\",\""
299                      <<to->bbGetName()<<"\",\""<<input<<"\")"
300                      <<std::endl);    
301   }
302  //==================================================================
303  
304   //==================================================================
305   /// Dtor 
306   Connection::~Connection()
307   {
308     bbtkDebugMessage("object",2,
309                      "==> Connection::~Connection() ["
310                      <<GetFullName()<<"]"<<std::endl);
311
312     if (mAdaptor) mAdaptor.reset();
313     if (mFrom!=0) 
314       {
315         mFrom->bbDisconnectOutput(mOutput,this);
316         //                                GetThisPointer<Connection>());
317         mFrom.reset();
318       }
319     else 
320       {
321         bbtkInternalError("Connection::~Connection() : invalid initial box pointer");
322       }
323     if (mTo!=0) 
324       {
325         mTo->bbDisconnectInput(mInput,this);//   GetThisPointer<Connection>());
326         mTo.reset();
327       }
328     else 
329       {
330         bbtkInternalError("Connection::~Connection() : invalid final box pointer");
331       }
332
333
334     bbtkDebugMessage("object",2,
335                      "<== Connection::~Connection() ["
336                      <<GetFullName()<<"]"<<std::endl);
337   }
338   //==================================================================
339   
340   //==================================================================
341   /// Recursive execution
342   void Connection::RecursiveExecute()
343   {
344     bbtkDebugMessage("process",4,
345                      "===> Connection::RecursiveExecute() ["
346                      <<GetFullName()<<"]"<<std::endl);
347
348     mFrom->bbRecursiveExecute(GetThisPointer<Connection>());
349
350     TransferData();
351
352     // Transfer status
353     IOStatus s = MODIFIED;
354     if ( mFrom->bbGetOutputConnector(mOutput).GetStatus() == OUTOFDATE) 
355       {
356         s = OUTOFDATE;
357       }
358     mTo->bbGetInputConnector(mInput).SetStatus(s);
359     
360     bbtkDebugMessage("process",4,
361                      " --> '"<<mTo->bbGetName()<<"."<<mInput
362                      <<" ["<<&mTo->bbGetInputConnector(mInput)<<"] "
363                      <<"' new status '"
364                      <<GetIOStatusString(s)
365                      <<"'"
366                      << std::endl);
367
368     bbtkDebugMessage("process",4,
369                      "<=== Connection::RecursiveExecute() ["
370                      <<GetFullName()<<"]"<<std::endl);
371     return; 
372   }
373   //==================================================================
374
375
376
377   //==================================================================
378   /// Transfers the data from the source output to the target input
379   /// doing necessary conversions (adaptation or pointer cast)
380   void Connection::TransferData()
381   {
382     bbtkDebugMessageInc("data",3,
383                         "Connection::TransferData() ["
384                         <<GetFullName()<<"]"<<std::endl);
385     
386     
387     // If an adaptor was created we need to adapt the data
388     if (mAdaptor) 
389       {
390         mAdaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
391         mAdaptor->bbExecute();
392         // LG : Connection Update does not set mTo as modified
393         mTo->bbSetInput(mInput, mAdaptor->bbGetOutput("Out"),false);
394         
395       }
396     // If no adaptor but source type is an any and target is not an any
397     else if ( mFromAny && (! mToAny) )
398       {
399         bbtkDebugMessage("data",3,
400                          " * Source type is an "
401                          <<HumanTypeName<Data>()
402                          <<" which contains a <"
403                          <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
404                          <<">"<<std::endl);
405         bbtkDebugMessage("data",3,
406                          " * Target type is <"
407                          <<HumanTypeName(mTo->bbGetInputType(mInput))
408                          <<">"<<std::endl);
409         
410         // 1) Test strict type matching between any content and target
411         if (mFrom->bbGetOutput(mOutput)
412             .contains( mTo->bbGetInputType(mInput) ) )
413           {
414             bbtkDebugMessage("data",3,
415                              " -> Equal types : transfer ok"<<std::endl);
416             mTo->bbSetInput( mInput, 
417                              mFrom->bbGetOutput(mOutput),
418                              false);
419           }
420         else 
421           {
422             // 2) Look for an adaptor
423             bbtk::BlackBox::Pointer adaptor;
424             try 
425               {
426                 adaptor = mFactory.lock()
427                   ->NewAdaptor(mFrom->bbGetOutput(mOutput).type(),
428                                mTo->bbGetInputType(mInput),
429                                "");
430               }
431             catch (...)
432               {
433               }
434             if (adaptor)  
435               {
436                 bbtkDebugMessage("data",3," -> Adaptor found : using it"
437                                  <<std::endl);
438                   adaptor->bbSetInput("In",mFrom->bbGetOutput(mOutput),false);
439                 adaptor->bbExecute();
440                 // LG : Connection Update does not set mTo as modified
441                 mTo->bbSetInput(mInput, adaptor->bbGetOutput("Out"),false);
442                 //      adaptor->bbDelete();
443               }
444             // 3) If no adaptor found but the any content is a pointer
445             //    and target type is also a pointer : we try run-time cast
446             else if ( (mFrom->bbGetOutput(mOutput).contains_pointer()) &&
447                       (mTo->bbGetDescriptor()->GetInputDescriptor(mInput)
448                        ->IsPointerType()) )
449               {
450                 bbtkDebugMessage("data",3,
451                                  " -> No adaptor found but source and target types are both pointers : trying up or down cast"<<std::endl);
452                 
453                 void* nptr = 
454                   mFrom->bbGetOutput(mOutput)
455                   .get_pointer_to(mTo->bbGetInput(mInput).pointed_type());
456                 if (!nptr)  
457                   {
458                     bbtkError("Connection '"
459                               <<GetFullName()
460                               <<"' : <"
461                               <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
462                               <<"> to <"
463                               <<HumanTypeName(mTo->bbGetInputType(mInput))
464                               <<"> : no adaptor available and run-time up and down cast failed");
465                   }
466                 mTo->bbBruteForceSetInputPointer(mInput, nptr, false);
467               }
468             // 4) Nothing worked : error
469             else 
470               {
471                 bbtkError("Connection '"<<GetFullName()<<"' "
472                           <<"no adaptor found to convert <"
473                           <<HumanTypeName(mFrom->bbGetOutput(mOutput).type())
474                           <<"> to <"
475                           <<HumanTypeName(mTo->bbGetInputType(mInput))<<">");
476               }
477           }
478       }
479     // EO : mFromAny && ! mToAny
480     // Default case : types are the same; we use simple get-set
481     else 
482       {
483         // LG : Connection Update does not set mTo as modified
484         mTo->bbSetInput(mInput, mFrom->bbGetOutput(mOutput),false);
485       }
486
487   }
488   //==================================================================
489
490   //==================================================================
491   /// From.Output change propagation
492   void Connection::OnOutputChange(bbtk::BlackBox::Pointer, const std::string&, 
493                                   IOStatus status)
494   {
495     bbtkDebugMessage("change",2,
496                      "==> Connection::OnOutputChange("
497                      <<GetIOStatusString(status)<<") ["
498                      <<GetFullName()<<"]"<<std::endl);
499     if (mAdaptor) 
500       {
501             BlackBoxInputConnector* ac = mAdaptor->bbGetInputConnectorMap().find("In")->second;
502             mAdaptor->bbSetStatusAndPropagate(ac,status);
503       }
504     
505     mTo->bbSetStatusAndPropagate( mTo->bbGetInputConnectorMap().find(mInput)->second, status);
506     
507  
508   }
509   //==================================================================
510
511   
512   //==================================================================
513   std::string Connection::GetFullName() const {
514     if (mFrom && mTo) 
515       {
516         std::string res = mFrom->bbGetName()+"."+mOutput+"--"
517           +mTo->bbGetName()+"."+mInput;
518         if ((!mOriginalFrom.expired()) && (!mOriginalTo.expired()) &&
519             ((mFrom!=mOriginalFrom.lock())||(mTo!=mOriginalTo.lock())))
520           {
521             res += "("+mOriginalFrom.lock()->bbGetName()
522               +"."+mOriginalOutput+"--"
523               + mOriginalTo.lock()->bbGetName()+"."+mOriginalInput+")";
524           }
525         return res;
526       }
527     return "***Invalid Connection***";
528   }
529   //==================================================================
530
531   //==================================================================
532   void Connection::Check() const
533   {
534     bbtkMessage("debug",1,"** Checking Connection "<<(void*)this<<" ["<<GetFullName()<<"]"
535                 <<std::endl);
536     if (mFrom==0) 
537       {
538         bbtkMessage("debug",2," - From = 0"<<std::endl);
539       }
540     else
541       {
542         bbtkMessage("debug",2," - From : "<<mFrom->bbGetFullName()<<std::endl);
543         if (!mFrom->bbHasOutput(mOutput))
544           {
545             bbtkError("** Checking Connection "<<(void*)this
546                        <<" ["<<GetFullName()<<"] : "
547                       << mFrom->bbGetFullName()<<" does not have output '"
548                       <<mOutput<<"'");
549           }     
550         bbtkMessage("debug",2," - From : Output '"<<mOutput<<"' exists"<<std::endl);
551         BlackBox::OutputConnectorMapType::const_iterator i 
552           = mFrom->bbGetOutputConnectorMap().find(mOutput);
553         if (i== mFrom->bbGetOutputConnectorMap().end())
554           {
555              bbtkError("** Checking Connection "<<(void*)this
556                        <<" ["<<GetFullName()<<"] : "
557                        <<mFrom->bbGetFullName()<<" output '"
558                        <<mOutput<<"' is not in OutputConnectorMap");
559           }
560         bbtkMessage("debug",2," - From : Output '"<<mOutput
561                     <<"' is in OutputConnectorMap"<<std::endl);
562
563         std::vector< Connection* >::const_iterator j;
564         /*
565         for (j  = i->second->GetConnectionVector().begin();
566              j != i->second->GetConnectionVector().end();
567              ++j)
568           {
569             if ((*j)==this) break;
570           }
571         */
572         j = find(i->second->GetConnectionVector().begin(),
573                  i->second->GetConnectionVector().end(),
574                  this);
575        
576         if (j==i->second->GetConnectionVector().end())
577           {
578             bbtkError("** Checking Connection "<<(void*)this
579                       <<" ["<<GetFullName()<<"] : "
580                       << "Connection ["<<GetFullName()<<"] : "
581                       <<" OutputConnector '"
582                       <<mOutput<<"' of "<<mFrom->bbGetFullName()
583                       <<" does not point to this connection");
584             
585           }
586         bbtkMessage("debug",2," - From : This connection is in OutputConnector connection vector"<<std::endl);
587         bbtkMessage("debug",2," * Box from : Check successfull"<<std::endl);
588
589       }
590
591     if (mTo==0) 
592       {
593         bbtkMessage("debug",2," - To   = 0"<<std::endl);
594       }
595     else
596       {
597         bbtkMessage("debug",2," - To   : "<<mTo->bbGetName()<<std::endl);
598         //      std::cout << mTo << std::endl;
599         //      std::cout << mTo->bbGetDescriptor() << std::endl;
600         //      std::cout << mTo->bbGetDescriptor()->GetTypeName() << std::endl;
601         //      mTo->bbGetFullName();
602         bbtkMessage("debug",2," - To   : "<<mTo->bbGetFullName()<<std::endl);
603         if (!mTo->bbHasInput(mInput))
604           {
605             bbtkError("** Checking Connection "<<(void*)this
606                       <<" ["<<GetFullName()<<"] : "
607                       <<mTo->bbGetFullName()<<" does not have input '"
608                       <<mInput<<"'");
609           }     
610         bbtkMessage("debug",2," - To   : Input '"<<mInput<<"' exists"<<std::endl);
611         BlackBox::InputConnectorMapType::const_iterator i 
612           = mTo->bbGetInputConnectorMap().find(mInput);
613         if (i== mTo->bbGetInputConnectorMap().end())
614           {
615              bbtkError("** Checking Connection "<<(void*)this
616                        <<" ["<<GetFullName()<<"] : "
617                        <<mTo->bbGetFullName()<<" input '"
618                        <<mInput<<"' is not in InputConnectorMap");
619           }
620         bbtkMessage("debug",2," - To   : Input '"<<mInput
621                     <<"' is in InputConnectorMap"<<std::endl);
622
623         if (i->second->GetConnection()==0)
624           {
625             bbtkError("** Checking Connection "<<(void*)this
626                       <<" ["<<GetFullName()<<"] : "
627                       <<"Connection "<<GetFullName()<<" : "
628                       <<" InputConnector '"
629                       <<mInput<<"' of "<<mTo->bbGetFullName()
630                       <<" does not point to this connection");
631     
632           }
633         bbtkMessage("debug",2," - To   : This connection is in InputConnector connection vector"<<std::endl);
634         bbtkMessage("debug",2," * Box to   : Check successfull"<<std::endl);
635
636       }
637   }
638   //==================================================================
639  //==========================================================================
640   std::string Connection::GetObjectName() const
641   {
642     std::string s("Connection '");
643     s += GetFullName();
644     s += "'";
645     return s;
646   }
647   //==========================================================================
648   
649   //==========================================================================
650   std::string  Connection::GetObjectInfo() const 
651   {
652     std::stringstream i;
653     return i.str();
654   }
655   //==========================================================================
656
657  //==========================================================================
658 size_t  Connection::GetObjectSize() const 
659 {
660   size_t s = Superclass::GetObjectSize();
661   s += Connection::GetObjectInternalSize();
662   return s;
663   }
664   //==========================================================================
665   //==========================================================================
666 size_t  Connection::GetObjectInternalSize() const 
667 {
668   size_t s = sizeof(Connection);
669   return s;
670   }
671   //==========================================================================
672   //==========================================================================
673   size_t  Connection::GetObjectRecursiveSize() const 
674   {
675     size_t s = Superclass::GetObjectRecursiveSize();
676     s += Connection::GetObjectInternalSize();
677     return s;
678   }
679   //==========================================================================
680
681 }// namespace bbtk
682
683
684
685
686