]> Creatis software - bbtk.git/blob - kernel/src/bbtkBlackBox.cxx
d0e93b5c14ba13b8f28590dc20ab03c6a3da50b6
[bbtk.git] / kernel / src / bbtkBlackBox.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkBlackBox.cxx,v $
4   Language:  C++
5   Date:      $Date: 2008/12/09 11:48:31 $
6   Version:   $Revision: 1.33 $
7 =========================================================================*/
8
9 /* ---------------------------------------------------------------------
10
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
13 *
14 *  This software is governed by the CeCILL-B license under French law and 
15 *  abiding by the rules of distribution of free software. You can  use, 
16 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
17 *  license as circulated by CEA, CNRS and INRIA at the following URL 
18 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
19 *  or in the file LICENSE.txt.
20 *
21 *  As a counterpart to the access to the source code and  rights to copy,
22 *  modify and redistribute granted by the license, users are provided only
23 *  with a limited warranty  and the software's author,  the holder of the
24 *  economic rights,  and the successive licensors  have only  limited
25 *  liability. 
26 *
27 *  The fact that you are presently reading this means that you have had
28 *  knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */                                                                         
30
31 /**
32  *  \file 
33  *  \brief Class bbtk::BlackBox : abstract black-box interface. 
34  */
35 #include "bbtkBlackBox.h"
36 #include "bbtkPackage.h"
37 #include "bbtkMessageManager.h"
38 #include "bbtkFactory.h"
39 #include "bbtkBlackBoxOutputConnector.h"
40
41 #include "bbtkConfigurationFile.h"
42 #include "bbtkWxBlackBox.h"
43
44 #include <fstream>
45 //#include <vector>
46
47
48 namespace bbtk
49 {
50
51
52   static bool bbmgSomeBoxExecuting = false;
53   static bool bbmgFreezeExecution = false;
54   static std::set<BlackBox::WeakPointer> bbmgExecutionList;
55
56   //=========================================================================
57   BlackBox::Deleter::Deleter()
58   {
59   }
60   //=========================================================================
61   
62   //=========================================================================
63   void BlackBox::Deleter::Delete(Object* p)
64   {
65     BlackBox* b = dynamic_cast<BlackBox*>(p);
66     if (!b)
67       {
68         bbtkInternalError("BlackBox::Deleter::Delete("<<p->GetObjectName()
69                           <<"["<<p<<"]) : "
70                           <<"dynamic cast to BlackBox* failed !");
71       }
72     std::string name = p->GetObjectName();//b->bbGetNameWithParent();
73     bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
74
75
76     BlackBoxDescriptor::WeakPointer desc = b->bbGetDescriptor();
77     bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : deleting black box"<<std::endl);
78     
79     b->bbDelete();
80
81     bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : releasing descriptor ["<<desc.lock()<<"]"<<std::endl);
82     
83     if (!desc.expired()) 
84       {
85         Package::WeakPointer pack = desc.lock()->GetPackage();
86         if (!pack.expired()) 
87           {
88             Package::ReleaseBlackBoxDescriptor(pack,desc);
89           }
90         else 
91           {
92             bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor package expired (was not held by a package and the box was the last instance)"<<std::endl);
93           }
94       }
95     else
96       {
97         bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor expired : nothing to do (was not held by a package or the box is a complex black box prototype)"<<std::endl);
98       }
99     bbtkDebugMessage("object",2,"<## BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
100   }
101   //=========================================================================
102
103   //=========================================================================
104   BlackBox::BlackBox(const std::string &name) 
105     : 
106     //    bbmStatus(MODIFIED), 
107     bbmExecuting(false),
108     bbmName(name),
109     bbmBoxProcessMode("Pipeline"),
110     bbmParent()
111     
112   {
113     bbtkDebugMessage("object",4,"==> BlackBox::BlackBox(\""
114                      <<name<<"\")"<<std::endl);
115     bbtkDebugMessage("object",4,"<== BlackBox::BlackBox(\""
116                      <<name<<"\")"<<std::endl);
117   }
118   //=========================================================================
119
120   //=========================================================================
121   BlackBox::BlackBox(const BlackBox&)
122   {}
123
124   //=========================================================================
125   BlackBox::BlackBox(BlackBox& from, const std::string &name) 
126     :
127     //    bbmStatus(from.bbmStatus), 
128       bbmExecuting(false),
129       bbmName(name), 
130       bbmBoxProcessMode(from.bbmBoxProcessMode),
131       bbmParent()
132
133   {
134     bbtkDebugMessage("object",4,"==> BlackBox::BlackBox("
135                      <<from.bbGetFullName()<<",\""
136                      <<name<<"\")"<<std::endl);
137     bbtkDebugMessage("object",4,"<== BlackBox::BlackBox("
138                      <<from.bbGetFullName()<<",\""
139                      <<name<<"\")"<<std::endl);
140   }
141   //=========================================================================
142
143
144   //=========================================================================
145   BlackBox::~BlackBox()
146   {
147     bbtkDebugMessage("object",4,"==> BlackBox::~BlackBox() ["<<bbmName
148                      <<"]"<<std::endl);
149     this->bbDesallocateConnectors();
150     bbtkDebugMessage("object",4,"<== BlackBox::~BlackBox() ["<<bbmName
151                      <<"]"<<std::endl);
152   }
153   //=========================================================================
154
155
156   //=========================================================================
157   /// Main processing method of the box.
158   void BlackBox::bbExecute(bool force)
159   {
160     bbtkDebugMessageInc("process",2,
161                         "=> BlackBox::bbExecute("<<(int)force<<") ["
162                         <<bbGetFullName()<<"]"<<std::endl);
163  
164     // If already executing : return
165     if (bbGetExecuting()) 
166       {
167         bbtkDebugMessage("process",2,
168                          " -> already executing : bailing out"<<std::endl);
169         return;
170       }
171
172     // If execution frozen : return
173     if (bbGlobalGetFreezeExecution()) 
174       {
175         bbtkDebugMessage("process",2,
176                          " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
177       }
178
179     BBTK_BUSY_CURSOR;
180
181     // If force is true then update is triggered even if the box is UPTODATE
182     //    if (force) bbSetModifiedStatus();
183
184     // Calls the main recursive update method 
185     bbBackwardUpdate(Connection::Pointer());
186
187     bbtkDebugMessageDec("process",2,
188                         "<= BlackBox::bbExecute() ["
189                         <<bbGetFullName()<<"]"<<std::endl);
190   }
191   //=========================================================================
192
193   //=========================================================================
194   std::string BlackBox::bbGetFullName() const
195   { 
196     return this->bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
197   }
198   //=========================================================================
199      
200
201
202   //=========================================================================
203   /// Returns the name with the name of the parent prepended if any
204   std::string BlackBox::bbGetNameWithParent() const
205   {
206     if (bbmParent.lock()) 
207       {
208         return bbmParent.lock()->bbGetNameWithParent() + ":" + bbmName;
209       }
210     else 
211       {
212         return bbmName;
213       }
214   } 
215   //=========================================================================
216
217   //=========================================================================
218   /// Prints the Help on the BlackBox type 
219   void BlackBox::bbGetHelp(bool full) const
220   {
221     bbGetDescriptor()->GetHelp(full); 
222   }
223   //=========================================================================
224
225
226   //=========================================================================
227   /// Returns true if the UserBlackBox has an input of name name
228   bool BlackBox::bbHasInput(const std::string& name) const
229   {
230     bbtkDebugMessageInc("Kernel",8,
231                         "BlackBox::bbHasInput(\""
232                         <<name<<"\") ["<<bbGetFullName()<<"]"
233                         <<std::endl);
234     bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
235                != bbGetDescriptor()->GetInputDescriptorMap().end());
236     bbtkDebugDecTab("Kernel",8);
237     return r;
238   }
239   //=========================================================================
240
241
242   //=========================================================================  
243   /// Returns true if the UserBlackBox has an output of name name
244   bool BlackBox::bbHasOutput(const std::string& name) const
245   {
246     bbtkDebugMessageInc("Kernel",8,"BlackBox::bbHasOutput(\""
247                         <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
248     bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
249                != bbGetDescriptor()->GetOutputDescriptorMap().end());
250     bbtkDebugDecTab("Kernel",8);
251     return r;
252   }
253   //=========================================================================
254
255
256   //=========================================================================  
257   ///  Gets the output type of a given name
258   TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const 
259   {
260     bbtkDebugMessageInc("Kernel",8,
261                         "BlackBox::bbGetOutputType(\""
262                         <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
263     TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
264     bbtkDebugDecTab("Kernel",8); 
265     return r;
266   }
267   //=========================================================================
268
269   //=========================================================================
270   ///  Gets the input type of a given name
271   TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
272   {
273     bbtkDebugMessageInc("Kernel",8,
274                         "BlackBox::bbGetInputType(\""
275                         <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
276     TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
277     bbtkDebugDecTab("Kernel",8);
278     return r;
279   }
280   //=========================================================================
281
282
283   //=========================================================================
284   /// Allocates the i/o connectors of the black box
285   void BlackBox::bbAllocateConnectors()
286   {  
287     bbtkDebugMessageInc("Kernel",8,
288                         "BlackBox::bbAllocateConnectors() ["
289                         <<bbGetFullName()<<"]"
290                         <<std::endl);                                   
291     const BlackBoxDescriptor::InputDescriptorMapType& imap 
292       = bbGetDescriptor()->GetInputDescriptorMap(); 
293     BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;       
294     for ( i = imap.begin(); i != imap.end(); ++i )                      
295       {                                                                 
296         bbtkDebugMessage("Kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
297         bbGetInputConnectorMap()[i->second->GetName()] 
298           = new BlackBoxInputConnector(GetThisPointer<BlackBox>());
299       }                                                                 
300     const BlackBoxDescriptor::OutputDescriptorMapType& omap 
301       = bbGetDescriptor()->GetOutputDescriptorMap();                   
302     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
303     for ( o = omap.begin(); o != omap.end(); ++o )
304       {                                                 
305         bbtkDebugMessage("Kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
306         bbGetOutputConnectorMap()[o->second->GetName()] 
307           = new BlackBoxOutputConnector();
308       }
309     bbtkDebugDecTab("Kernel",8);  
310   }
311   //=========================================================================
312
313
314   //=========================================================================
315   /// Desallocates the i/o connectors of the black box
316   void BlackBox::bbDesallocateConnectors()
317   {
318     bbtkDebugMessageInc("Kernel",8,
319                         "BlackBox::bbDesallocateConnectors()"
320                         <<std::endl);                                   
321
322     InputConnectorMapType::const_iterator i;
323     for ( i = bbGetInputConnectorMap().begin();
324           i != bbGetInputConnectorMap().end(); ++i )                   
325       {                                                                 
326         bbtkDebugMessage("Kernel",8,"* Delete \""<<i->first<<"\""<<std::endl);
327         delete (i->second);
328       }                                                                 
329     OutputConnectorMapType::const_iterator o;   
330     for ( o = bbGetOutputConnectorMap().begin(); 
331           o != bbGetOutputConnectorMap().end(); ++o )                   
332       {                                                                 
333         bbtkDebugMessage("Kernel",8,"* Delete \""<<o->first<<"\""<<std::endl);         
334         delete (o->second);
335       }                                                                 
336    
337     bbtkDebugDecTab("Kernel",8);  
338
339   }
340   //=========================================================================
341
342
343   //=========================================================================
344   /// Copies the input / output values from another box
345   void BlackBox::bbCopyIOValues(BlackBox& from)
346   {
347     bbtkDebugMessageInc("Kernel",1,
348                         "BlackBox::bbCopyIOValues("
349                         <<from.bbGetFullName()<<") ["
350                         <<bbGetFullName()<<"]"<<std::endl);
351     // copies the input values
352     const BlackBoxDescriptor::InputDescriptorMapType& imap 
353       = bbGetDescriptor()->GetInputDescriptorMap(); 
354     BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;       
355     for ( i = imap.begin(); i != imap.end(); ++i )                      
356       {         
357         if (! i->second->GetCopyConstruct() ) continue;
358         std::string input = i->second->GetName();
359         bbtkDebugMessage("Kernel",2,"* Copying input "<<input<<std::endl);
360         this->bbSetInput(input, from.bbGetInput(input) );
361       }                                                                 
362     // copies the output values
363     const BlackBoxDescriptor::OutputDescriptorMapType& omap 
364       = bbGetDescriptor()->GetOutputDescriptorMap();                   
365     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
366     for ( o = omap.begin(); o != omap.end(); ++o )
367       {                                                 
368         if (! o->second->GetCopyConstruct() ) continue;
369         std::string output = o->second->GetName();
370         bbtkDebugMessage("Kernel",2,"* Copying output "<<output<<std::endl);
371         this->bbSetOutput(output, from.bbGetOutput(output) );
372       }
373
374     bbtkDebugDecTab("Kernel",9);
375
376   }
377   //=========================================================================
378
379
380
381   //=========================================================================
382   bool BlackBox::bbCanReact() const 
383   { 
384     return ( bbGlobalGetSomeBoxExecuting() 
385 #ifdef _USE_WXWIDGETS_
386              || Wx::IsSomeWindowAlive() 
387 #endif
388              ); 
389   }
390   //=========================================================================
391
392
393
394   //=========================================================================
395   /// User overloadable destruction method of a black box
396   void BlackBox::bbUserDelete() 
397   {   
398     bbtkDebugMessage("process",5,
399                      "=> BlackBox::bbUserDelete() ["
400                      <<bbGetFullName()<<"]"
401                      <<" : not overloaded; using standard deletion"
402                      <<std::endl);
403     delete this;
404   }
405   //=========================================================================
406
407
408   //=========================================================================
409   BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
410   {
411     const std::string& p = bbmBoxProcessMode;
412     if ( (p == "0") ||
413          (p == "P") || (p == "p") ||
414          (p == "Pipeline") || (p == "pipeline") ) return Pipeline;
415     if ( (p == "1") ||
416          (p == "A") || (p == "a") ||
417          (p == "Always") || (p == "always") ) return Always;
418     if ( (p == "2") ||
419          (p == "R") || (p == "r") ||
420          (p == "Reactive") || (p == "reactive") ) return Reactive;
421     bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
422               <<"' unknown. Possible values : "
423               <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
424               <<"'1'/'A'/'a'/'Always'/'always' | "
425               <<"'2'/'R'/'r'/'Reactive'/'reactive'"<<std::endl);
426   }
427   //=========================================================================
428   
429   //=========================================================================
430   bool  BlackBox::bbBoxProcessModeIsReactive() const
431   {
432     return (bbGetBoxProcessModeValue() == Reactive);
433   }
434   //=========================================================================
435
436   //=========================================================================
437   bool  BlackBox::bbBoxProcessModeIsAlways() const
438   {
439     return (bbGetBoxProcessModeValue() == Always);
440   }
441   //=========================================================================
442
443
444
445
446   //=========================================================================
447   void BlackBox::AddChangeObserver(const std::string& output_name, 
448                                    OutputChangeCallbackType f)
449   {
450   }  
451   //=========================================================================
452
453   //=========================================================================
454   void BlackBox::RemoveChangeObserver(const std::string& output_name, 
455                                       OutputChangeCallbackType f)
456   {
457   }
458   //=========================================================================
459
460
461   /*
462   //=========================================================================
463   ///  Sets the ChangeTime of input 
464   void BlackBox::bbSetInputChangeTime(BlackBoxInputConnector* c, 
465                                       const ChangeTime& t)
466   {
467     bbtkDebugMessage("change",1,
468                      "==> BlackBox::bbSetInputChangeTime("<<c<<","<<t<<") ["
469                      <<bbGetFullName()<<"]"<<std::endl);
470     
471     // If new time is greater than old one
472     if ( c->SetChangeTime(t) ) 
473       {
474         bool was_up_to_date = bbIsUpToDate();
475         // If new time is greater than the old max time of inputs
476         if ( mMaxInputChangeTime.Set(t) ) 
477           {
478             // If the box turned out-of-date
479             if ( was_up_to_date && bbIsOutOfDate() )
480               {
481                 // 
482                 if ( ( bbBoxProcessModeIsReactive()  ||
483                        (c==bbGetInputConnectorMap().find("BoxExecute")->second))
484                      && (bbCanReact() ) )
485                   {
486                     bbtkDebugMessage("change",2,
487                                      "an input of "
488                                      <<bbGetFullName()
489                                      <<" changed and box is in Reactive mode or BoxExecute input changed : adding it to the global execution list"
490                                      <<std::endl);
491                     bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
492                   }
493                 // Have to propagate the modification to aval boxes
494                 OutputConnectorMapType::iterator i;
495                 for (i = bbGetOutputConnectorMap().begin();
496                      i != bbGetOutputConnectorMap().end();
497                      ++i)
498                   {
499                     i->second->SetChangeTime(t);
500                   }
501                 // update the MinOutputChangeTime
502                 mMinOutputChangeTime.Set(t);
503               }
504           }
505       }
506   }
507   //=========================================================================
508
509  //=========================================================================
510   ///  Sets the ChangeTime of output 
511   void BlackBox::bbSetOutputChangeTime(BlackBoxOutputConnector* c, 
512                                        const ChangeTime& t)
513   {
514     bbtkDebugMessage("change",1,
515                      "==> BlackBox::bbSetOutputChangeTime("<<c<<","<<t<<") ["
516                      <<bbGetFullName()<<"]"<<std::endl);
517     
518     //ChangeTime old = 
519     c->SetChangeTime(t);
520     // c->GetChangeTime() = t;
521     //    bbUpdateMinOutputChangeTime(t);
522     // propagate
523     
524   }
525   //=========================================================================
526   */
527
528   /*
529   //=========================================================================
530   void BlackBox::bbUpdateMaxInputChangeTime(const ChangeTime& t)
531   {    
532
533     
534     if ( t > mMaxInputChangeTime ) 
535       {
536         mMaxInputChangeTime = t;
537         if ( mMinOutputChangeTime > mMaxInputChangeTime )
538           {
539             
540           }
541       }
542     
543   }
544   //=========================================================================
545
546   //=========================================================================
547   void bbUpdateMinOutputChangeTime(const ChangeTime& t)
548   {
549     ChangeTime old = mMinOutputChangeTime;
550     mMinOutputChangeTime = MAXLONG;
551     OutputConnectorMapType::iterator i;
552     for (i = bbGetOutputConnectorMap.begin();
553          i != bbGetOutputConnectorMap.end();
554          ++i)
555       {
556         if (i->second->GetChangeTime() < mMinOutputChangeTime)
557           mMinOutputChangeTime = i->second->GetChangeTime();
558       }
559     if ( mMinOutputChangeTime < old )
560       {
561       }
562    
563   }
564   //=========================================================================
565   */
566
567   //=========================================================================
568   /// Signals that the BlackBox has been modified through 
569   /// the input connector c
570   /// and propagates it downward
571   /// ** NOT USER INTENDED **
572   void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
573                                          IOStatus s)
574   {
575     bbtkDebugMessageInc("change",5,
576                         "=> BlackBox::bbSetStatusAndPropagate(input,"
577                         <<GetIOStatusString(s)<<") ["
578                         <<bbGetFullName()<<"]"<<std::endl);
579
580     if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
581     c->SetStatus(s);
582     OutputConnectorMapType::const_iterator o;   
583     for ( o = bbGetOutputConnectorMap().begin(); 
584           o != bbGetOutputConnectorMap().end(); ++o )                   
585       {                                                                 
586         //      bbSetStatusAndPropagate(o->second, OUTOFDATE);
587         if (o->second->GetStatus()==UPTODATE) 
588           {
589             o->second->SetStatus(OUTOFDATE);
590             o->second->SignalChange(GetThisPointer<BlackBox>(),o->first); 
591           }
592       }                                                                 
593     
594     if ( ( bbBoxProcessModeIsReactive()  ||
595            (c==bbGetInputConnectorMap().find("BoxExecute")->second))
596          && (bbCanReact() ) )
597       {
598         bbtkDebugMessage("change",2,
599                          "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
600         bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
601       }    
602     bbtkDebugMessageInc("change",5,
603                         "<= BlackBox::bbSetStatusAndPropagate(input) ["
604                         <<bbGetFullName()<<"]"<<std::endl);
605   }
606   //=========================================================================
607
608   //=========================================================================
609   void BlackBox::bbSetStatusAndPropagate(BlackBoxOutputConnector* c,
610                                          IOStatus s)
611   {
612     bbtkError("bbSetStatusAndPropagate(BlackBoxOutputConnector* c,IOStatus s)");
613     /*
614     if (i->GetStatus()==UPTODATE) 
615       {
616         i->second->SetStatus(s);
617         i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
618       }
619     */
620   }
621   //=========================================================================
622  
623
624  ///  Signals that the BlackBox has been modified
625   /*
626   void BlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
627   {
628     bbtkDebugMessage("modified",1,
629                      "==> BlackBox::bbSetModifiedStatus("<<c<<") ["
630                      <<bbGetFullName()<<"]"<<std::endl);
631     
632     if ( (c==bbGetInputConnectorMap().find("WinHide")->second) )
633       //         && (bbCanReact()))
634       {
635         bbtkDebugMessage("modified",2,
636                          "-> Hide triggered by WinHide input change"
637                          <<std::endl);
638         this->bbHideWindow();
639         this->bbSetStatus(MODIFIED); 
640         return;
641       }
642     if ( (c==bbGetInputConnectorMap().find("WinClose")->second) )
643       //         && (bbCanReact()))
644       {
645         bbtkDebugMessage("modified",2,
646                          "-> Close triggered by WinClose input change"
647                          <<std::endl);
648         this->bbHideWindow();
649         this->bbSetStatus(MODIFIED); 
650         return;
651       }
652     
653     if ( ( bbBoxProcessModeIsReactive()  ||
654            (c==bbGetInputConnectorMap().find("BoxExecute")->second))
655          && (bbCanReact() ) )
656       {
657         bbtkDebugMessage("modified",2,
658                          "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
659         this->bbSetStatus(MODIFIED); 
660         bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
661       }
662     
663     //else if ( bbGetStatus() == MODIFIED ) //! this->bbIsUptodate()) 
664      // { 
665 //      bbtkDebugMessage("modified",2,"-> Already modified"<<std::endl);
666 //      return;
667  //     }
668    
669     else 
670       {
671         bbtkDebugMessage("modified",2,"-> Status set to modified"<<std::endl);
672         this->bbSetStatus(MODIFIED); 
673       }
674  
675     this->bbSignalOutputModification(false);
676
677   bbtkDebugMessageDec("process",5,
678                         "<= BlackBox::bbSetModifiedStatus("<<c<<") ["
679                         <<bbGetFullName()<<"]"<<std::endl);
680   }  
681 */
682   //=========================================================================
683
684   //=========================================================================  
685   void BlackBox::bbSignalOutputModification(bool reaction)
686   {
687     bbtkDebugMessageInc("change",5,
688                         "=> BlackBox::bbSignalOutputModification("
689                         <<reaction<<") ["
690                         <<bbGetFullName()<<"]"<<std::endl);
691     
692     OutputConnectorMapType::iterator i;
693     for ( i  = bbGetOutputConnectorMap().begin(); 
694           i != bbGetOutputConnectorMap().end(); ++i) 
695       {
696         if (i->second->GetStatus()==UPTODATE) 
697           {
698             //      i->second->SetStatus(MODIFIED);
699             i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
700           }
701       } 
702
703     if (reaction) bbGlobalProcessExecutionList();
704
705     bbtkDebugMessageDec("change",5,
706                         "<= BlackBox::bbSignalOutputModification() ["
707                         <<bbGetFullName()<<"]"<<std::endl);
708     
709   }  
710   //=========================================================================   
711   //=========================================================================  
712   void BlackBox::bbSignalOutputModification(const std::string& output,
713                                             bool reaction)
714   {
715     bbtkDebugMessageInc("change",5,
716                         "=> BlackBox::bbSignalOutputModification("
717                         <<output<<","<<reaction<<") ["
718                         <<bbGetFullName()<<"]"<<std::endl);
719     
720     OutputConnectorMapType::iterator i = 
721       bbGetOutputConnectorMap().find(output);
722
723
724     if ( i == bbGetOutputConnectorMap().end() ) 
725         {
726           bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
727         }
728
729     if (i->second->GetStatus()==UPTODATE) 
730       {
731         //      i->second->SetStatus(MODIFIED);
732         i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
733         // Has to notify the output "BoxChange" also
734         if (output != "BoxChange") 
735           {
736             i = bbGetOutputConnectorMap().find("BoxChange");
737             if ( i != bbGetOutputConnectorMap().end() ) 
738               {
739                 //              i->second->SetStatus(MODIFIED);
740                 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
741               }
742           }
743         if (reaction) bbGlobalProcessExecutionList();
744       }
745
746     bbtkDebugMessageDec("change",5,
747                         "<= BlackBox::bbSignalOutputModification("
748                         <<output<<") ["
749                         <<bbGetFullName()<<"]"<<std::endl);
750     
751   }  
752   //=========================================================================   
753   //=========================================================================  
754   void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
755         bool reaction)
756   {
757     bbtkDebugMessageInc("change",5,
758                         "=> BlackBox::bbSignalOutputModification(vector of outputs) ["
759                         <<bbGetFullName()<<"]"<<std::endl);
760     OutputConnectorMapType::iterator i;
761     std::vector<std::string>::const_iterator o;
762     bool changed = false;
763     for (o=output.begin();o!=output.end();++o) 
764       {
765         // the output "BoxChange" must be signaled **AFTER** all others
766         if (*o == "BoxChange") continue;
767         // Look for the connector
768         i = bbGetOutputConnectorMap().find(*o);
769         if ( i == bbGetOutputConnectorMap().end() ) 
770           {
771             bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
772           }
773         // Already OUTOFDATE : noting to do
774         if (i->second->GetStatus()==UPTODATE)
775           {
776             //  i->second->SetStatus(MODIFIED);
777             i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
778             changed = true;
779           }
780       }
781     // Has to notify the output "BoxChange" also
782     i = bbGetOutputConnectorMap().find("BoxChange");
783     if ( changed && (i != bbGetOutputConnectorMap().end())) 
784       {
785         // Already OUTOFDATE : noting to do
786         if (i->second->GetStatus()==UPTODATE) 
787           {
788             //  i->second->SetStatus(MODIFIED);
789             i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
790             if (reaction) bbGlobalProcessExecutionList();
791           }
792       }
793
794     bbtkDebugMessageDec("change",5,
795                         "<= BlackBox::bbSignalOutputModification(vector of outputs) ["
796                         <<bbGetFullName()<<"]"<<std::endl);
797
798   }  
799   //=========================================================================   
800
801   //=========================================================================
802   /// Updates the BlackBox inputs
803   /// Calls BackwardUpdate on all BlackBoxInputConnector
804   /// \returns The maximum of final IOStatus after each input update
805   IOStatus BlackBox::bbUpdateInputs()
806   {
807     bbtkDebugMessageInc("process",4,
808                         "=> BlackBox::bbUpdateInputs() ["
809                         <<bbGetFullName()<<"]"
810                         <<std::endl);   
811
812     IOStatus s = UPTODATE;
813
814     InputConnectorMapType::iterator i;
815     for ( i = bbGetInputConnectorMap().begin(); 
816           i!= bbGetInputConnectorMap().end(); ++i) 
817       {
818         //      if (i->first=="WinHide") continue;
819         // If input type is Void : no recurse
820         //if (  bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo() 
821         //      == typeid(Void) ) 
822         //  continue;
823         bbtkDebugMessageDec("change",2,
824                             bbGetName()<<"."<<i->first
825                             <<" ["<<i->second<<"] "
826                             <<" status before update = '"
827                             <<GetIOStatusString(i->second->GetStatus())
828                             <<"'"<<std::endl);
829         i->second->BackwardUpdate();
830         IOStatus t = i->second->GetStatus();
831         if (t > s) s = t;
832         bbtkDebugMessageDec("change",2,
833                             bbGetName()<<"."<<i->first
834                             <<" ["<<i->second<<"] "
835                             <<" status before process = '"
836                             <<GetIOStatusString(i->second->GetStatus())
837                             <<"'"<<std::endl);
838       }
839     
840     bbtkDebugMessageDec("process",4,
841                         "<= BlackBox::bbUpdateInputs() ["
842                         <<bbGetFullName()<<"]"
843                         <<std::endl);   
844     
845     
846     return s;
847   }
848   //=========================================================================
849
850   //==================================================================
851   /// Computes the final IOStatus of inputs and outputs after processing
852   void BlackBox::bbComputePostProcessStatus()
853   {
854     bbtkDebugMessageInc("process",4,
855                         "=> BlackBox::bbComputePostProcessStatus() ["
856                         <<bbGetFullName()<<"]"
857                         <<std::endl);   
858
859     IOStatus new_output_status = UPTODATE;
860     if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
861
862     // Update the input statuses
863     InputConnectorMapType::iterator i;
864     for ( i = bbGetInputConnectorMap().begin(); 
865           i!= bbGetInputConnectorMap().end(); ++i) 
866       {
867         IOStatus t = i->second->GetStatus();
868         if (t == OUTOFDATE) new_output_status = OUTOFDATE;
869         // A previously MODIFIED status turns to UPTODATE
870         if (t==MODIFIED) i->second->SetStatus(UPTODATE);
871         bbtkDebugMessage("change",2,
872                          bbGetName()<<"."<<i->first<<" : "
873                          << GetIOStatusString(t) << " -> "
874                          << GetIOStatusString(i->second->GetStatus())
875                          << std::endl);
876       }
877         bbtkDebugMessage("change",2,
878                          bbGetName()<<" new output status : "
879                          << GetIOStatusString(new_output_status)
880                          <<std::endl);
881     // Update the output statuses
882     OutputConnectorMapType::iterator o;
883     for ( o = bbGetOutputConnectorMap().begin(); 
884           o!= bbGetOutputConnectorMap().end(); ++o) 
885       {
886         o->second->SetStatus(new_output_status);
887       }
888
889     bbtkDebugMessageInc("process",4,
890                         "<= BlackBox::bbComputePostProcessStatus() ["
891                         <<bbGetFullName()<<"]"
892                         <<std::endl);   
893
894   }
895   //==================================================================
896
897   //=========================================================================
898   /// Connects the input <name> to the connection c
899   void BlackBox::bbConnectInput( const std::string& name, Connection* c)
900   {
901     bbtkDebugMessage("connection",2,
902                         "==> BlackBox::bbConnectInput(\""
903                         <<name<<"\","<<c->GetFullName()<<") ["
904                         <<bbGetFullName()<<"]"
905                         <<std::endl);       
906
907
908     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
909     if (i==bbGetInputConnectorMap().end())
910       {
911         bbtkError("no input called '"<<name<<"'");
912       }
913     i->second->SetConnection(c);
914
915     // Check the status of the from.output of c 
916     // to set the new status of the input
917     IOStatus s = MODIFIED;
918     if ( c->GetBlackBoxFrom()->bbGetOutputConnector(c->GetBlackBoxFromOutput()).GetStatus() == OUTOFDATE ) 
919       s = OUTOFDATE;
920     bbSetStatusAndPropagate(i->second,s);
921     
922     bbtkDebugMessage("connection",2,
923                         "<== BlackBox::bbConnectInput(\""
924                         <<name<<"\","<<c->GetFullName()<<") ["
925                         <<bbGetFullName()<<"]"
926                         <<std::endl);       
927
928   }
929   //=========================================================================
930
931
932   //=========================================================================  
933   /// Connects the output <name> to the connection c
934   void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
935   {
936     bbtkDebugMessage("connection",2,
937                      "==> BlackBox::bbConnectOutput(\""<<name<<"\","
938                      <<c->GetFullName()<<") ["
939                      <<bbGetFullName()<<"]"<<std::endl);       
940     
941     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
942     if (i==bbGetOutputConnectorMap().end())
943       {
944         bbtkError("no output called '"<<name<<"'");
945       }
946     i->second->SetConnection(c);
947
948     bbtkDebugMessage("connection",2,
949                      "<== BlackBox::bbConnectOutput(\""<<name<<"\","
950                      <<c->GetFullName()<<") ["
951                      <<bbGetFullName()<<"]"<<std::endl);       
952
953   }
954   //=========================================================================
955
956
957   //=========================================================================
958   /// Disconnects the input <name> from the connection c
959   void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
960   {
961
962     bbtkDebugMessage("connection",2,
963                      "==> BlackBox::bbDisconnectInput(\""<<name
964                      <<"\","<<c->GetFullName()<<") ["
965                      <<bbGetFullName()<<"]"
966                      <<std::endl);      
967
968     if (!c) 
969       {
970
971         bbtkDebugMessage("connection",2,"c==0"<<std::endl);     
972         return;
973       }
974
975     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
976     if (i==bbGetInputConnectorMap().end())
977       {
978         bbtkError("no input called '"<<name<<"'");
979       }
980     i->second->UnsetConnection(c);
981
982     bbtkDebugMessage("connection",2,
983                      "<== BlackBox::bbDisconnectInput(\""<<name
984                      <<"\","<<c->GetFullName()<<") ["
985                      <<bbGetFullName()<<"]"
986                      <<std::endl);      
987
988   }
989   //=========================================================================
990
991
992   //=========================================================================
993   /// Disconnects the output <name> from the connection c
994   void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
995   {
996     bbtkDebugMessage("connection",2,
997                      "==> BlackBox::bbDisconnectOutput(\""<<name
998                      <<"\","<<c->GetFullName()<<") ["
999                      <<bbGetFullName()<<"]"
1000                      <<std::endl);       
1001     if (!c) 
1002       {
1003
1004         bbtkDebugMessage("connection",2,"c==0"<<std::endl);     
1005         return;
1006       }
1007
1008     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
1009     if (i==bbGetOutputConnectorMap().end())
1010       {
1011         bbtkError("no output called '"<<name<<"'");
1012       }
1013     i->second->UnsetConnection(c);
1014
1015     bbtkDebugMessage("connection",2,
1016                      "<== BlackBox::bbDisconnectOutput(\""<<name
1017                      <<"\","<<c->GetFullName()<<") ["
1018                      <<bbGetFullName()<<"]"
1019                      <<std::endl);       
1020   } 
1021   //=========================================================================
1022  
1023
1024   //=========================================================================
1025   /// Virtual
1026   void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
1027   {
1028     fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
1029   }
1030   //=========================================================================
1031
1032
1033   //=========================================================================
1034   std::string BlackBox::bbGetOutputAsString( const std::string &output ) 
1035   {
1036     std::string v;
1037     // Looks for the adaptor
1038     if (bbGetOutputType(output).name() != typeid(std::string).name() ) 
1039       {
1040         // Look for factory 
1041         Package::Pointer p = bbGetDescriptor()->GetPackage();
1042         if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1043           {
1044             Factory::Pointer f = p->GetFactorySet().begin()->lock();
1045             BlackBox::Pointer a;
1046             try
1047               {
1048                 a = f->NewAdaptor(  
1049                                   bbGetOutputType(output),
1050                                   typeid(std::string),
1051                                   "");
1052               } catch (bbtk::Exception e) 
1053               {
1054               }
1055             if (a){
1056               //                        bbUpdate();
1057               a->bbSetInput("In",bbGetOutput(output));
1058               a->bbExecute();
1059               v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1060             } else {
1061               v="? (no adaptor found)";
1062             }
1063           }
1064         else 
1065           {
1066             v="? (no factory found)";
1067           }
1068       } 
1069     else 
1070       {
1071         //         bbUpdate();
1072         v = bbGetOutput(output).unsafe_get<std::string>() ;
1073       }
1074     return v;
1075   }
1076   //=========================================================================
1077
1078   //=========================================================================
1079   std::string BlackBox::bbGetInputAsString( const std::string &input ) 
1080   {
1081     std::string v;
1082     // Looks for the adaptor
1083     if (bbGetInputType(input) != typeid(std::string)) 
1084       {
1085         // Look for factory 
1086         Package::Pointer p = bbGetDescriptor()->GetPackage();
1087         if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1088           {
1089             Factory::Pointer f = p->GetFactorySet().begin()->lock();
1090             BlackBox::Pointer a;
1091             try
1092               {
1093                 a = f->NewAdaptor(  
1094                                bbGetInputType(input),
1095                                typeid(std::string),
1096                                "");
1097               }catch (bbtk::Exception e) 
1098               {
1099               }
1100             if (a)
1101               {
1102                 //                      bbUpdate();
1103                 a->bbSetInput("In",bbGetInput(input));
1104                 a->bbExecute();
1105                 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1106               } 
1107             else 
1108               {
1109                 v="? (no adaptor found)";
1110               }
1111           } 
1112         else 
1113           {
1114             v="? (no factory found)";
1115           }
1116       }
1117     else 
1118       {
1119         v = bbGetInput(input).unsafe_get<std::string>() ;
1120       }
1121     return v;
1122   }
1123   //=======================================================================
1124
1125   //=======================================================================
1126   // Replaces substrings "<" by "["
1127   void SubsBrackets ( std::string& s )
1128   {
1129     //   std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1130     std::string ss("<");
1131     std::string::size_type pos = 0;
1132     pos = s.find(ss,0);
1133     std::string cr("[");
1134     while ( pos != std::string::npos )
1135       {
1136         //      std::cout << "*** find one "<<std::endl;
1137         s.replace(pos,1,cr.c_str(),1);
1138         pos = s.find(ss, pos);
1139       } 
1140     ss = ">";
1141     pos = 0;
1142     pos = s.find(ss,0);
1143     cr = "]";
1144     while ( pos != std::string::npos )
1145       {
1146         //      std::cout << "*** find one "<<std::endl;
1147         s.replace(pos,1,cr.c_str(),1);
1148         pos = s.find(ss, pos);
1149       } 
1150     ss = ",";
1151     pos = 0;
1152     pos = s.find(ss,0);
1153     cr = "-";
1154     while ( pos != std::string::npos )
1155       {
1156         //      std::cout << "*** find one "<<std::endl;
1157         s.replace(pos,1,cr.c_str(),1);
1158         pos = s.find(ss, pos);
1159       }     //    std::cout << "AFTER=["<<s<<"]"<<std::endl;
1160   }
1161   //=======================================================================
1162
1163   //=========================================================================
1164   /// Write Graphviz-dot description in file
1165   void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1166                                         BlackBox::Pointer parentblackbox, 
1167                                         int detail, int level,
1168                                         bool instanceOrtype,
1169                                         bool relative_link )
1170
1171   { 
1172     InputConnectorMapType::iterator i;
1173     // label
1174     std::string labelStr;
1175     std::string valueStr("");
1176
1177         if (detail==0) {
1178                 labelStr = bbGetName() ; 
1179 //EED 18 Fev 2008
1180                 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1181         } else {
1182                 labelStr = bbGetName();
1183                 labelStr = labelStr + "   [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]  ";
1184     }
1185
1186     SubsBrackets(labelStr);
1187     if (detail==1)
1188       {
1189         labelStr = labelStr + " | {{ "; 
1190         std::string tempStrTypeName;
1191         bool tmp; 
1192         tmp=false;
1193         for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
1194           {
1195             if (tmp==true)
1196               {
1197                 labelStr=labelStr+" | ";
1198               }
1199             tmp=true;
1200             if (instanceOrtype==true)
1201               {
1202                 valueStr = this->bbGetInputAsString(i->first) + " = ";
1203               } 
1204             const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1205             tempStrTypeName=id->GetTypeName();
1206             SubsBrackets(tempStrTypeName);
1207             std::string Name(i->first);
1208             SubsBrackets(Name);
1209             labelStr=labelStr + "<"+i->first.c_str()+"> "  + valueStr +  Name.c_str() + "  [" + tempStrTypeName.c_str() + "]";
1210           }
1211         labelStr=labelStr+ " } | {";
1212         tmp = false;
1213         OutputConnectorMapType::iterator ii;
1214         for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii ) 
1215         {
1216            if (tmp==true)
1217            {
1218                    labelStr=labelStr+" | ";
1219            }
1220            tmp = true;
1221            if (instanceOrtype==true)
1222            {
1223                    valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1224            }
1225            const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first); 
1226            tempStrTypeName=id->GetTypeName();
1227            SubsBrackets(tempStrTypeName);
1228             std::string Name(ii->first);
1229             SubsBrackets(Name);
1230            labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + "  ["+tempStrTypeName+"]";
1231         }
1232         labelStr = labelStr+ "      } }" ;
1233 } // detail
1234
1235     fprintf(ff,"  " );
1236     bbWriteDotInputOutputName(ff,true,detail,level);
1237     std::string tmp ( bbGetTypeName() );
1238     SubsBrackets(tmp);
1239     std::string url;
1240     if (relative_link) 
1241       url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1242     else 
1243       url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1244   
1245     fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1246     //    std::cout  << labelStr << std::endl;
1247
1248     // Relation Input
1249     if (GetThisPointer<BlackBox>()!=parentblackbox){
1250       for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
1251         {
1252           if (i->second)
1253             {
1254               Connection* con = i->second->GetConnection();
1255               if (con!=NULL){
1256                 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1257                 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1258                 fprintf(ff,"  ");
1259                 a->bbWriteDotInputOutputName(ff,false,detail,level);
1260                 if (detail==1)
1261                   {
1262                     fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1263                   }
1264                 fprintf(ff,"->");
1265                 b->bbWriteDotInputOutputName(ff,true,detail,level);
1266                 if (detail==1)
1267                   {
1268                     fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1269                   }
1270                 fprintf(ff,"%s\n",";");
1271               }  // if con
1272             } // if second
1273         } // for
1274     } // if parentblackbox
1275   }
1276   //=========================================================================
1277
1278
1279
1280
1281   //=========================================================================
1282   void BlackBox::bbShowRelations(BlackBox::Pointer parentblackbox, 
1283                                  int detail, int level
1284                                  /*,Factory *factory*/ )
1285   {
1286      
1287     if (this->bbGetDescriptor()->GetPackage()) 
1288       {
1289         bbtkMessage("Help",1,"Black Box '"<<bbGetName()<<"' <"<<
1290                     this->bbGetDescriptor()->GetPackage()->GetName()
1291                     <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1292       }
1293     else 
1294       {
1295         bbtkMessage("Help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1296       }
1297     /*
1298     if (bbIsUpToDate())
1299       {
1300         bbtkMessage("Help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1301                     <<mMinOutputChangeTime<<"]"<<std::endl);
1302       }
1303     else 
1304       {
1305         bbtkMessage("Help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1306                     <<mMinOutputChangeTime<<"]"<<std::endl);
1307       }
1308     */
1309     //    bbtkMessage("Help",1," "<<GetDescription()<<std::endl);
1310     //    bbtkMessage("Help",1," By : "<<GetAuthor()<<std::endl);
1311
1312     std::vector<std::string> iname;
1313     std::vector<std::string> ivalue;
1314     std::vector<std::string> iconn;
1315     std::vector<std::string> istatus;
1316
1317     InputConnectorMapType::iterator i;
1318     unsigned int namelmax = 0;
1319     unsigned int valuelmax = 0;
1320     //   unsigned int connlmax = 0;
1321     for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
1322       {
1323         iname.push_back(i->first);
1324         if (iname.back().size()>namelmax) namelmax = iname.back().size();
1325         ivalue.push_back(bbGetInputAsString(i->first));
1326         if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1327         std::string s("");
1328         Connection* con = i->second->GetConnection();
1329         if (con!=0){
1330           s = con->GetOriginalBlackBoxFrom()->bbGetName();
1331           s += ".";
1332           s += con->GetOriginalBlackBoxFromOutput();
1333         }  // if con
1334         iconn.push_back(s);
1335         istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1336       }
1337     OutputConnectorMapType::iterator o;
1338     std::vector<std::string> oname;
1339     std::vector<std::string> ovalue;
1340     std::vector<std::vector<std::string> > oconn;
1341     std::vector<std::string> ostatus;
1342     for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o ) 
1343       {
1344         oname.push_back(o->first);
1345         if (oname.back().size()>namelmax) namelmax = oname.back().size();
1346         ovalue.push_back(bbGetOutputAsString(o->first));
1347         if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size();
1348         std::vector<std::string> ss;
1349         const std::vector<Connection*>& con 
1350           = o->second->GetConnectionVector();
1351         std::vector<Connection*>::const_iterator c;
1352         for (c=con.begin();c!=con.end();++c) 
1353           {
1354             std::string s;
1355             s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1356             s += ".";
1357             s += (*c)->GetOriginalBlackBoxToInput();
1358             ss.push_back(s);
1359         }  // if con
1360         oconn.push_back(ss);
1361         ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1362       }
1363
1364     if (iname.size()) 
1365       bbtkMessage("Help",1," * Inputs : "<<std::endl);
1366     else 
1367       bbtkMessage("Help",1," * No inputs"<<std::endl);
1368
1369     std::vector<std::string>::iterator i1,i2,i3,i4;
1370     for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1371          i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1372          ++i1,++i2,++i3,++i4)
1373       {
1374         std::string name(*i1);
1375         name += "'";
1376         name.append(1+namelmax-name.size(),' ');
1377         std::string value(*i2);
1378         value += "'";
1379         value.append(1+valuelmax-value.size(),' ');
1380         if (i3->size()) 
1381           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<" <-- '"
1382                       <<*i3<<"'");
1383         else 
1384           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value);
1385         bbtkMessage("Help",1," ["<<*i4<<"]"<<std::endl);
1386       }
1387
1388     if (oname.size()) 
1389       bbtkMessage("Help",1," * Outputs : "<<std::endl);
1390     else 
1391       bbtkMessage("Help",1," * No outputs"<<std::endl);
1392
1393     std::vector<std::vector<std::string> >::iterator i5;
1394
1395     for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1396          i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1397          ++i1,++i2,++i4,++i5)
1398       {
1399         std::string name(*i1);
1400         name += "'";
1401         name.append(1+namelmax-name.size(),' ');
1402         std::string value(*i2);
1403         value += "'";
1404         value.append(1+valuelmax-value.size(),' ');
1405         if (!(*i5).size())
1406           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value);
1407         else 
1408           {
1409             std::string pref = "    '"+name+" = '"+value;
1410             for (i3=i5->begin();i3!=i5->end();++i3)
1411               {
1412                 bbtkMessage("Help",1,pref<<" --> '"<<*i3<<"'");
1413                 pref.replace(0,pref.size(),pref.size(),' ');
1414               }
1415           }
1416         bbtkMessage("Help",1," ["<<*i4<<"]"<<std::endl);
1417       }
1418
1419    }
1420   //=========================================================================
1421
1422   static bool bbmgGlobalProcessingExecutionList = false;
1423
1424   //=========================================================================
1425    void BlackBox::bbGlobalProcessExecutionList()
1426    {   
1427      bbtkDebugMessageInc("process",3,
1428                          "=> BlackBox::bbGlobalProcessExecutionList()"
1429                          <<std::endl);    
1430      if (bbmgGlobalProcessingExecutionList) 
1431        {
1432          bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1433          return;
1434        }
1435      bbmgGlobalProcessingExecutionList = true;
1436
1437      std::set<BlackBox::WeakPointer>::iterator i; 
1438      while (bbmgExecutionList.size()>0)
1439        {
1440          i = bbmgExecutionList.begin();
1441          BlackBox::WeakPointer p = *i;
1442          bbmgExecutionList.erase(i);
1443          if (p.lock())
1444            {
1445              bbtkDebugMessage("process",4,
1446                               " -> Executing "<<
1447                               p.lock()->bbGetFullName()<<std::endl);
1448              p.lock()->bbExecute(true);
1449            }
1450          else 
1451            {
1452              bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1453            }
1454        }
1455      
1456      bbmgExecutionList.clear();
1457      bbtkDebugMessageDec("process",3,
1458                          "<= BlackBox::bbGlobalProcessExecutionList()"
1459                          <<std::endl);     
1460      
1461      bbmgGlobalProcessingExecutionList = false;
1462      
1463    }
1464   //=========================================================================
1465
1466     bool BlackBox::bbGlobalGetSomeBoxExecuting()
1467         { 
1468                 return bbmgSomeBoxExecuting; 
1469         }
1470
1471     void BlackBox::bbGlobalSetSomeBoxExecuting(bool b) 
1472         { 
1473                 bbmgSomeBoxExecuting = b; 
1474         }
1475
1476     void BlackBox::bbGlobalSetFreezeExecution(bool b) 
1477         { 
1478                 bbmgFreezeExecution = b;
1479         }
1480
1481     bool BlackBox::bbGlobalGetFreezeExecution() 
1482         { 
1483                 return bbmgFreezeExecution; 
1484         }
1485
1486   void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1487   {  
1488     bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetFullName()<<")"<<std::endl);
1489     if (bbmgGlobalProcessingExecutionList) 
1490       {
1491         bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1492       }
1493     bbmgExecutionList.insert(b); 
1494   } 
1495
1496
1497    //=========================================================================
1498
1499   //=========================================================================
1500   void BlackBox::Check(bool recursive)
1501   {
1502     bbtkMessage("debug",1,"*** Checking Black Box "<<(void*)this<<" ["<<bbGetFullName()
1503                 <<"] ... OK"<<std::endl);
1504   }
1505   //=========================================================================
1506
1507   void BlackBox::bbUserOnShowWidget(std::string nameInput)
1508   {
1509           bbtk::BlackBoxInputConnector *cc;
1510           cc = this->bbGetInputConnectorMap().find( nameInput.c_str() )->second;
1511           if (cc->GetConnection()!=NULL) 
1512           {
1513                   cc->GetConnection()->GetBlackBoxFrom()->bbUserOnShow();
1514           }
1515   }
1516
1517
1518
1519 }  // EO namespace bbtk
1520
1521 // EOF
1522