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