]> Creatis software - bbtk.git/blob - kernel/src/bbtkComplexBlackBox.cxx
BUG MACOS
[bbtk.git] / kernel / src / bbtkComplexBlackBox.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkComplexBlackBox.cxx,v $
4   Language:  C++
5   Date:      $Date: 2009/03/30 15:22:51 $
6   Version:   $Revision: 1.25 $
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 /**
33  *  \file 
34  *  \brief class bbtk::ComplexBlackBox : user defined complex black boxes
35  */
36 #include "bbtkComplexBlackBox.h"
37 #include "bbtkWx.h"
38 #include "bbtkBlackBoxDescriptor.h"
39 #include "bbtkFactory.h"
40 #include "bbtkConfigurationFile.h"
41
42 namespace bbtk
43 {
44
45   //==========================================================================
46   /// Creates a new complex black box
47   ComplexBlackBox::Pointer ComplexBlackBox::New(const std::string& name,
48                                                 ComplexBlackBoxDescriptor::Pointer desc)
49   {
50     bbtkDebugMessage("object",1,"##> ComplexBlackBox::New('"<<name<<"','"<<
51                      desc->GetTypeName()<<"')" <<bbtkendl);
52     ComplexBlackBox::Pointer p = 
53       MakeBlackBoxPointer(new ComplexBlackBox(name,desc));
54     bbtkDebugMessage("object",2,"<## ComplexBlackBox::New('"<<name<<"','"<<
55                      desc->GetTypeName()<<"')" <<bbtkendl);
56     return p;
57   }
58   //==========================================================================
59
60   //=======================================================================
61   /// Usefull constructor 
62   ComplexBlackBox::ComplexBlackBox(const std::string &name,
63                                    ComplexBlackBoxDescriptor::Pointer desc)
64     : 
65     BlackBox(name),
66     mLockedDescriptor(desc),
67     mDescriptor(desc)
68   {
69     bbtkDebugMessage("object",3,
70                      "##> ComplexBlackBox::ComplexBlackBox(\""
71                      <<name<<"\")"<<std::endl);
72     bbAllocateConnectors();
73     bbtkDebugMessage("object",3,
74                      "<## ComplexBlackBox::ComplexBlackBox(\""
75                      <<name<<"\")"<<std::endl);
76   }
77   //=======================================================================
78
79   //=======================================================================
80   /// Constructor from an existing box (copy) with a new name 
81   ComplexBlackBox::ComplexBlackBox(ComplexBlackBox& from, 
82                                    const std::string &name)
83     : BlackBox(from,name),
84       // The locked descriptor is copied from the unlocked one 
85       // to make the box a non-prototype !!
86       mLockedDescriptor(from.mDescriptor),
87       mDescriptor(from.mDescriptor),
88      mExecutionList(from.mExecutionList)    
89   {
90     bbtkDebugMessage("object",3,
91                         "##> ComplexBlackBox::ComplexBlackBox(\""
92                         <<from.bbGetName()<<"\",\""
93                         <<name<<"\")"<<std::endl);
94     bbtkDebugMessage("object",4,"  * Cloning Black Boxes"<<std::endl);
95
96     // We have to make the shared_ptr on this because it is used 
97     // in bbUnsafeAddBlackBox !
98     MakeBlackBoxPointer(this,true);
99
100     BlackBoxMapType::const_iterator i;
101     for ( i = from.mBlackBoxMap.begin(); i != from.mBlackBoxMap.end(); ++i ) 
102       {
103         bbtkDebugMessageInc("object",5,"    * Cloning \""<<i->first<<"\""<<std::endl);
104         BlackBox::Pointer B = i->second->bbClone(i->second->bbGetName());
105         bbUnsafeAddBlackBox(B);
106       }
107    
108     bbtkDebugMessage("object",4,"  * Cloning Connections"<<std::endl);
109     ConnectionListType::const_iterator j;
110     for ( j = from.mConnectionList.begin(); j != from.mConnectionList.end(); ++j ) 
111       {
112         bbtkDebugMessage("object",5,"    * Cloning \""<<
113                          (*j)->GetFullName()<<"\""<<std::endl);
114
115         BlackBox::Pointer bbfrom = bbGetBlackBox( (*j)->GetOriginalBlackBoxFrom()->bbGetName() );
116         BlackBox::Pointer bbto = bbGetBlackBox( (*j)->GetOriginalBlackBoxTo()->bbGetName() );
117
118         Connection::Pointer c = mDescriptor.lock()->GetFactory()-> 
119           NewConnection( bbfrom, 
120                          (*j)->GetOriginalBlackBoxFromOutput(), 
121                          bbto, 
122                          (*j)->GetOriginalBlackBoxToInput() );
123         
124         //c->Check();
125         bbAddConnection(c);
126
127       }
128
129     bbAllocateConnectors();
130     bbtkDebugMessage("object",3,
131                         "<## ComplexBlackBox::ComplexBlackBox(\""
132                         <<from.bbGetName()<<"\",\""
133                         <<name<<"\")"<<std::endl);
134   }
135   //=======================================================================
136
137   //======================================================================= 
138   ///  Destructor
139   ComplexBlackBox::~ComplexBlackBox()
140   {
141     bbtkDebugMessage("object",3,
142                      "==> ComplexBlackBox::~ComplexBlackBox() ["
143                      <<bbGetName()<<"]"<<std::endl);
144     
145     Clear();
146     this->bbDesallocateConnectors();
147
148     bbtkDebugMessage("object",3,
149                      "<== ComplexBlackBox::~ComplexBlackBox() ["
150                      <<bbGetName()<<"]"<<std::endl);
151   } 
152   //=======================================================================
153  
154
155   //======================================================================= 
156   ///  Clear
157   void ComplexBlackBox::Clear()
158   {
159     bbtkDebugMessage("object",3,
160                      "==> ComplexBlackBox::Clear() ["
161                      <<bbGetName()<<"]"<<std::endl);
162
163     bbtkDebugMessage("object",4,
164                      " -> Releasing connections"<<std::endl);
165     mConnectionList.clear();
166     bbtkDebugMessage("object",4,
167                      " -> Releasing boxes"<<std::endl);
168     mBlackBoxMap.clear();
169
170     bbtkDebugMessage("object",3,
171                      "<== ComplexBlackBox::Clear() ["
172                      <<bbGetName()<<"]"<<std::endl);
173   } 
174   //=======================================================================
175
176   //=========================================================================
177   /// Allocates the i/o connectors of the black box
178   void ComplexBlackBox::bbAllocateConnectors()
179   {  
180     bbtkDebugMessageInc("Kernel",8,
181                         "ComplexBlackBox::bbAllocateConnectors() ["
182                         <<bbGetFullName()<<"]"
183                         <<std::endl);   
184     
185     // Input connectors
186     const BlackBoxDescriptor::InputDescriptorMapType& imap 
187       = bbGetDescriptor()->GetInputDescriptorMap(); 
188     BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;       
189     for ( i = imap.begin(); i != imap.end(); ++i )                      
190       {                                                                 
191         bbtkDebugMessage("Kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
192         // Redirect the connector to the internal box connector
193         // Cast the BBInputDescriptor into a ComplexBBInputDescriptor
194         ComplexBlackBoxInputDescriptor* d = 
195           (ComplexBlackBoxInputDescriptor*)i->second;
196         // Get the internal box connector
197         BlackBoxInputConnector* c = 
198           bbUnsafeGetBlackBox ( d->GetTarget() )
199           ->bbGetInputConnectorMap()[ d->GetInput() ];
200         
201         bbGetInputConnectorMap()[i->second->GetName()] = c;
202       }                                                                 
203
204     // Output connectors
205     const BlackBoxDescriptor::OutputDescriptorMapType& omap 
206       = bbGetDescriptor()->GetOutputDescriptorMap();                   
207     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
208     for ( o = omap.begin(); o != omap.end(); ++o )
209       {                                                 
210         bbtkDebugMessage("Kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
211         // Redirect the connector to the internal box connector
212         // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
213         ComplexBlackBoxOutputDescriptor* d = 
214           (ComplexBlackBoxOutputDescriptor*)o->second;
215         // Get the internal box connector
216         BlackBoxOutputConnector* c = 
217           bbUnsafeGetBlackBox ( d->GetTarget() )
218           ->bbGetOutputConnectorMap()[ d->GetOutput() ];
219
220         bbGetOutputConnectorMap()[o->second->GetName()] = c;
221       }
222     
223     bbtkDebugDecTab("Kernel",8);  
224   }
225   //=========================================================================
226
227
228   //=========================================================================
229   /// Desallocates the i/o connectors of the black box
230   void ComplexBlackBox::bbDesallocateConnectors()
231   {
232     bbtkDebugMessageInc("Kernel",8,
233                         "ComplexBlackBox::DesallocateConnectors()"
234                         <<std::endl);                                   
235
236     // The connectors have not been allocated by the complex box 
237     // but by the internal boxes. Hence **DO NOT** desallocate !
238     // just clear the maps to avoid that 
239     // BlackBox::bbDesallocateConnectors delete the connectors
240     bbGetInputConnectorMap().clear();
241     bbGetOutputConnectorMap().clear();
242
243     bbtkDebugDecTab("Kernel",8);  
244
245   }
246   //=========================================================================
247
248   //=======================================================================
249   BlackBox::Pointer ComplexBlackBox::bbClone(const std::string& name)
250   {
251     bbtkDebugMessageInc("Kernel",9,
252                         "ComplexBlackBox::bbClone(\""<<name<<"\") ["
253                         <<bbGetFullName()<<"]"<<std::endl);
254     
255     ComplexBlackBox* CBB = new ComplexBlackBox(*this,name);
256     return MakeBlackBoxPointer(CBB);
257   }
258   //=======================================================================
259
260   //=======================================================================
261   /// Main processing method of the box.
262   /// Executes the box so that its outputs are up-to-date on exit
263   void ComplexBlackBox::bbExecute(bool force)
264   {
265     bbtkDebugMessageInc("process",2,
266                         "=> ComplexBlackBox::bbExecute() ["
267                         <<bbGetFullName()<<"]"<<std::endl);
268
269
270     Wx::BusyCursor wait;
271     
272     if (mExecutionList.size() != 0) 
273       {
274         
275         std::vector<std::string>::const_iterator i;
276         for (i=mExecutionList.begin(); 
277              i!=mExecutionList.end();
278              ++i) 
279           {
280             bbtkDebugMessage("process",3," -> Executing '"<<*i<<"'"<<std::endl);
281             mBlackBoxMap[*i]->bbExecute(force);
282           }
283       }
284     else 
285       {
286         std::map<std::string, BlackBox::Pointer>::iterator i;
287         for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i)
288           {
289             i->second->bbExecute(force);
290           }
291       } 
292
293   }
294   //==================================================================
295
296   //==================================================================
297   void ComplexBlackBox::bbAddToExecutionList( const std::string& name )
298   {
299     bbtkDebugMessageInc("Kernel",9,
300                         "ComplexBlackBox::bbAddToExecutionList(\""
301                         <<name<<"\") ["
302                         <<bbGetFullName()<<"]"<<std::endl);
303     
304     mExecutionList.push_back( name );
305     
306     bbtkDebugDecTab("Kernel",9);   
307     
308   }
309   //==================================================================
310
311
312   //==================================================================
313   Data ComplexBlackBox::bbGetOutput( const std::string &name )
314   {
315     bbtkDebugMessageInc("Data",7,
316                         "ComplexBlackBox::bbGetOutput(\""<<name<<"\") ["
317                         <<bbGetFullName()<<"]"<<std::endl);
318
319     ComplexBlackBoxOutputDescriptor* d = 
320       (ComplexBlackBoxOutputDescriptor*)
321       bbGetDescriptor()->GetOutputDescriptor(name);
322     
323     Data p = bbGetBlackBox(d->GetTarget())->bbGetOutput(d->GetOutput());
324
325
326     bbtkDebugDecTab("Data",7);
327     return p;
328   }
329   //==================================================================
330
331   //==================================================================
332   ///  Gets the input Data of a given name
333   Data ComplexBlackBox::bbGetInput( const std::string &name ) 
334   {
335     bbtkDebugMessageInc("Data",7,
336                         "ComplexBlackBox::bbGetInput(\""<<name<<"\") ["
337                         <<bbGetFullName()<<"]"<<std::endl);  
338
339     ComplexBlackBoxInputDescriptor* d = 
340       (ComplexBlackBoxInputDescriptor*)
341       bbGetDescriptor()->GetInputDescriptor(name);
342
343     Data p = bbGetBlackBox(d->GetTarget())->bbGetInput(d->GetInput());
344
345     bbtkDebugDecTab("Data",7);
346     return p;
347   }
348   //==================================================================
349
350   //==================================================================
351   ///  Sets the data of the output called <name>
352   void ComplexBlackBox::bbSetOutput( const std::string &name, Data data)
353   {
354     bbtkDebugMessageInc("Data",7,
355                         "ComplexBlackBox::bbSetOutput(\""<<name<<"\",data) ["
356                         <<bbGetFullName()<<"]"<<std::endl); 
357
358     ComplexBlackBoxOutputDescriptor* d = 
359       (ComplexBlackBoxOutputDescriptor*)
360       bbGetDescriptor()->GetOutputDescriptor(name);
361     
362     bbGetBlackBox(d->GetTarget())->bbSetOutput(d->GetOutput(),data);
363
364     bbtkDebugDecTab("Data",7);
365   }
366   //==================================================================
367   
368   //==================================================================
369   ///  Sets the data of the input called <name>
370   void ComplexBlackBox::bbSetInput( const std::string &name, Data data,
371                                     bool setModified)
372   {
373     bbtkDebugMessageInc("Data",7,
374                         "ComplexBlackBox::bbSetInput(\""<<name<<"\",data) ["
375                         <<bbGetFullName()<<"]"<<std::endl);  
376
377     ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
378       bbGetDescriptor()->GetInputDescriptor(name);
379
380     bbGetBlackBox(d->GetTarget())->bbSetInput(d->GetInput(),data,setModified);
381
382     bbtkDebugDecTab("Data",7);
383   }
384   //==================================================================
385
386  
387   //==================================================================
388   ///  Sets the data of the input called <name>
389   void ComplexBlackBox::bbBruteForceSetInputPointer( const std::string &name, 
390                                                      void* data,
391                                                      bool setModified)
392   {
393     bbtkDebugMessageInc("Data",7,
394                         "ComplexBlackBox::bbBruteForceSetInputPointer('"
395                         <<name<<"',"<<data<<") ["
396                         <<bbGetFullName()<<"]"<<std::endl);  
397
398     ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
399       bbGetDescriptor()->GetInputDescriptor(name);
400
401     bbGetBlackBox(d->GetTarget())->bbBruteForceSetInputPointer(d->GetInput(),
402                                                                data,
403                                                                setModified);
404
405     bbtkDebugDecTab("Data",7);
406   }
407   //==================================================================
408
409   //=========================================================================
410   /// Connects the input <name> to the connection c
411   void ComplexBlackBox::bbConnectInput( const std::string& name, Connection* c)
412   {
413     bbtkDebugMessage("connection",2,
414                      "==> ComplexBlackBox::bbConnectInput(\""
415                      <<name<<"\","<<c->GetFullName()<<") ["
416                      <<bbGetFullName()<<"]"
417                      <<std::endl);       
418     
419    ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
420       bbGetDescriptor()->GetInputDescriptor(name);
421
422
423    BlackBox::Pointer t = bbGetBlackBox(d->GetTarget());
424
425    bbtkDebugMessage("connection",2," - Target = "<<d->GetTarget()<<" = "<<t->bbGetFullName()<<std::endl);
426
427    c->SetBlackBoxTo(t);
428    c->SetBlackBoxToInput(d->GetInput());
429
430    bbtkDebugMessage("connection",2," - New conn = "<<c->GetFullName()<<std::endl);
431    t->bbConnectInput(d->GetInput(),c);
432
433    bbtkDebugMessage("connection",2,
434                      "<== ComplexBlackBox::bbConnectInput(\""
435                      <<name<<"\","<<c->GetFullName()<<") ["
436                      <<bbGetFullName()<<"]"
437                      <<std::endl);       
438   }
439   //=========================================================================
440
441
442   //=========================================================================  
443   /// Connects the output <name> to the connection c
444   void ComplexBlackBox::bbConnectOutput( const std::string& name, Connection* c)
445   {
446     bbtkDebugMessage("connection",2,
447                      "==> ComplexBlackBox::bbConnectOutput(\""
448                      <<name<<"\","<<c->GetFullName()<<") ["
449                      <<bbGetFullName()<<"]"<<std::endl);       
450
451    ComplexBlackBoxOutputDescriptor* d = (ComplexBlackBoxOutputDescriptor*)
452       bbGetDescriptor()->GetOutputDescriptor(name);
453
454    BlackBox::Pointer t = bbGetBlackBox(d->GetTarget());
455  
456   bbtkDebugMessage("connection",2," - Target = "<<d->GetTarget()<<" = "<<t->bbGetFullName()<<std::endl);
457
458    c->SetBlackBoxFrom(t);
459    c->SetBlackBoxFromOutput(d->GetOutput());
460
461    bbtkDebugMessage("connection",2," - New conn = "<<c->GetFullName()<<std::endl);
462
463    t->bbConnectOutput(d->GetOutput(),c);
464   
465     bbtkDebugMessage("connection",2,
466                      "<== ComplexBlackBox::bbConnectOutput(\""
467                      <<name<<"\","<<c->GetFullName()<<") ["
468                      <<bbGetFullName()<<"]"<<std::endl);       
469   }
470   //=========================================================================
471
472
473   //==================================================================
474   /// Adds the black box to the complex box
475   void ComplexBlackBox::bbAddBlackBox( BlackBox::Pointer b)
476   {
477     bbtkDebugMessageInc("Kernel",7,
478                         "ComplexBlackBox::AddBlackBox(\""<<b->bbGetName()
479                         <<"\") ["
480                         <<bbGetFullName()<<"]"<<std::endl);  
481     
482     if ( bbUnsafeGetBlackBox(b->bbGetName()) ) 
483       {
484         bbtkError("a black box called \""<<b->bbGetName()
485                   <<"\" already exists");
486       }
487     b->bbSetParent(GetThisPointer<ComplexBlackBox>());
488     mBlackBoxMap[b->bbGetName()] = b;
489
490     bbtkDebugDecTab("Kernel",7);
491   }
492   //==================================================================
493
494   //==================================================================
495   /// Adds the black box to the complex box (unsafe)
496   void ComplexBlackBox::bbUnsafeAddBlackBox( BlackBox::Pointer b)
497   {
498     bbtkDebugMessageInc("Kernel",7,
499                         "ComplexBlackBox::UnsafeAddBlackBox(\""<<b->bbGetName()
500                         <<"\") ["
501                         <<bbGetFullName()<<"]"<<std::endl);  
502     
503     b->bbSetParent(GetThisPointer<ComplexBlackBox>());
504     mBlackBoxMap[b->bbGetName()] = b;
505
506     bbtkDebugDecTab("Kernel",7);
507   }
508   //==================================================================
509
510   //==================================================================
511   /// Removes the black box from the complex box
512   void ComplexBlackBox::bbRemoveBlackBox( const std::string& name, 
513                                           bool remove_connections )
514   {
515     bbtkDebugMessageInc("Kernel",7,
516                         "ComplexBlackBox::RemoveBlackBox(\""<<name<<"\") ["
517                         <<bbGetFullName()<<"]"<<std::endl);  
518
519     BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
520     if ( i == mBlackBoxMap.end() ) 
521       {
522         bbtkError("the black box \""<<name<<"\" does not exist");
523       }
524     BlackBox::WeakPointer p = i->second;
525     
526     if (remove_connections)
527       {
528         ConnectionListType::const_iterator j;
529         for ( j = mConnectionList.begin(); 
530               j != mConnectionList.end(); ++j ) 
531           {
532             (*j)->Check();
533           }
534       }
535     if (p.use_count()!=1) 
536       {
537         bbtkError("the black box \""<<name<<"\" is still connected");
538       }
539     
540     mBlackBoxMap.erase(i);
541     
542
543     // Unload orphan dl packages 
544     Package::UnLoadReleasedDynamicallyLoadedPackages();
545
546     bbtkDebugDecTab("Kernel",7);
547   }
548   //==================================================================
549
550   //==================================================================
551   /// Adds the connection to the complex box
552   void ComplexBlackBox::bbAddConnection( Connection::Pointer c)
553   {
554     bbtkDebugMessageInc("Kernel",7,
555                         "ComplexBlackBox::AddConnection(\""<<"..."<<"\") ["
556                         <<bbGetFullName()<<"]"<<std::endl);  
557
558     mConnectionList.push_back(c);
559
560     bbtkDebugDecTab("Kernel",7);
561   }
562   //==================================================================
563   //    void RemoveConnection( );
564
565   //==================================================================
566   /// Returns the black box with name <name>
567   BlackBox::Pointer ComplexBlackBox::bbGetBlackBox( const std::string& name )
568   {
569     bbtkDebugMessageInc("Kernel",9,
570                         "ComplexBlackBox::GetBlackBox(\""<<name<<"\") ["
571                         <<bbGetFullName()<<"]"<<std::endl);  
572
573     BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
574     if ( i == mBlackBoxMap.end() ) 
575       {
576         bbtkError("the black box \""<<name<<"\" does not exist");
577       }
578
579     bbtkDebugDecTab("Kernel",9);
580     return i->second;
581   }
582   //==================================================================
583
584   //==================================================================
585   /// Returns the black box with name <name> : does not throw an exception 
586   /// if it does not exist but return a null pointer
587   BlackBox::Pointer ComplexBlackBox::bbUnsafeGetBlackBox( const std::string& name )
588   {
589     bbtkDebugMessageInc("Kernel",9,
590                         "ComplexBlackBox::UnsafeGetBlackBox(\""<<name<<"\") ["
591                         <<bbGetFullName()<<"]"
592                         <<std::endl);  
593
594     BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
595     if ( i == mBlackBoxMap.end() ) 
596       {
597         bbtkDebugDecTab("Kernel",9);
598         return BlackBox::Pointer();
599       }
600
601     bbtkDebugDecTab("Kernel",9);
602     return i->second;
603     
604   }
605   //==================================================================
606
607   //==================================================================
608   void ComplexBlackBox::bbPrintBlackBoxes()
609   {
610     bbtkDebugMessageInc("Kernel",9,
611                         "ComplexBlackBox::PrintBlackBoxes() ["
612                         <<bbGetFullName()<<"]"
613                         <<std::endl);  
614
615     BlackBoxMapType::iterator i;
616     for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) 
617       {
618         bbtkMessage("Help",1,i->second->bbGetFullName()<<std::endl);
619       }
620
621     bbtkDebugDecTab("Kernel",9);
622   }
623   //==================================================================
624
625
626  
627   //=========================================================================
628   /// Virtual
629   void ComplexBlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
630   {
631     if (inputoutput)
632       {
633         fprintf(ff,"%s_IN_%p",bbGetTypeName().c_str(),this);
634       } else {
635       fprintf(ff,"%s_OUT_%p",bbGetTypeName().c_str(),this);
636     } // if inputoutput
637   }
638   //=========================================================================
639
640
641   //=========================================================================
642   BlackBox::Pointer ComplexBlackBox::bbFindBlackBox(const std::string &blackboxname)
643   {
644     BlackBox::Pointer blackbox;
645     std::string subname="";
646     std::string restname="";
647     std::string delimiters(">");
648     // Skip delimiters at beginning.
649     std::string::size_type lastPos = blackboxname.find_first_not_of(delimiters, 0);
650     // Find first "non-delimiter".
651     std::string::size_type pos     = blackboxname.find_first_of(delimiters, lastPos);
652             
653     // Found a token, add it to the vector.
654     subname = blackboxname.substr(lastPos, pos - lastPos);
655     restname = blackboxname.substr(lastPos+pos - lastPos+1, 999);
656
657     if (restname==subname)
658     {
659            restname="";
660     }
661
662     BlackBoxMapType::iterator i = mBlackBoxMap.find(subname);
663     if ( i != mBlackBoxMap.end() ) 
664     {
665        blackbox = i->second;
666        if (restname!="")
667             {
668              blackbox = blackbox->bbFindBlackBox(restname);
669             }
670     }
671     return blackbox;
672   }
673   //=========================================================================
674
675   //=========================================================================
676   void ComplexBlackBox::bbInsertHTMLGraph(  std::ofstream& s, 
677                                             int detail, 
678                                             int level,
679                                             bool instanceOrtype,
680                                             const std::string& output_dir,
681                                             bool relative_link )
682   {
683     std::string directory(output_dir);
684
685     if (output_dir.length() == 0) 
686     {
687            // Don't pollute the file store with  "temp_dir" directories ... 
688            std::string default_temp_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
689            directory =  default_temp_dir + "/" + "temp_dir";
690     }
691     
692     std::string simplefilename  (this->bbGetTypeName()+"_"+this->bbGetName());
693     std::string simplefilename_png (simplefilename+".png");
694     std::string filename           (directory+"/"+simplefilename);
695     std::string filename_png       (filename+".png");
696     std::string filename_cmap      (filename+".cmap");
697     std::string filename_dot       (filename+".dot");
698
699     std::string filename_png2   ("\""   + filename_png  + "\"");
700     std::string filename_cmap2  ("\""   + filename_cmap + "\"");
701     std::string filename_dot2   ("\""   + filename_dot  + "\"");
702     
703
704     std::string command1 ("dot -Tpng:quartz -o "  
705                           + filename_png2  + " " + filename_dot2 );
706     std::string command1a("dot -T cmap -o " 
707                           + filename_cmap2 + " " + filename_dot2 );
708
709     // 1. Generating .dot file
710     FILE *ff;
711     ff = fopen(filename_dot.c_str(),"w");
712     fprintf(ff,"digraph bbtk_graph{\n");
713     fprintf(ff,"rankdir=LR%s\n",";");
714     fprintf(ff,"node [shape=record]%s\n",";");
715
716     this->bbWriteDotFileBlackBox(ff,
717                                  GetThisPointer<ComplexBlackBox>(),
718                                  detail,level,
719                                  instanceOrtype,
720                                  relative_link );
721
722     fprintf(ff,"}\n");
723     fclose(ff);
724
725     // 2. Executing .dot file -> png
726     system( command1.c_str() );   
727     // 3. Executing .dot file -> cmap
728     system( command1a.c_str() );  
729     
730     // 4. HTML code insertion
731     // 4.1 image
732     (s) << "<center><img src=\"" << simplefilename_png 
733          <<   "\" border=\"0\" usemap=\"#map_"<< simplefilename 
734          <<"\" alt=\"\"></center>\n";
735
736     // 4.2 map
737     (s) << "<map name=\"map_"<< simplefilename <<"\">\n";
738     FILE *ff2;
739     char c;
740     ff2=fopen(filename_cmap.c_str(),"r");
741         if (ff2!=NULL){
742                 while (!feof(ff2))
743                 {
744                         c=fgetc(ff2);
745                         if (c!=-1)
746                         {
747                                 (s) << c;
748                         } // if 
749                 } // while
750         } // if ff2
751     (s) << "</map>\n\n";
752     
753     // End
754   }
755   //=========================================================================
756
757
758   //=========================================================================
759   /// Write Graphviz-dot description in file 
760   void ComplexBlackBox::bbWriteDotFileBlackBox(FILE *ff,
761                                                BlackBox::Pointer parentblackbox, 
762                                                int detail, int level,
763                                                bool instanceOrtype,
764                                                bool relative_link )   
765   {
766     std::string tmp1;
767     std::string valueStr("");
768     Package::Pointer package = this->bbGetDescriptor()->GetPackage(); 
769
770     if (package!=NULL)
771     {
772       if (relative_link)
773              tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL();
774            else 
775              tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocURL();
776     } 
777     else 
778     {
779            tmp1 = "Caspitas";
780     }
781
782     std::string tmp2=bbGetTypeName();
783     std::string url(tmp1 + "#" + tmp2 );        
784     fprintf( ff , "subgraph cluster_%s_%p {\n",bbGetName().c_str(),this);
785
786     if (!(   (bbGetTypeName()=="workspace") && (bbGetName()=="workspacePrototype")) )
787     {
788            fprintf( ff , "  URL = \"%s\" %s",url.c_str(),";");
789     }
790
791     std::string boxname="["+bbGetTypeName()+"]";
792     if (GetThisPointer<ComplexBlackBox>()!=parentblackbox)
793     {
794        if (detail==0)
795             {
796           boxname=bbGetName();
797        } 
798        else 
799        {
800           boxname = bbGetName();
801           boxname = boxname + "   [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
802             }
803
804     }
805     fprintf( ff , "  label = \"%s\"%s\n",  boxname.c_str() ,";");
806
807
808
809     //  fprintf( ff , "  style=filled%s\n",";");
810     //  fprintf( ff , "  color=grey%s\n",";");
811     fprintf( ff , "  node [style=filled]%s\n",";");
812     fprintf( ff , "  fillcolor=grey%s\n",";");
813     fprintf( ff , "  edge [color=blue]%s\n",";");
814
815
816     // Labels Salida
817     std::string labelStr1;
818     std::string labelStr2;
819     labelStr1 = boxname + "\\n(output)" ; 
820     labelStr2 = " | {{ ";
821     bool tmp; 
822     tmp=false;
823     OutputConnectorMapType::iterator i;
824
825     const BlackBoxDescriptor::OutputDescriptorMapType& omap = this->bbGetDescriptor()->GetOutputDescriptorMap();
826     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;      
827     for ( o = omap.begin();  o != omap.end(); ++o ) 
828       {
829         if (tmp==true)
830           {
831             labelStr2=labelStr2+" | ";
832           }
833         tmp=true;
834         if (instanceOrtype==true)
835           {
836             valueStr = this->bbGetOutputAsString(o->second->GetName()/*
837                                                                    ,factory*/) + " = ";
838           } 
839         labelStr2=labelStr2+"<"+o->second->GetName().c_str()+"> " + valueStr + o->second->GetName().c_str();
840       }
841
842     labelStr2 = labelStr2+ " } }";
843
844
845
846     if (detail==1)
847       {
848         labelStr1 = labelStr1 + labelStr2;
849       }
850
851     if (tmp){
852       fprintf(ff,"  " );
853       bbWriteDotInputOutputName(ff,false,detail,level);
854       fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
855     }
856
857
858     // label Entrada
859     labelStr1 = boxname + "\\n(input)" ; 
860     labelStr2 = " | {{ "; 
861     tmp=false;
862     InputConnectorMapType::iterator ii;
863
864     const BlackBoxDescriptor::InputDescriptorMapType& imap = this->bbGetDescriptor()->GetInputDescriptorMap();  
865     BlackBoxDescriptor::InputDescriptorMapType::const_iterator iii;
866     for ( iii = imap.begin();  iii != imap.end(); ++iii ) 
867       {
868         if (tmp==true)
869           {
870             labelStr2=labelStr2+" | ";
871           }
872         tmp=true;
873         if (instanceOrtype==true)
874           {
875             valueStr = this->bbGetInputAsString(iii->second->GetName()/*,factory*/) + " = ";
876           } 
877         labelStr2=labelStr2+"<"+iii->second->GetName().c_str()+"> " + valueStr + iii->second->GetName().c_str();
878       }
879
880
881     labelStr2 = labelStr2+ " } }";
882     if (detail==1)
883       {
884         labelStr1 = labelStr1 + labelStr2;
885       }
886     if (tmp){
887       fprintf(ff,"  " );
888       bbWriteDotInputOutputName(ff,true,detail,level);
889       fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
890     }
891
892
893     // Body
894     BlackBoxMapType::iterator j;
895     for ( j = mBlackBoxMap.begin(); j != mBlackBoxMap.end(); ++j ) 
896       {
897         if (level>-1)
898           {
899             j->second->bbWriteDotFileBlackBox(ff,
900                                               parentblackbox,
901                                               detail,
902                                               level-1,
903                                               instanceOrtype,
904                                               relative_link);
905           }
906       }
907
908     fprintf( ff , "}\n\n");
909
910     fprintf( ff , "  edge[color=blue]%s\n",";");
911
912     if (level>-1)
913       {
914         // Relation Input  with the inside BlackBox of the this ComplexBlackbox
915         ComplexBlackBoxDescriptor::InputDescriptorMapType::iterator xx;
916         ComplexBlackBoxDescriptor::InputDescriptorMapType idmt=bbGetDescriptor()->GetInputDescriptorMap();
917         for ( xx = idmt.begin(); xx != idmt.end(); ++xx ) 
918           {
919             ComplexBlackBoxInputDescriptor *cbbid = (ComplexBlackBoxInputDescriptor*)xx->second;
920
921             fprintf(ff,"  ");
922             bbWriteDotInputOutputName(ff,true,detail,level);
923             if (detail==1)
924               {
925                 fprintf(ff,":%s",cbbid->GetName().c_str() );
926               }
927             fprintf(ff,"->" );
928             BlackBox::Pointer bb = bbGetBlackBox( cbbid->GetTarget() ); 
929             bb->bbWriteDotInputOutputName(ff,true,detail,level);
930             if (detail==1)
931               {
932                 fprintf(ff,":%s \n", cbbid->GetInput().c_str() );
933               }
934           }// for xx
935
936
937
938         fprintf(ff,"\n \n");
939
940
941
942         // Relation Output ComplexBlackBox
943         ComplexBlackBoxDescriptor::OutputDescriptorMapType::iterator yy;
944         ComplexBlackBoxDescriptor::OutputDescriptorMapType odmt=bbGetDescriptor()->GetOutputDescriptorMap();
945         for ( yy = odmt.begin(); yy != odmt.end(); ++yy ) 
946           {
947             ComplexBlackBoxOutputDescriptor *cbbod = (ComplexBlackBoxOutputDescriptor*)yy->second;
948             fprintf(ff,"  ");
949             BlackBox::Pointer bb = bbGetBlackBox( cbbod->GetTarget() ); 
950             bb->bbWriteDotInputOutputName(ff,false,detail,level);
951             if (detail==1)
952               {
953                 fprintf(ff,":%s", cbbod->GetOutput().c_str() );
954               }
955             fprintf(ff,"->" );
956             bbWriteDotInputOutputName(ff,false,detail,level);
957             if (detail==1)
958               {
959                 fprintf(ff,":%s",cbbod->GetName().c_str() );
960               }
961             fprintf(ff,"\n");
962           } // for yy
963
964       } // if level
965
966
967
968         // Relation from the out side of this ComplexBlackBox with its Inputs
969     if (GetThisPointer<ComplexBlackBox>()!=parentblackbox) {
970       for ( ii = bbGetInputConnectorMap().begin(); 
971             ii != bbGetInputConnectorMap().end(); ++ii ) 
972         {
973           if (ii->second)
974             {
975               Connection* con = ii->second->GetConnection();
976               if (con!=NULL){
977                 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
978                 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
979                 fprintf(ff,"  ");
980                 a->bbWriteDotInputOutputName(ff,false,detail,level);
981                 if (detail==1)
982                   {
983                     fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
984                   }
985                 fprintf(ff,"->");
986                 b->bbWriteDotInputOutputName(ff,true,detail,level);
987                 if (detail==1)
988                   {
989                     fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
990                   }
991                 fprintf(ff,"%s\n",";");
992               } // if con
993             } // if second
994         } // for
995     } // if parentblackbox
996   }
997   //=========================================================================
998   
999
1000
1001
1002   /*
1003
1004   //=======================================================================
1005   /// Generates the list of the packages of which its depends 
1006   /// (cause an internal box belongs to it)
1007   void ComplexBlackBox::GetPackagesDependencies(std::vector<Package*>& deps)
1008   {
1009     deps.clear;
1010     BlackBoxMapType::iterator i;
1011     for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) 
1012       {
1013         deps.push_back(i->second->bbGetDescriptor()->GetPackage());
1014       }
1015
1016   }
1017   //=======================================================================
1018   */
1019
1020   //=======================================================================
1021   void ComplexBlackBox::Check(bool recursive)
1022   {
1023      bbtkMessage("debug",1,"**** Checking Complex Black Box "<<(void*)this
1024                  <<" ["<<bbGetFullName()<<"]"<<std::endl);
1025      
1026      BlackBoxMapType::const_iterator i;
1027      for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) 
1028        {
1029          i->second->Check(recursive);
1030        }
1031      ConnectionListType::const_iterator j;
1032      for ( j = mConnectionList.begin(); 
1033            j != mConnectionList.end(); ++j ) 
1034        {
1035          (*j)->Check();
1036        }
1037      bbtkMessage("debug",1,"**** Checking Complex Black Box "<<(void*)this
1038                  <<" ["<<bbGetFullName()<<"] ... OK"<<std::endl);
1039   
1040   }
1041   //=======================================================================
1042
1043   //=========================================================================
1044   /// Returns the name with the name of the parent prepended if any
1045   std::string ComplexBlackBox::bbGetNameWithParent() const
1046   {
1047     if (!IsAPrototype()) return BlackBox::bbGetNameWithParent();
1048     if (bbGetDescriptor()) 
1049       {
1050         return bbGetDescriptor()->GetFullTypeName() + ":" + bbGetName();
1051       }
1052     else 
1053       {
1054         return std::string(":") + bbGetName();
1055       }
1056   } 
1057   //=========================================================================
1058
1059   //==========================================================================
1060   std::string ComplexBlackBox::GetObjectName() const
1061   {
1062     return std::string("ComplexBlackBox '")+bbGetNameWithParent()
1063       +std::string("'");
1064   }
1065   //==========================================================================
1066   
1067   //==========================================================================
1068   std::string ComplexBlackBox::GetObjectInfo() const 
1069   {
1070     std::stringstream i;
1071     i << "  - "<<mBlackBoxMap.size() << " boxes / "
1072       <<mConnectionList.size() << " connections" << std::endl;
1073     return i.str();
1074   }
1075   //==========================================================================
1076
1077   //==========================================================================
1078   size_t  ComplexBlackBox::GetObjectSize() const 
1079   {
1080     size_t s = Superclass::GetObjectSize();
1081     s += ComplexBlackBox::GetObjectInternalSize();
1082     return s;
1083   }
1084   //==========================================================================
1085   //==========================================================================
1086   size_t  ComplexBlackBox::GetObjectInternalSize() const 
1087   {
1088     size_t s = sizeof(ComplexBlackBox);
1089     return s;
1090   }
1091   //==========================================================================
1092   //==========================================================================
1093   size_t  ComplexBlackBox::GetObjectRecursiveSize() const 
1094   {
1095     size_t s = Superclass::GetObjectRecursiveSize();
1096     s += ComplexBlackBox::GetObjectInternalSize();
1097     BlackBoxMapType::const_iterator i;
1098     for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) 
1099       {
1100         s += i->second->GetObjectRecursiveSize();
1101       }
1102     ConnectionListType::const_iterator j;
1103     for ( j = mConnectionList.begin(); 
1104           j != mConnectionList.end(); ++j ) 
1105       {
1106         s += (*j)->GetObjectRecursiveSize();
1107       }
1108     return s;
1109   }
1110   //==========================================================================
1111
1112 }