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