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