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