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