]> Creatis software - bbtk.git/blob - kernel/src/bbtkBlackBox.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkBlackBox.cxx
1 /*=========================================================================
2                                                                                 
3 Program:   bbtk
4 Module:    $RCSfile: bbtkBlackBox.cxx,v $
5 Language:  C++
6 Date:      $Date: 2008/01/22 15:02:00 $
7 Version:   $Revision: 1.1 $
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::BlackBox : abstract black-box interface. 
23  */
24 #include "bbtkBlackBox.h"
25 #include "bbtkPackage.h"
26 #include "bbtkMessageManager.h"
27 #include "bbtkFactory.h"
28
29 #include "bbtkConfigurationFile.h"
30 #include "bbtkWxBlackBox.h"
31
32 #include <fstream>
33 //#include <vector>
34
35
36 namespace bbtk
37 {
38   //=========================================================================
39   BlackBox::BlackBox(const std::string &name) 
40     : bbmName(name), bbmStatus(MODIFIED), 
41       bbmBoxProcessMode("Pipeline"),bbmParent(NULL)
42   {
43     bbtkDebugMessage("Core",7,"BlackBox::BlackBox(\""
44                      <<name<<"\")"<<std::endl);
45   }
46   //=========================================================================
47
48
49   //=========================================================================
50   BlackBox::BlackBox(BlackBox& from, const std::string &name) 
51     : bbmName(name), 
52       bbmStatus(from.bbmStatus), 
53       bbmBoxProcessMode(from.bbmBoxProcessMode),bbmParent(NULL)
54   {
55     bbtkDebugMessage("Core",7,"BlackBox::BlackBox("
56                      <<from.bbGetFullName()<<",\""
57                      <<name<<"\")"<<std::endl);
58   }
59   //=========================================================================
60
61
62   //=========================================================================
63   BlackBox::~BlackBox()
64   {
65     //    std::cout << "EED BlackBox::~BlackBox 01 [" << bbGetName()<<"]\n";
66     bbtkDebugMessageInc("Core",7,"BlackBox::~BlackBox()"<<std::endl);
67     this->bbDesallocateConnectors();
68     //printf("EED BlackBox::~BlackBox 02 \n");
69     bbtkDebugDecTab("Core",7);
70   }
71   //=========================================================================
72
73   //=========================================================================
74   /// Destruction method of a black box
75   void BlackBox::bbDelete()
76   {
77     bbtkDebugMessage("Core",5,"BlackBox::bbDelete() ["
78                      <<bbGetFullName()<<"]"<<std::endl);    
79     this->bbUserDelete();
80   }
81   //=========================================================================
82
83
84   //=========================================================================
85   /// Main processing method of the box.
86   void BlackBox::bbExecute(bool force)
87   {
88     bbtkDebugMessageInc("Process",1,
89                         "=> BlackBox::bbExecute() ["
90                         <<bbGetFullName()<<"]"<<std::endl);
91
92     wx::BeginBusyCursor();
93
94     // If execution frozen : return
95     if (bbGlobalGetFreezeExecution()) 
96       {
97         bbtkDebugMessage("Process",1,
98                          " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
99       }
100
101     // If force is true then update is triggered even if the box is UPTODATE
102     if (force) bbSetModifiedStatus();
103
104     // Calls the main recursive update method 
105     bbBackwardUpdate(0);
106
107     wx::EndBusyCursor();
108
109     bbtkDebugMessageDec("Process",1,
110                         "<= BlackBox::bbExecute() ["
111                         <<bbGetFullName()<<"]"<<std::endl);
112   }
113   //=========================================================================
114
115   //=========================================================================
116   std::string BlackBox::bbGetFullName() const
117   { 
118     return bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
119   }
120   //=========================================================================
121      
122
123
124   //=========================================================================
125   /// Returns the name with the name of the parent prepended if any
126   std::string BlackBox::bbGetNameWithParent() const
127   {
128     if (bbmParent) 
129       {
130         return bbmParent->bbGetNameWithParent() + ":" + bbmName;
131       }
132     else 
133       {
134         return bbmName;
135       }
136   } 
137   //=========================================================================
138
139   //=========================================================================
140   /// Prints the Help on the BlackBox type 
141   void BlackBox::bbGetHelp(bool full) const
142   {
143     bbGetDescriptor()->GetHelp(full); 
144   }
145   //=========================================================================
146
147
148   //=========================================================================
149   /// Returns true if the UserBlackBox has an input of name name
150   bool BlackBox::bbHasInput(const std::string& name) const
151   {
152     bbtkDebugMessageInc("Core",8,
153                         "BlackBox::bbHasInput(\""
154                         <<name<<"\") ["<<bbGetFullName()<<"]"
155                         <<std::endl);
156     bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
157                != bbGetDescriptor()->GetInputDescriptorMap().end());
158     bbtkDebugDecTab("Core",8);
159     return r;
160   }
161   //=========================================================================
162
163
164   //=========================================================================  
165   /// Returns true if the UserBlackBox has an output of name name
166   bool BlackBox::bbHasOutput(const std::string& name) const
167   {
168     bbtkDebugMessageInc("Core",8,"BlackBox::bbHasOutput(\""
169                         <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
170     bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
171                != bbGetDescriptor()->GetOutputDescriptorMap().end());
172     bbtkDebugDecTab("Core",8);
173     return r;
174   }
175   //=========================================================================
176
177
178   //=========================================================================  
179   ///  Gets the output type of a given name
180   TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const 
181   {
182     bbtkDebugMessageInc("Core",8,
183                         "BlackBox::bbGetOutputType(\""
184                         <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
185     TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
186     bbtkDebugDecTab("Core",8); 
187     return r;
188   }
189   //=========================================================================
190
191   //=========================================================================
192   ///  Gets the input type of a given name
193   TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
194   {
195     bbtkDebugMessageInc("Core",8,
196                         "BlackBox::bbGetInputType(\""
197                         <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
198     TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
199     bbtkDebugDecTab("Core",8);
200     return r;
201   }
202   //=========================================================================
203
204
205   //=========================================================================
206   /// Allocates the i/o connectors of the black box
207   void BlackBox::bbAllocateConnectors()
208   {  
209     bbtkDebugMessageInc("Core",8,
210                         "BlackBox::bbAllocateConnectors() ["
211                         <<bbGetFullName()<<"]"
212                         <<std::endl);                                   
213     const BlackBoxDescriptor::InputDescriptorMapType& imap 
214       = bbGetDescriptor()->GetInputDescriptorMap(); 
215     BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;       
216     for ( i = imap.begin(); i != imap.end(); ++i )                      
217       {                                                                 
218         bbtkDebugMessage("Core",8,"* Allocate \""<<i->first<<"\""<<std::endl);
219         bbGetInputConnectorMap()[i->second->GetName()] 
220           = new BlackBoxInputConnector(this);
221       }                                                                 
222     const BlackBoxDescriptor::OutputDescriptorMapType& omap 
223       = bbGetDescriptor()->GetOutputDescriptorMap();                   
224     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
225     for ( o = omap.begin(); o != omap.end(); ++o )
226       {                                                 
227         bbtkDebugMessage("Core",8,"* Allocate \""<<o->first<<"\""<<std::endl);
228         bbGetOutputConnectorMap()[o->second->GetName()] 
229           = new BlackBoxOutputConnector();
230       }
231     bbtkDebugDecTab("Core",8);  
232   }
233   //=========================================================================
234
235
236   //=========================================================================
237   /// Desallocates the i/o connectors of the black box
238   void BlackBox::bbDesallocateConnectors()
239   {
240     bbtkDebugMessageInc("Core",8,
241                         "BlackBox::bbDesallocateConnectors()"
242                         <<std::endl);                                   
243
244     InputConnectorMapType::const_iterator i;
245     for ( i = bbGetInputConnectorMap().begin();
246           i != bbGetInputConnectorMap().end(); ++i )                   
247       {                                                                 
248         bbtkDebugMessage("Core",8,"* Delete \""<<i->first<<"\""<<std::endl);
249         delete (i->second);
250       }                                                                 
251     OutputConnectorMapType::const_iterator o;   
252     for ( o = bbGetOutputConnectorMap().begin(); 
253           o != bbGetOutputConnectorMap().end(); ++o )                   
254       {                                                                 
255         bbtkDebugMessage("Core",8,"* Delete \""<<o->first<<"\""<<std::endl);           
256         delete (o->second);
257       }                                                                 
258    
259     bbtkDebugDecTab("Core",8);  
260
261   }
262   //=========================================================================
263
264
265   //=========================================================================
266   /// Copies the input / output values from another box
267   void BlackBox::bbCopyIOValues(BlackBox& from)
268   {
269     bbtkDebugMessageInc("Core",9,
270                         "BlackBox::bbCopyIOValues("
271                         <<from.bbGetFullName()<<") ["
272                         <<bbGetFullName()<<"]"<<std::endl);
273     // copies the input values
274     const BlackBoxDescriptor::InputDescriptorMapType& imap 
275       = bbGetDescriptor()->GetInputDescriptorMap(); 
276     BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;       
277     for ( i = imap.begin(); i != imap.end(); ++i )                      
278       {         
279         if (! i->second->GetCopyConstruct() ) continue;
280         std::string input = i->second->GetName();
281         this->bbSetInput(input, from.bbGetInput(input) );
282       }                                                                 
283     // copies the output values
284     const BlackBoxDescriptor::OutputDescriptorMapType& omap 
285       = bbGetDescriptor()->GetOutputDescriptorMap();                   
286     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
287     for ( o = omap.begin(); o != omap.end(); ++o )
288       {                                                 
289         if (! o->second->GetCopyConstruct() ) continue;
290         std::string output = o->second->GetName();
291         this->bbSetOutput(output, from.bbGetOutput(output) );
292       }
293
294     bbtkDebugDecTab("Core",9);
295
296   }
297   //=========================================================================
298
299
300
301   //=========================================================================
302   bool BlackBox::bbCanReact() const 
303   { 
304     return ( bbGlobalGetSomeBoxExecuting() 
305 #ifdef _USE_WXWIDGETS_
306              || WxBlackBox::bbGlobalIsSomeWindowAlive() 
307 #endif
308              ); 
309   }
310   //=========================================================================
311
312
313
314   //=========================================================================
315   /// User overloadable destruction method of a black box
316   void BlackBox::bbUserDelete() 
317   {   
318     bbtkDebugMessage("Process",5,
319                      "=> BlackBox::bbUserDelete() ["
320                      <<bbGetFullName()<<"]"
321                      <<" : not overloaded; using standard deletion"
322                      <<std::endl);
323     delete this;
324   }
325   //=========================================================================
326
327
328   //=========================================================================
329   BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
330   {
331     const std::string& p = bbmBoxProcessMode;
332     if ( (p == "0") ||
333          (p == "P") || (p == "p") ||
334          (p == "Pipeline") || (p == "pipeline") ) return Pipeline;
335     if ( (p == "1") ||
336          (p == "A") || (p == "a") ||
337          (p == "Always") || (p == "always") ) return Always;
338     if ( (p == "2") ||
339          (p == "R") || (p == "r") ||
340          (p == "Reactive") || (p == "reactive") ) return Reactive;
341     bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
342               <<"' unknown. Possible values : "
343               <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
344               <<"'1'/'A'/'a'/'Always'/'always' | "
345               <<"'2'/'R'/'r'/'Reactive'/'reactive'"<<std::endl);
346   }
347   //=========================================================================
348   
349   //=========================================================================
350   bool  BlackBox::bbBoxProcessModeIsReactive() const
351   {
352     return (bbGetBoxProcessModeValue() == Reactive);
353   }
354   //=========================================================================
355
356   //=========================================================================
357   bool  BlackBox::bbBoxProcessModeIsAlways() const
358   {
359     return (bbGetBoxProcessModeValue() == Always);
360   }
361   //=========================================================================
362
363   //=========================================================================
364   ///  Signals that the BlackBox has been modified
365   void BlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
366   {
367     bbtkDebugMessageInc("Process",5,
368                         "=> BlackBox::bbSetModifiedStatus("<<c<<") ["
369                         <<bbGetFullName()<<"]"<<std::endl);
370    
371     if ( (c==bbGetInputConnectorMap().find("WinHide")->second) )
372          //      && (bbCanReact()))
373       {
374         bbtkDebugMessage("Process",9,
375                          "-> Hide triggered by WinHide input change"
376                          <<std::endl);
377         this->bbHideWindow();
378         this->bbSetStatus(MODIFIED); 
379         return;
380       }
381  
382     if ( ( bbBoxProcessModeIsReactive()  ||
383            (c==bbGetInputConnectorMap().find("BoxExecute")->second))
384          && (bbCanReact() ) )
385       {
386         bbtkDebugMessage("Process",9,
387                          "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
388         this->bbSetStatus(MODIFIED); 
389         bbGlobalAddToExecutionList( this );
390       }
391     else if ( bbGetStatus() == MODIFIED ) //! this->bbIsUptodate()) 
392       { 
393         bbtkDebugMessage("Process",5,"-> Already modified"<<std::endl);
394         bbtkDebugDecTab("Process",5);
395         return;
396       }
397     else 
398       {
399         bbtkDebugMessage("Process",5,"-> Status set to modified"<<std::endl);
400         bbtkDebugDecTab("Process",5);
401         this->bbSetStatus(MODIFIED); 
402       }
403  
404     this->bbSignalOutputModification(false);
405
406    bbtkDebugMessageDec("Process",5,
407                         "<= BlackBox::bbSetModifiedStatus("<<c<<") ["
408                         <<bbGetFullName()<<"]"<<std::endl);
409   }  
410   //=========================================================================
411
412   //=========================================================================  
413   void BlackBox::bbSignalOutputModification(bool reaction)
414   {
415     bbtkDebugMessageInc("Process",5,
416                         "=> BlackBox::bbSignalOutputModification() ["
417                         <<bbGetFullName()<<"]"<<std::endl);
418     
419     OutputConnectorMapType::iterator change = bbGetOutputConnectorMap().end();
420     OutputConnectorMapType::iterator i;
421     for ( i  = bbGetOutputConnectorMap().begin(); 
422           i != bbGetOutputConnectorMap().end(); ++i) {
423       /*     if ( i->first == "BoxChange" ) 
424         {
425           change = i;
426           continue;
427         }
428       */
429       i->second->SetModifiedStatus();
430     } 
431     //    if (change != bbGetOutputConnectorMap().end()) 
432     // change->second->SetModifiedStatus();
433
434     if (reaction) bbGlobalProcessExecutionList();
435
436     bbtkDebugMessageDec("Process",5,
437                         "<= BlackBox::bbSignalOutputModification() ["
438                         <<bbGetFullName()<<"]"<<std::endl);
439     
440   }  
441   //=========================================================================   
442   //=========================================================================  
443   void BlackBox::bbSignalOutputModification(const std::string& output,
444         bool reaction)
445   {
446     bbtkDebugMessageInc("Process",5,
447                         "=> BlackBox::bbSignalOutputModification("
448                         <<output<<") ["
449                         <<bbGetFullName()<<"]"<<std::endl);
450     
451     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(output);
452     if ( i == bbGetOutputConnectorMap().end() ) 
453         {
454           bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
455         }
456     i->second->SetModifiedStatus();
457     // Has to notify the output "BoxChange" also
458     if (output != "BoxChange") 
459       {
460         i = bbGetOutputConnectorMap().find("BoxChange");
461         if ( i != bbGetOutputConnectorMap().end() ) 
462           {
463             i->second->SetModifiedStatus();
464           }
465       }
466   if (reaction) bbGlobalProcessExecutionList();
467
468     bbtkDebugMessageDec("Process",5,
469                         "<= BlackBox::bbSignalOutputModification("
470                         <<output<<") ["
471                         <<bbGetFullName()<<"]"<<std::endl);
472
473   }  
474   //=========================================================================   
475   //=========================================================================  
476   void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
477         bool reaction)
478   {
479     bbtkDebugMessageInc("Process",5,
480                         "=> BlackBox::bbSignalOutputModification(vector of outputs) ["
481                         <<bbGetFullName()<<"]"<<std::endl);
482     OutputConnectorMapType::iterator i;
483     std::vector<std::string>::const_iterator o;
484     for (o=output.begin();o!=output.end();++o) 
485       {
486         // the output "BoxChange" must be signaled **AFTER** all others
487         if (*o == "BoxChange") continue;
488         // Look for the connector
489         i = bbGetOutputConnectorMap().find(*o);
490         if ( i == bbGetOutputConnectorMap().end() ) 
491           {
492             bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
493           }
494         i->second->SetModifiedStatus();
495       }
496     // Has to notify the output "BoxChange" also
497     i = bbGetOutputConnectorMap().find("BoxChange");
498     if ( i != bbGetOutputConnectorMap().end() ) 
499       {
500         i->second->SetModifiedStatus();
501       }
502   if (reaction) bbGlobalProcessExecutionList();
503
504    bbtkDebugMessageDec("Process",5,
505                        "<= BlackBox::bbSignalOutputModification(vector of outputs) ["
506                         <<bbGetFullName()<<"]"<<std::endl);
507
508   }  
509   //=========================================================================   
510
511   //=========================================================================
512   /// Updates the BlackBox inputs
513   /// \returns UPTODATE if all inputs are in UPTODATE status after update
514   ///          else MODIFIED 
515   IOStatus BlackBox::bbUpdateInputs(bool excludeParent)
516   {
517     bbtkDebugMessageInc("Process",4,
518                         "=> BlackBox::bbUpdateInputs() ["
519                         <<bbGetFullName()<<"]"
520                         <<std::endl);   
521
522     IOStatus s = UPTODATE;
523     
524     InputConnectorMapType::iterator i;
525     for ( i = bbGetInputConnectorMap().begin(); 
526           i!= bbGetInputConnectorMap().end(); ++i) 
527       {
528         if (excludeParent && (i->first=="WinParent")) continue;
529         if (i->first=="WinHide") continue;
530         // If input type is Void : no recurse
531         //if (  bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo() 
532         //      == typeid(Void) ) 
533         //  continue;
534
535         IOStatus t = i->second->BackwardUpdate();
536         if (t==MODIFIED) s = MODIFIED;
537       }
538     
539    bbtkDebugMessageDec("Process",4,
540                         "<= BlackBox::bbUpdateInputs() ["
541                         <<bbGetFullName()<<"]"
542                         <<std::endl);   
543
544
545     return s;
546   }
547   //=========================================================================
548
549  
550   //=========================================================================
551   /// Connects the input <name> to the connection c
552   void BlackBox::bbConnectInput( const std::string& name, Connection* c)
553   {
554     bbtkDebugMessageInc("Core",7,
555                         "BlackBox::bbConnectInput(\""<<name<<"\","<<c<<") ["
556                         <<bbGetFullName()<<"]"
557                         <<std::endl);       
558     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
559     if (i==bbGetInputConnectorMap().end())
560       {
561         bbtkError("no input called '"<<name<<"'");
562       }
563     i->second->SetConnection(c);
564     
565     //  bbSetModifiedStatus();
566
567     bbtkDebugDecTab("Core",7);
568   }
569   //=========================================================================
570
571
572   //=========================================================================  
573   /// Connects the output <name> to the connection c
574   void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
575   {
576     bbtkDebugMessageInc("Core",7,
577                         "BlackBox::bbConnectOutput(\""<<name<<"\","<<c<<") ["
578                         <<bbGetFullName()<<"]"<<std::endl);       
579
580     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
581     if (i==bbGetOutputConnectorMap().end())
582       {
583         bbtkError("no output called '"<<name<<"'");
584       }
585     i->second->SetConnection(c);
586
587     bbtkDebugDecTab("Core",7);
588   }
589   //=========================================================================
590
591
592   //=========================================================================
593   /// Disconnects the input <name> from the connection c
594   void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
595   {
596     bbtkDebugMessageInc("Core",7,
597                         "BlackBox::bbDisconnectInput(\""<<name
598                         <<"\","<<c<<") ["
599                         <<bbGetFullName()<<"]"
600                         <<std::endl);      
601
602     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
603     if (i==bbGetInputConnectorMap().end())
604       {
605         bbtkError("no input called '"<<name<<"'");
606       }
607     i->second->UnsetConnection(c);
608
609     bbtkDebugDecTab("Core",7);
610   }
611   //=========================================================================
612
613
614   //=========================================================================
615   /// Disconnects the output <name> from the connection c
616   void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
617   {
618     bbtkDebugMessageInc("Core",7,
619                         "BlackBox::bbDisconnectOutput(\""<<name
620                         <<"\","<<c<<") ["
621                         <<bbGetFullName()<<"]"
622                         <<std::endl);       
623
624     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
625     if (i==bbGetOutputConnectorMap().end())
626       {
627         bbtkError("no output called '"<<name<<"'");
628       }
629     i->second->UnsetConnection(c);
630
631     bbtkDebugDecTab("Core",7);
632   } 
633   //=========================================================================
634  
635
636   //=========================================================================
637   /// Virtual
638   void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
639   {
640     fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
641   }
642   //=========================================================================
643
644
645   //=========================================================================
646   std::string BlackBox::bbGetOutputAsString( const std::string &output ) 
647   {
648     std::string v;
649     // Looks for the adaptor
650     if (bbGetOutputType(output).name() != typeid(std::string).name() ) 
651       {
652         BlackBox* a = 0;
653         try
654           {
655             a = NewAdaptor(  
656                            bbGetOutputType(output),
657                            typeid(std::string),
658                            "");
659           } catch (bbtk::Exception e) 
660           {
661           }
662         if (a!=NULL){
663           //                    bbUpdate();
664           a->bbSetInput("In",bbGetOutput(output));
665           a->bbExecute();
666           v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
667         } else {
668           v="? (no adaptor found)";
669         }
670       } else {
671       //         bbUpdate();
672       v = bbGetOutput(output).unsafe_get<std::string>() ;
673     }
674     return v;
675   }
676   //=========================================================================
677
678   //=========================================================================
679   std::string BlackBox::bbGetInputAsString( const std::string &input ) 
680   {
681     std::string v;
682     // Looks for the adaptor
683     if (bbGetInputType(input) != typeid(std::string)) 
684       {
685         BlackBox* a = 0;
686         try
687           {
688             a = NewAdaptor(  
689                            bbGetInputType(input),
690                            typeid(std::string),
691                            "");
692           }catch (bbtk::Exception e) 
693           {
694           }
695         if (a!=NULL)
696           {
697             //                  bbUpdate();
698             a->bbSetInput("In",bbGetInput(input));
699             a->bbExecute();
700             v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
701           } 
702         else 
703           {
704             v="? (no adaptor found)";
705           }
706       } 
707     else 
708       {
709         v = bbGetInput(input).unsafe_get<std::string>() ;
710       }
711     return v;
712   }
713   //=======================================================================
714
715   //=======================================================================
716   // Replaces substrings "<" by "["
717   void SubsBrackets ( std::string& s )
718   {
719     //   std::cout << "BEFORE=["<<s<<"]"<<std::endl;
720     std::string ss("<");
721     std::string::size_type pos = 0;
722     pos = s.find(ss,0);
723     char* cr = "[";
724     while ( pos != std::string::npos )
725       {
726         //      std::cout << "*** find one "<<std::endl;
727         s.replace(pos,1,cr,1);
728         pos = s.find(ss, pos);
729       } 
730     ss = ">";
731     pos = 0;
732     pos = s.find(ss,0);
733     cr = "]";
734     while ( pos != std::string::npos )
735       {
736         //      std::cout << "*** find one "<<std::endl;
737         s.replace(pos,1,cr,1);
738         pos = s.find(ss, pos);
739       } 
740     ss = ",";
741     pos = 0;
742     pos = s.find(ss,0);
743     cr = "-";
744     while ( pos != std::string::npos )
745       {
746         //      std::cout << "*** find one "<<std::endl;
747         s.replace(pos,1,cr,1);
748         pos = s.find(ss, pos);
749       }     //    std::cout << "AFTER=["<<s<<"]"<<std::endl;
750   }
751   //=======================================================================
752
753   //=========================================================================
754   /// Write Graphviz-dot description in file
755   void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
756                                         BlackBox *parentblackbox, 
757                                         int detail, int level,
758                                         bool instanceOrtype,
759                                         bool relative_link )
760
761   {
762     InputConnectorMapType::iterator i;
763     // label
764     std::string labelStr;
765     std::string valueStr("");
766     if (detail==0)
767       {
768         labelStr = bbGetName() ; 
769       } else {
770       labelStr = bbGetName();
771       labelStr = labelStr + "   [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]  ";
772     }
773
774     SubsBrackets(labelStr);
775     if (detail==1)
776       {
777         labelStr = labelStr + " | {{ "; 
778         std::string tempStrTypeName;
779         bool tmp; 
780         tmp=false;
781         for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
782           {
783             if (tmp==true)
784               {
785                 labelStr=labelStr+" | ";
786               }
787             tmp=true;
788             if (instanceOrtype==true)
789               {
790                 valueStr = this->bbGetInputAsString(i->first) + " = ";
791               } 
792             const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
793             tempStrTypeName=id->GetTypeName();
794             SubsBrackets(tempStrTypeName);
795             std::string Name(i->first);
796             SubsBrackets(Name);
797             labelStr=labelStr + "<"+i->first.c_str()+"> "  + valueStr +  Name.c_str() + "  [" + tempStrTypeName.c_str() + "]";
798           }
799         labelStr=labelStr+ " } | {";
800         tmp = false;
801         OutputConnectorMapType::iterator ii;
802         for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii ) 
803         {
804            if (tmp==true)
805            {
806                    labelStr=labelStr+" | ";
807            }
808            tmp = true;
809            if (instanceOrtype==true)
810            {
811                    valueStr = this->bbGetOutputAsString(ii->first) + " = ";
812            }
813            const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first); 
814            tempStrTypeName=id->GetTypeName();
815            SubsBrackets(tempStrTypeName);
816             std::string Name(ii->first);
817             SubsBrackets(Name);
818            labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + "  ["+tempStrTypeName+"]";
819         }
820         labelStr = labelStr+ "      } }" ;
821 } // detail
822
823     fprintf(ff,"  " );
824     bbWriteDotInputOutputName(ff,true,detail,level);
825     std::string tmp ( bbGetTypeName() );
826     SubsBrackets(tmp);
827     std::string url;
828     if (relative_link) 
829       url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
830     else 
831       url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
832   
833     fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
834     //    std::cout  << labelStr << std::endl;
835
836     // Relation Input
837     if (this!=parentblackbox){
838       for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
839         {
840           if (i->second)
841             {
842               Connection* con = i->second->GetConnection();
843               if (con!=NULL){
844                 BlackBox *a=con->GetBlackBoxFrom();
845                 BlackBox *b=con->GetBlackBoxTo();
846                 fprintf(ff,"  ");
847                 a->bbWriteDotInputOutputName(ff,false,detail,level);
848                 if (detail==1)
849                   {
850                     fprintf(ff,":%s",con->GetBlackBoxFromOutput().c_str());
851                   }
852                 fprintf(ff,"->");
853                 b->bbWriteDotInputOutputName(ff,true,detail,level);
854                 if (detail==1)
855                   {
856                     fprintf(ff,":%s",con->GetBlackBoxToInput().c_str());
857                   }
858                 fprintf(ff,"%s\n",";");
859               }  // if con
860             } // if second
861         } // for
862     } // if parentblackbox
863   }
864   //=========================================================================
865
866
867
868
869   //=========================================================================
870   void BlackBox::bbShowRelations(BlackBox *parentblackbox, 
871                                  int detail, int level
872                                  /*,Factory *factory*/ )
873   {
874      
875     if (this->bbGetDescriptor()->GetPackage()) 
876       {
877         bbtkMessage("Help",1,"Black Box '"<<bbGetName()<<"' <"<<
878                     this->bbGetDescriptor()->GetPackage()->GetName()
879                     <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
880       }
881     else 
882       {
883         bbtkMessage("Help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
884       }
885     //    bbtkMessage("Help",1," "<<GetDescription()<<std::endl);
886     //    bbtkMessage("Help",1," By : "<<GetAuthor()<<std::endl);
887
888     std::vector<std::string> iname;
889     std::vector<std::string> ivalue;
890     std::vector<std::string> iconn;
891
892     InputConnectorMapType::iterator i;
893     unsigned int namelmax = 0;
894     unsigned int valuelmax = 0;
895     unsigned int connlmax = 0;
896     for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
897       {
898         iname.push_back(i->first);
899         if (iname.back().size()>namelmax) namelmax = iname.back().size();
900         ivalue.push_back(bbGetInputAsString(i->first));
901         if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
902         std::string s("");
903         Connection* con = i->second->GetConnection();
904         if (con!=0){
905           s = con->GetBlackBoxFrom()->bbGetName();
906           s += ".";
907           s += con->GetBlackBoxFromOutput();
908         }  // if con
909         iconn.push_back(s);
910       }
911     OutputConnectorMapType::iterator o;
912     std::vector<std::string> oname;
913     std::vector<std::string> ovalue;
914     std::vector<std::vector<std::string> > oconn;
915     for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o ) 
916       {
917         oname.push_back(o->first);
918         if (oname.back().size()>namelmax) namelmax = oname.back().size();
919         ovalue.push_back(bbGetOutputAsString(o->first));
920         if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size();
921         std::vector<std::string> ss;
922         const std::vector<Connection*>& con = o->second->GetConnectionVector();
923         std::vector<Connection*>::const_iterator c;
924         for (c=con.begin();c!=con.end();++c) 
925           {
926             std::string s;
927             s = (*c)->GetBlackBoxTo()->bbGetName();
928             s += ".";
929             s += (*c)->GetBlackBoxToInput();
930             ss.push_back(s);
931         }  // if con
932         oconn.push_back(ss);
933       }
934
935     if (iname.size()) 
936       bbtkMessage("Help",1," * Inputs : "<<std::endl);
937     else 
938       bbtkMessage("Help",1," * No inputs"<<std::endl);
939
940     std::vector<std::string>::iterator i1,i2,i3;
941     for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin();
942          i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end();
943          ++i1,++i2,++i3)
944       {
945         std::string name(*i1);
946         name += "'";
947         name.append(1+namelmax-name.size(),' ');
948         std::string value(*i2);
949         value += "'";
950         value.append(1+valuelmax-value.size(),' ');
951         if (i3->size()) 
952           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<" <-- '"<<*i3<<"'"<<std::endl);
953         else 
954           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<std::endl);
955       }
956
957     if (oname.size()) 
958       bbtkMessage("Help",1," * Outputs : "<<std::endl);
959     else 
960       bbtkMessage("Help",1," * No outputs"<<std::endl);
961
962     std::vector<std::vector<std::string> >::iterator i4;
963
964     for (i1=oname.begin(),i2=ovalue.begin(),i4=oconn.begin();
965          i1!=oname.end(),i2!=ovalue.end(),i4!=oconn.end();
966          ++i1,++i2,++i4)
967       {
968         std::string name(*i1);
969         name += "'";
970         name.append(1+namelmax-name.size(),' ');
971         std::string value(*i2);
972         value += "'";
973         value.append(1+valuelmax-value.size(),' ');
974         if (!(*i4).size())
975           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<std::endl);
976         else 
977           {
978             std::string pref = "    '"+name+" = '"+value;
979             for (i3=i4->begin();i3!=i4->end();++i3)
980               {
981                 bbtkMessage("Help",1,pref<<" --> '"<<*i3<<"'"<<std::endl);
982                 pref.replace(0,pref.size(),pref.size(),' ');
983               }
984           }
985       }
986
987    }
988   //=========================================================================
989
990
991   //=========================================================================
992    void BlackBox::bbGlobalProcessExecutionList()
993    {   
994      bbtkDebugMessageInc("Process",1,
995                          "=> BlackBox::bbGlobalProcessExecutionList()"
996                          <<std::endl);     
997      
998      std::set<BlackBox*>::iterator i;
999      for (i=bbmgExecutionList.begin();
1000           i!=bbmgExecutionList.end();
1001           ++i)
1002        {
1003          bbtkDebugMessage("Process",2,
1004                           " -> Executing "<<(*i)->bbGetFullName()<<std::endl);
1005          (*i)->bbExecute(true);
1006        }
1007      
1008      bbmgExecutionList.clear();
1009      bbtkDebugMessageDec("Process",1,
1010                          "<= BlackBox::bbGlobalProcessExecutionList()"
1011                          <<std::endl);     
1012      
1013      
1014    }
1015   //=========================================================================
1016
1017   //=========================================================================
1018   // Static members initialization
1019   bool BlackBox::bbmgSomeBoxExecuting = false;
1020   bool BlackBox::bbmgFreezeExecution = false;
1021   std::set<BlackBox*> BlackBox::bbmgExecutionList;
1022    //=========================================================================
1023
1024
1025 }  // EO namespace bbtk
1026
1027 // EOF
1028