]> Creatis software - bbtk.git/blob - kernel/src/bbtkBlackBox.cxx
MagicBox : support of data synchronization + various related fixes
[bbtk.git] / kernel / src / bbtkBlackBox.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkBlackBox.cxx,v $
4   Language:  C++
5   Date:      $Date: 2009/03/30 14:42:16 $
6   Version:   $Revision: 1.41 $
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     /*
387     if ( (p == "3") ||
388          (p == "F") || (p == "f") ||
389          (p == "Flash") || (p == "flash") ) return Flash;
390     */
391     bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
392               <<"' unknown. Possible values : "
393               <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
394               <<"'1'/'A'/'a'/'Always'/'always' | "
395               <<"'2'/'R'/'r'/'Reactive'/'reactive'"
396               //      <<"'3'/'F'/'f'/'Flash'/'flash'"
397               <<std::endl);
398   }
399   //=========================================================================
400   
401   //=========================================================================
402   bool  BlackBox::bbBoxProcessModeIsReactive() const
403   {
404     return (bbGetBoxProcessModeValue() == Reactive);
405   }
406   //=========================================================================
407
408   //=========================================================================
409   bool  BlackBox::bbBoxProcessModeIsAlways() const
410   {
411     return (bbGetBoxProcessModeValue() == Always);
412   }
413   //=========================================================================
414
415
416
417
418   //=========================================================================
419   void BlackBox::bbAddOutputObserver(const std::string& output, 
420                                    OutputChangeCallbackType f)
421   {
422     bbGetOutputConnector(output).AddChangeObserver(f);
423   }  
424   //=========================================================================
425
426   //=========================================================================
427   void BlackBox::bbRemoveOutputObserver(const std::string& output_name, 
428                                       OutputChangeCallbackType f)
429   {
430     bbtkError("BlackBox::RemoveChangeObserver NOT IMPLEMENTED");
431   }
432   //=========================================================================
433
434
435   /*
436   //=========================================================================
437   ///  Sets the ChangeTime of input 
438   void BlackBox::bbSetInputChangeTime(BlackBoxInputConnector* c, 
439                                       const ChangeTime& t)
440   {
441     bbtkDebugMessage("change",1,
442                      "==> BlackBox::bbSetInputChangeTime("<<c<<","<<t<<") ["
443                      <<bbGetFullName()<<"]"<<std::endl);
444     
445     // If new time is greater than old one
446     if ( c->SetChangeTime(t) ) 
447       {
448         bool was_up_to_date = bbIsUpToDate();
449         // If new time is greater than the old max time of inputs
450         if ( mMaxInputChangeTime.Set(t) ) 
451           {
452             // If the box turned out-of-date
453             if ( was_up_to_date && bbIsOutOfDate() )
454               {
455                 // 
456                 if ( ( bbBoxProcessModeIsReactive()  ||
457                        (c==bbGetInputConnectorMap().find("BoxExecute")->second))
458                      && (bbCanReact() ) )
459                   {
460                     bbtkDebugMessage("change",2,
461                                      "an input of "
462                                      <<bbGetFullName()
463                                      <<" changed and box is in Reactive mode or BoxExecute input changed : adding it to the global execution list"
464                                      <<std::endl);
465                     bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
466                   }
467                 // Have to propagate the modification to aval boxes
468                 OutputConnectorMapType::iterator i;
469                 for (i = bbGetOutputConnectorMap().begin();
470                      i != bbGetOutputConnectorMap().end();
471                      ++i)
472                   {
473                     i->second->SetChangeTime(t);
474                   }
475                 // update the MinOutputChangeTime
476                 mMinOutputChangeTime.Set(t);
477               }
478           }
479       }
480   }
481   //=========================================================================
482
483  //=========================================================================
484   ///  Sets the ChangeTime of output 
485   void BlackBox::bbSetOutputChangeTime(BlackBoxOutputConnector* c, 
486                                        const ChangeTime& t)
487   {
488     bbtkDebugMessage("change",1,
489                      "==> BlackBox::bbSetOutputChangeTime("<<c<<","<<t<<") ["
490                      <<bbGetFullName()<<"]"<<std::endl);
491     
492     //ChangeTime old = 
493     c->SetChangeTime(t);
494     // c->GetChangeTime() = t;
495     //    bbUpdateMinOutputChangeTime(t);
496     // propagate
497     
498   }
499   //=========================================================================
500   */
501
502   /*
503   //=========================================================================
504   void BlackBox::bbUpdateMaxInputChangeTime(const ChangeTime& t)
505   {    
506
507     
508     if ( t > mMaxInputChangeTime ) 
509       {
510         mMaxInputChangeTime = t;
511         if ( mMinOutputChangeTime > mMaxInputChangeTime )
512           {
513             
514           }
515       }
516     
517   }
518   //=========================================================================
519
520   //=========================================================================
521   void bbUpdateMinOutputChangeTime(const ChangeTime& t)
522   {
523     ChangeTime old = mMinOutputChangeTime;
524     mMinOutputChangeTime = MAXLONG;
525     OutputConnectorMapType::iterator i;
526     for (i = bbGetOutputConnectorMap.begin();
527          i != bbGetOutputConnectorMap.end();
528          ++i)
529       {
530         if (i->second->GetChangeTime() < mMinOutputChangeTime)
531           mMinOutputChangeTime = i->second->GetChangeTime();
532       }
533     if ( mMinOutputChangeTime < old )
534       {
535       }
536    
537   }
538   //=========================================================================
539   */
540
541   //=========================================================================
542   /// Signals that the BlackBox has been modified through 
543   /// the input connector c
544   /// and propagates it downward
545   /// ** NOT USER INTENDED **
546   void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
547                                          IOStatus s)
548   {
549     bbtkDebugMessageInc("change",5,
550                         "=> BlackBox::bbSetStatusAndPropagate(input,"
551                         <<GetIOStatusString(s)<<") ["
552                         <<bbGetFullName()<<"]"<<std::endl);
553
554     if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
555     c->SetStatus(s);
556
557     // Flash reaction
558     /*
559     if (bbGetBoxProcessModeValue() == Flash)
560       {
561         this->bbExecute();
562       }
563     */
564
565     OutputConnectorMapType::const_iterator o;   
566     for ( o = bbGetOutputConnectorMap().begin(); 
567           o != bbGetOutputConnectorMap().end(); ++o )                   
568       {                                                                 
569         if (o->second->GetStatus()==UPTODATE) 
570           {
571             o->second->SetStatus(OUTOFDATE);
572             o->second->SignalChange(GetThisPointer<BlackBox>(),o->first); 
573           }
574       }                                                                 
575     
576     if ( ( bbBoxProcessModeIsReactive()  ||
577            (c==bbGetInputConnectorMap().find("BoxExecute")->second))
578          && (bbCanReact() ) )
579       {
580         bbtkDebugMessage("change",2,
581                          "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
582         bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
583       }    
584     bbtkDebugMessageInc("change",5,
585                         "<= BlackBox::bbSetStatusAndPropagate(input) ["
586                         <<bbGetFullName()<<"]"<<std::endl);
587   }
588   //=========================================================================
589
590
591   //=========================================================================  
592   void BlackBox::bbSignalOutputModification(bool reaction)
593   {
594     bbtkDebugMessageInc("change",5,
595                         "=> BlackBox::bbSignalOutputModification("
596                         <<reaction<<") ["
597                         <<bbGetFullName()<<"]"<<std::endl);
598     
599     OutputConnectorMapType::iterator i;
600     for ( i  = bbGetOutputConnectorMap().begin(); 
601           i != bbGetOutputConnectorMap().end(); ++i) 
602       {
603         //      std::cout << "Stat = "
604         //<<GetIOStatusString(i->second->GetStatus())
605         //                <<std::endl;
606         // LG : CANNOT SIGNAL ONLY WHEN UPTODATE 
607         // See bbtkSampleOutputObserver
608         //      if (i->second->GetStatus()==UPTODATE) 
609         //        {
610             i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
611             //    }
612       } 
613
614     if (reaction) bbGlobalProcessExecutionList();
615
616     bbtkDebugMessageDec("change",5,
617                         "<= BlackBox::bbSignalOutputModification() ["
618                         <<bbGetFullName()<<"]"<<std::endl);
619     
620   }  
621   //=========================================================================   
622   //=========================================================================  
623   void BlackBox::bbSignalOutputModification(const std::string& output,
624                                             bool reaction)
625   {
626     bbtkDebugMessageInc("change",5,
627                         "=> BlackBox::bbSignalOutputModification("
628                         <<output<<","<<reaction<<") ["
629                         <<bbGetFullName()<<"]"<<std::endl);
630     
631     OutputConnectorMapType::iterator i = 
632       bbGetOutputConnectorMap().find(output);
633
634
635     if ( i == bbGetOutputConnectorMap().end() ) 
636         {
637           bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
638         }
639
640     //    if (i->second->GetStatus()==UPTODATE) 
641     //      {
642         i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
643         // Has to notify the output "BoxChange" also
644         if (output != "BoxChange") 
645           {
646             i = bbGetOutputConnectorMap().find("BoxChange");
647             if ( i != bbGetOutputConnectorMap().end() ) 
648               {
649                 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
650               }
651           }
652         if (reaction) bbGlobalProcessExecutionList();
653         //      }
654
655     bbtkDebugMessageDec("change",5,
656                         "<= BlackBox::bbSignalOutputModification("
657                         <<output<<") ["
658                         <<bbGetFullName()<<"]"<<std::endl);
659     
660   }  
661   //=========================================================================   
662   //=========================================================================  
663   void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
664         bool reaction)
665   {
666     bbtkDebugMessageInc("change",5,
667                         "=> BlackBox::bbSignalOutputModification(vector of outputs) ["
668                         <<bbGetFullName()<<"]"<<std::endl);
669     OutputConnectorMapType::iterator i;
670     std::vector<std::string>::const_iterator o;
671     bool changed = false;
672     for (o=output.begin();o!=output.end();++o) 
673       {
674         // the output "BoxChange" must be signaled **AFTER** all others
675         if (*o == "BoxChange") continue;
676         // Look for the connector
677         i = bbGetOutputConnectorMap().find(*o);
678         if ( i == bbGetOutputConnectorMap().end() ) 
679           {
680             bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
681           }
682
683         //      if (i->second->GetStatus()==UPTODATE)
684         //        {
685             i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
686             changed = true;
687             //  }
688       }
689     // Has to notify the output "BoxChange" also
690     i = bbGetOutputConnectorMap().find("BoxChange");
691     if ( changed && (i != bbGetOutputConnectorMap().end())) 
692       {
693         // if (i->second->GetStatus()==UPTODATE) 
694         //        {
695             i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
696             if (reaction) bbGlobalProcessExecutionList();
697             //  }
698       }
699
700     bbtkDebugMessageDec("change",5,
701                         "<= BlackBox::bbSignalOutputModification(vector of outputs) ["
702                         <<bbGetFullName()<<"]"<<std::endl);
703
704   }  
705   //=========================================================================   
706
707
708
709
710
711
712
713   //=========================================================================
714   /// Main processing method of the box.
715   void BlackBox::bbExecute(bool force)
716   {
717     bbtkDebugMessageInc("process",2,
718                         "=> BlackBox::bbExecute("<<(int)force<<") ["
719                         <<bbGetFullName()<<"]"<<std::endl);
720  
721     // If already executing : return
722     /*
723     if (bbGetExecuting()) 
724       {
725         bbtkDebugMessage("process",2,
726                          " -> already executing : abort"<<std::endl);
727         return;
728       }
729     */
730
731     // If execution frozen : return
732     if (bbGlobalGetFreezeExecution()) 
733       {
734         bbtkDebugMessage("process",2,
735                          " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
736       }
737
738     BBTK_BUSY_CURSOR;
739
740     // If force is true then update is triggered even if the box is UPTODATE
741     //    if (force) bbSetModifiedStatus();
742
743     // Calls the main recursive execution method 
744     bbRecursiveExecute(Connection::Pointer());
745
746     bbtkDebugMessageDec("process",2,
747                         "<= BlackBox::bbExecute() ["
748                         <<bbGetFullName()<<"]"<<std::endl);
749   }
750   //=========================================================================
751
752
753   //=========================================================================
754   /// Main recursive processing method of the box.
755   void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
756   {
757     bbtkDebugMessageInc("process",3,
758                         "=> BlackBox::bbRecursiveExecute("
759                         <<(caller?caller->GetFullName():"0")<<") ["
760                         <<bbGetFullName()<<"]"<<std::endl);
761
762     // If already executing : return
763     if (bbGetExecuting()) 
764       {
765         bbtkDebugMessage("process",3,
766                          " -> already executing : abort"<<std::endl);
767         return; 
768       }
769
770     bbSetExecuting(true);
771     bool wasExecuting = bbGlobalGetSomeBoxExecuting();
772     bbGlobalSetSomeBoxExecuting(true);
773
774         this->bbCreateWidget();
775
776     // Updates its inputs
777     IOStatus s = bbUpdateInputs();
778     
779     if ( (s != UPTODATE) ||
780          bbBoxProcessModeIsAlways() )
781       {
782           // Displays the window (WxBlackbox)
783           //    bbShowWindow(caller);
784
785           // Actual processing (virtual)
786           this->bbProcess();
787         
788         
789           // Update the I/O statuses
790           bbComputePostProcessStatus();
791       }
792     else 
793       {
794         // Test output status...
795         OutputConnectorMapType::iterator o;
796         for ( o = bbGetOutputConnectorMap().begin(); 
797               o!= bbGetOutputConnectorMap().end(); ++o) 
798           {
799             if (o->second->GetStatus() != UPTODATE)
800               {
801                 bbtkWarning("BlackBox::bbRecursiveExecute ["
802                             <<bbGetFullName()
803                             <<"] : all inputs are Up-to-date but output '"
804                             <<o->first<<"' is Out-of-date ???");
805               }
806           }
807         
808         bbtkDebugMessage("process",3," -> Up-to-date : nothing to do"
809                          <<std::endl);
810       }
811
812           this->bbShowWidget(); 
813
814           
815     bbtkDebugMessage("process",3,
816             "<= BlackBox::bbRecursiveExecute() ["
817             <<bbGetFullName()<<"]"<<std::endl);
818
819     bbSetExecuting(false);
820     bbGlobalSetSomeBoxExecuting(wasExecuting);
821
822     return; 
823
824   }
825   //=========================================================================
826   
827    
828
829
830
831   //=========================================================================
832   /// Updates the BlackBox inputs
833   /// Calls RecursiveExecute on all BlackBoxInputConnector
834   /// \returns The maximum of final IOStatus after each input update
835   IOStatus BlackBox::bbUpdateInputs()
836   {
837     bbtkDebugMessageInc("process",4,
838                         "=> BlackBox::bbUpdateInputs() ["
839                         <<bbGetFullName()<<"]"
840                         <<std::endl);   
841
842     IOStatus s = UPTODATE;
843
844     InputConnectorMapType::iterator i;
845     for ( i = bbGetInputConnectorMap().begin(); 
846           i!= bbGetInputConnectorMap().end(); ++i) 
847       {
848         //      if (i->first=="WinHide") continue;
849         // If input type is Void : no recurse
850         //if (  bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo() 
851         //      == typeid(Void) ) 
852         //  continue;
853         bbtkDebugMessageDec("change",2,
854                             bbGetName()<<"."<<i->first
855                             <<" ["<<i->second<<"] "
856                             <<" status before update = '"
857                             <<GetIOStatusString(i->second->GetStatus())
858                             <<"'"<<std::endl);
859         i->second->RecursiveExecute();
860         IOStatus t = i->second->GetStatus();
861         if (t > s) s = t;
862         bbtkDebugMessageDec("change",2,
863                             bbGetName()<<"."<<i->first
864                             <<" ["<<i->second<<"] "
865                             <<" status before process = '"
866                             <<GetIOStatusString(i->second->GetStatus())
867                             <<"'"<<std::endl);
868       }
869     
870     bbtkDebugMessageDec("process",4,
871                         "<= BlackBox::bbUpdateInputs() ["
872                         <<bbGetFullName()<<"]"
873                         <<std::endl);   
874     
875     
876     return s;
877   }
878   //=========================================================================
879
880   //==================================================================
881   /// Computes the final IOStatus of inputs and outputs after processing
882   void BlackBox::bbComputePostProcessStatus()
883   {
884     bbtkDebugMessageInc("process",4,
885                         "=> BlackBox::bbComputePostProcessStatus() ["
886                         <<bbGetFullName()<<"]"
887                         <<std::endl);   
888
889     IOStatus new_output_status = UPTODATE;
890     if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
891
892     // Update the input statuses
893     InputConnectorMapType::iterator i;
894     for ( i = bbGetInputConnectorMap().begin(); 
895           i!= bbGetInputConnectorMap().end(); ++i) 
896       {
897         IOStatus t = i->second->GetStatus();
898         if (t == OUTOFDATE) new_output_status = OUTOFDATE;
899         // A previously MODIFIED status turns to UPTODATE
900         if (t==MODIFIED) i->second->SetStatus(UPTODATE);
901         bbtkDebugMessage("change",2,
902                          bbGetName()<<"."<<i->first<<" : "
903                          << GetIOStatusString(t) << " -> "
904                          << GetIOStatusString(i->second->GetStatus())
905                          << std::endl);
906       }
907         bbtkDebugMessage("change",2,
908                          bbGetName()<<" new output status : "
909                          << GetIOStatusString(new_output_status)
910                          <<std::endl);
911     // Update the output statuses
912     OutputConnectorMapType::iterator o;
913     for ( o = bbGetOutputConnectorMap().begin(); 
914           o!= bbGetOutputConnectorMap().end(); ++o) 
915       {
916         o->second->SetStatus(new_output_status);
917       }
918
919     bbtkDebugMessageInc("process",4,
920                         "<= BlackBox::bbComputePostProcessStatus() ["
921                         <<bbGetFullName()<<"]"
922                         <<std::endl);   
923
924   }
925   //==================================================================
926
927   //=========================================================================
928   /// Connects the input <name> to the connection c
929   void BlackBox::bbConnectInput( const std::string& name, Connection* c)
930   {
931     bbtkDebugMessage("connection",2,
932                         "==> BlackBox::bbConnectInput(\""
933                         <<name<<"\","<<c->GetFullName()<<") ["
934                         <<bbGetFullName()<<"]"
935                         <<std::endl);       
936
937
938     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
939     if (i==bbGetInputConnectorMap().end())
940       {
941         bbtkError("no input called '"<<name<<"'");
942       }
943     i->second->SetConnection(c);
944     // The input *MUST* be set OUTOFDATE to update its input on next execution
945     bbSetStatusAndPropagate(i->second,OUTOFDATE);
946     
947     bbtkDebugMessage("connection",2,
948                         "<== BlackBox::bbConnectInput(\""
949                         <<name<<"\","<<c->GetFullName()<<") ["
950                         <<bbGetFullName()<<"]"
951                         <<std::endl);       
952
953   }
954   //=========================================================================
955
956
957   //=========================================================================  
958   /// Connects the output <name> to the connection c
959   void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
960   {
961     bbtkDebugMessage("connection",2,
962                      "==> BlackBox::bbConnectOutput(\""<<name<<"\","
963                      <<c->GetFullName()<<") ["
964                      <<bbGetFullName()<<"]"<<std::endl);       
965     
966     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
967     if (i==bbGetOutputConnectorMap().end())
968       {
969         bbtkError("no output called '"<<name<<"'");
970       }
971     i->second->SetConnection(c);
972
973     bbtkDebugMessage("connection",2,
974                      "<== BlackBox::bbConnectOutput(\""<<name<<"\","
975                      <<c->GetFullName()<<") ["
976                      <<bbGetFullName()<<"]"<<std::endl);       
977
978   }
979   //=========================================================================
980
981
982   //=========================================================================
983   /// Disconnects the input <name> from the connection c
984   void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
985   {
986
987     bbtkDebugMessage("connection",2,
988                      "==> BlackBox::bbDisconnectInput(\""<<name
989                      <<"\","<<c->GetFullName()<<") ["
990                      <<bbGetFullName()<<"]"
991                      <<std::endl);      
992
993     if (!c) 
994       {
995
996         bbtkDebugMessage("connection",2,"c==0"<<std::endl);     
997         return;
998       }
999
1000     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
1001     if (i==bbGetInputConnectorMap().end())
1002       {
1003         bbtkError("no input called '"<<name<<"'");
1004       }
1005     i->second->UnsetConnection(c);
1006
1007     bbtkDebugMessage("connection",2,
1008                      "<== BlackBox::bbDisconnectInput(\""<<name
1009                      <<"\","<<c->GetFullName()<<") ["
1010                      <<bbGetFullName()<<"]"
1011                      <<std::endl);      
1012
1013   }
1014   //=========================================================================
1015
1016
1017   //=========================================================================
1018   /// Disconnects the output <name> from the connection c
1019   void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
1020   {
1021     bbtkDebugMessage("connection",2,
1022                      "==> BlackBox::bbDisconnectOutput(\""<<name
1023                      <<"\","<<c->GetFullName()<<") ["
1024                      <<bbGetFullName()<<"]"
1025                      <<std::endl);       
1026     if (!c) 
1027       {
1028
1029         bbtkDebugMessage("connection",2,"c==0"<<std::endl);     
1030         return;
1031       }
1032
1033     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
1034     if (i==bbGetOutputConnectorMap().end())
1035       {
1036         bbtkError("no output called '"<<name<<"'");
1037       }
1038     i->second->UnsetConnection(c);
1039
1040     bbtkDebugMessage("connection",2,
1041                      "<== BlackBox::bbDisconnectOutput(\""<<name
1042                      <<"\","<<c->GetFullName()<<") ["
1043                      <<bbGetFullName()<<"]"
1044                      <<std::endl);       
1045   } 
1046   //=========================================================================
1047  
1048
1049   //=========================================================================
1050   /// Virtual
1051   void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
1052   {
1053     fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
1054   }
1055   //=========================================================================
1056
1057
1058   //=========================================================================
1059   std::string BlackBox::bbGetOutputAsString( const std::string &output ) 
1060   {
1061     std::string v;
1062     // Looks for the adaptor
1063     if (bbGetOutputType(output).name() != typeid(std::string).name() ) 
1064       {
1065         // Look for factory 
1066         Package::Pointer p = bbGetDescriptor()->GetPackage();
1067         if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1068           {
1069             Factory::Pointer f = p->GetFactorySet().begin()->lock();
1070             BlackBox::Pointer a;
1071             try
1072               {
1073                 a = f->NewAdaptor(  
1074                                   bbGetOutputType(output),
1075                                   typeid(std::string),
1076                                   "");
1077               } catch (bbtk::Exception e) 
1078               {
1079               }
1080             if (a){
1081               //                        bbUpdate();
1082               a->bbSetInput("In",bbGetOutput(output));
1083               a->bbExecute();
1084               v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1085             } else {
1086               v="? (no adaptor found)";
1087             }
1088           }
1089         else 
1090           {
1091             v="? (no factory found)";
1092           }
1093       } 
1094     else 
1095       {
1096         //         bbUpdate();
1097         v = bbGetOutput(output).unsafe_get<std::string>() ;
1098       }
1099     return v;
1100   }
1101   //=========================================================================
1102
1103   //=========================================================================
1104   std::string BlackBox::bbGetInputAsString( const std::string &input ) 
1105   {
1106     std::string v;
1107     // Looks for the adaptor
1108     if (bbGetInputType(input) != typeid(std::string)) 
1109       {
1110         // Look for factory 
1111         Package::Pointer p = bbGetDescriptor()->GetPackage();
1112         if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1113           {
1114             Factory::Pointer f = p->GetFactorySet().begin()->lock();
1115             BlackBox::Pointer a;
1116             try
1117               {
1118                 a = f->NewAdaptor(  
1119                                bbGetInputType(input),
1120                                typeid(std::string),
1121                                "");
1122               }catch (bbtk::Exception e) 
1123               {
1124               }
1125             if (a)
1126               {
1127                 //                      bbUpdate();
1128                 a->bbSetInput("In",bbGetInput(input));
1129                 a->bbExecute();
1130                 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1131               } 
1132             else 
1133               {
1134                 v="? (no adaptor found)";
1135               }
1136           } 
1137         else 
1138           {
1139             v="? (no factory found)";
1140           }
1141       }
1142     else 
1143       {
1144         v = bbGetInput(input).unsafe_get<std::string>() ;
1145       }
1146     return v;
1147   }
1148   //=======================================================================
1149
1150   //=======================================================================
1151   // Replaces substrings "<" by "["
1152   void SubsBrackets ( std::string& s )
1153   {
1154     //   std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1155     std::string ss("<");
1156     std::string::size_type pos = 0;
1157     pos = s.find(ss,0);
1158     std::string cr("[");
1159     while ( pos != std::string::npos )
1160       {
1161         //      std::cout << "*** find one "<<std::endl;
1162         s.replace(pos,1,cr.c_str(),1);
1163         pos = s.find(ss, pos);
1164       } 
1165     ss = ">";
1166     pos = 0;
1167     pos = s.find(ss,0);
1168     cr = "]";
1169     while ( pos != std::string::npos )
1170       {
1171         //      std::cout << "*** find one "<<std::endl;
1172         s.replace(pos,1,cr.c_str(),1);
1173         pos = s.find(ss, pos);
1174       } 
1175     ss = ",";
1176     pos = 0;
1177     pos = s.find(ss,0);
1178     cr = "-";
1179     while ( pos != std::string::npos )
1180       {
1181         //      std::cout << "*** find one "<<std::endl;
1182         s.replace(pos,1,cr.c_str(),1);
1183         pos = s.find(ss, pos);
1184       }     //    std::cout << "AFTER=["<<s<<"]"<<std::endl;
1185   }
1186   //=======================================================================
1187
1188   //=========================================================================
1189   /// Write Graphviz-dot description in file
1190   void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1191                                         BlackBox::Pointer parentblackbox, 
1192                                         int detail, int level,
1193                                         bool instanceOrtype,
1194                                         bool relative_link )
1195
1196   { 
1197     InputConnectorMapType::iterator i;
1198     // label
1199     std::string labelStr;
1200     std::string valueStr("");
1201
1202         if (detail==0) {
1203                 labelStr = bbGetName() ; 
1204 //EED 18 Fev 2008
1205                 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1206         } else {
1207                 labelStr = bbGetName();
1208                 labelStr = labelStr + "   [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]  ";
1209     }
1210
1211     SubsBrackets(labelStr);
1212     if (detail==1)
1213       {
1214         labelStr = labelStr + " | {{ "; 
1215         std::string tempStrTypeName;
1216         bool tmp; 
1217         tmp=false;
1218         for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
1219           {
1220             if (tmp==true)
1221               {
1222                 labelStr=labelStr+" | ";
1223               }
1224             tmp=true;
1225             if (instanceOrtype==true)
1226               {
1227                 valueStr = this->bbGetInputAsString(i->first) + " = ";
1228               } 
1229             const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1230             tempStrTypeName=id->GetTypeName();
1231             SubsBrackets(tempStrTypeName);
1232             std::string Name(i->first);
1233             SubsBrackets(Name);
1234             labelStr=labelStr + "<"+i->first.c_str()+"> "  + valueStr +  Name.c_str() + "  [" + tempStrTypeName.c_str() + "]";
1235           }
1236         labelStr=labelStr+ " } | {";
1237         tmp = false;
1238         OutputConnectorMapType::iterator ii;
1239         for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii ) 
1240         {
1241            if (tmp==true)
1242            {
1243                    labelStr=labelStr+" | ";
1244            }
1245            tmp = true;
1246            if (instanceOrtype==true)
1247            {
1248                    valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1249            }
1250            const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first); 
1251            tempStrTypeName=id->GetTypeName();
1252            SubsBrackets(tempStrTypeName);
1253             std::string Name(ii->first);
1254             SubsBrackets(Name);
1255            labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + "  ["+tempStrTypeName+"]";
1256         }
1257         labelStr = labelStr+ "      } }" ;
1258 } // detail
1259
1260     fprintf(ff,"  " );
1261     bbWriteDotInputOutputName(ff,true,detail,level);
1262     std::string tmp ( bbGetTypeName() );
1263     SubsBrackets(tmp);
1264     std::string url;
1265     if (relative_link) 
1266       url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1267     else 
1268       url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1269   
1270     fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1271     //    std::cout  << labelStr << std::endl;
1272
1273     // Relation Input
1274     if (GetThisPointer<BlackBox>()!=parentblackbox){
1275       for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
1276         {
1277           if (i->second)
1278             {
1279               Connection* con = i->second->GetConnection();
1280               if (con!=NULL){
1281                 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1282                 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1283                 fprintf(ff,"  ");
1284                 a->bbWriteDotInputOutputName(ff,false,detail,level);
1285                 if (detail==1)
1286                   {
1287                     fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1288                   }
1289                 fprintf(ff,"->");
1290                 b->bbWriteDotInputOutputName(ff,true,detail,level);
1291                 if (detail==1)
1292                   {
1293                     fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1294                   }
1295                 fprintf(ff,"%s\n",";");
1296               }  // if con
1297             } // if second
1298         } // for
1299     } // if parentblackbox
1300   }
1301   //=========================================================================
1302
1303
1304
1305
1306   //=========================================================================
1307   void BlackBox::bbShowRelations(BlackBox::Pointer parentblackbox, 
1308                                  int detail, int level
1309                                  /*,Factory *factory*/ )
1310   {
1311      
1312     if (this->bbGetDescriptor()->GetPackage()) 
1313       {
1314         bbtkMessage("Help",1,"Black Box '"<<bbGetName()<<"' <"<<
1315                     this->bbGetDescriptor()->GetPackage()->GetName()
1316                     <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1317       }
1318     else 
1319       {
1320         bbtkMessage("Help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1321       }
1322     /*
1323     if (bbIsUpToDate())
1324       {
1325         bbtkMessage("Help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1326                     <<mMinOutputChangeTime<<"]"<<std::endl);
1327       }
1328     else 
1329       {
1330         bbtkMessage("Help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1331                     <<mMinOutputChangeTime<<"]"<<std::endl);
1332       }
1333     */
1334     //    bbtkMessage("Help",1," "<<GetDescription()<<std::endl);
1335     //    bbtkMessage("Help",1," By : "<<GetAuthor()<<std::endl);
1336
1337     std::vector<std::string> iname;
1338     std::vector<std::string> ivalue;
1339     std::vector<std::string> iconn;
1340     std::vector<std::string> istatus;
1341
1342     InputConnectorMapType::iterator i;
1343     unsigned int namelmax = 0;
1344     unsigned int valuelmax = 0;
1345     //   unsigned int connlmax = 0;
1346     for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
1347       {
1348         iname.push_back(i->first);
1349         if (iname.back().size()>namelmax) namelmax = iname.back().size();
1350         ivalue.push_back(bbGetInputAsString(i->first));
1351         if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1352         std::string s("");
1353         Connection* con = i->second->GetConnection();
1354         if (con!=0){
1355           s = con->GetOriginalBlackBoxFrom()->bbGetName();
1356           s += ".";
1357           s += con->GetOriginalBlackBoxFromOutput();
1358         }  // if con
1359         iconn.push_back(s);
1360         istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1361       }
1362     OutputConnectorMapType::iterator o;
1363     std::vector<std::string> oname;
1364     std::vector<std::string> ovalue;
1365     std::vector<std::vector<std::string> > oconn;
1366     std::vector<std::string> ostatus;
1367     for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o ) 
1368       {
1369         oname.push_back(o->first);
1370         if (oname.back().size()>namelmax) namelmax = oname.back().size();
1371         ovalue.push_back(bbGetOutputAsString(o->first));
1372         if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size();
1373         std::vector<std::string> ss;
1374         const std::vector<Connection*>& con 
1375           = o->second->GetConnectionVector();
1376         std::vector<Connection*>::const_iterator c;
1377         for (c=con.begin();c!=con.end();++c) 
1378           {
1379             std::string s;
1380             s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1381             s += ".";
1382             s += (*c)->GetOriginalBlackBoxToInput();
1383             ss.push_back(s);
1384         }  // if con
1385         oconn.push_back(ss);
1386         ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1387       }
1388
1389     if (iname.size()) 
1390       bbtkMessage("Help",1," * Inputs : "<<std::endl);
1391     else 
1392       bbtkMessage("Help",1," * No inputs"<<std::endl);
1393
1394     std::vector<std::string>::iterator i1,i2,i3,i4;
1395     for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1396          i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1397          ++i1,++i2,++i3,++i4)
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 (i3->size()) 
1406           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<" <-- '"
1407                       <<*i3<<"'");
1408         else 
1409           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value);
1410         bbtkMessage("Help",1," ["<<*i4<<"]"<<std::endl);
1411       }
1412
1413     if (oname.size()) 
1414       bbtkMessage("Help",1," * Outputs : "<<std::endl);
1415     else 
1416       bbtkMessage("Help",1," * No outputs"<<std::endl);
1417
1418     std::vector<std::vector<std::string> >::iterator i5;
1419
1420     for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1421          i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1422          ++i1,++i2,++i4,++i5)
1423       {
1424         std::string name(*i1);
1425         name += "'";
1426         name.append(1+namelmax-name.size(),' ');
1427         std::string value(*i2);
1428         value += "'";
1429         value.append(1+valuelmax-value.size(),' ');
1430         if (!(*i5).size())
1431           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value);
1432         else 
1433           {
1434             std::string pref = "    '"+name+" = '"+value;
1435             for (i3=i5->begin();i3!=i5->end();++i3)
1436               {
1437                 bbtkMessage("Help",1,pref<<" --> '"<<*i3<<"'");
1438                 pref.replace(0,pref.size(),pref.size(),' ');
1439               }
1440           }
1441         bbtkMessage("Help",1," ["<<*i4<<"]"<<std::endl);
1442       }
1443
1444    }
1445   //=========================================================================
1446
1447   static bool bbmgGlobalProcessingExecutionList = false;
1448
1449   //=========================================================================
1450    void BlackBox::bbGlobalProcessExecutionList()
1451    {   
1452      bbtkDebugMessageInc("process",3,
1453                          "=> BlackBox::bbGlobalProcessExecutionList()"
1454                          <<std::endl);    
1455      if (bbmgGlobalProcessingExecutionList) 
1456        {
1457          bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1458          return;
1459        }
1460      bbmgGlobalProcessingExecutionList = true;
1461
1462      std::set<BlackBox::WeakPointer>::iterator i; 
1463      while (bbmgExecutionList.size()>0)
1464        {
1465          i = bbmgExecutionList.begin();
1466          BlackBox::WeakPointer p = *i;
1467          bbmgExecutionList.erase(i);
1468          if (p.lock())
1469            {
1470              bbtkDebugMessage("process",4,
1471                               " -> Executing "<<
1472                               p.lock()->bbGetFullName()<<std::endl);
1473              p.lock()->bbExecute(true);
1474            }
1475          else 
1476            {
1477              bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1478            }
1479        }
1480      
1481      bbmgExecutionList.clear();
1482      bbtkDebugMessageDec("process",3,
1483                          "<= BlackBox::bbGlobalProcessExecutionList()"
1484                          <<std::endl);     
1485      
1486      bbmgGlobalProcessingExecutionList = false;
1487      
1488    }
1489   //=========================================================================
1490
1491     bool BlackBox::bbGlobalGetSomeBoxExecuting()
1492         { 
1493                 return bbmgSomeBoxExecuting; 
1494         }
1495
1496     void BlackBox::bbGlobalSetSomeBoxExecuting(bool b) 
1497         { 
1498                 bbmgSomeBoxExecuting = b; 
1499         }
1500
1501     void BlackBox::bbGlobalSetFreezeExecution(bool b) 
1502         { 
1503                 bbmgFreezeExecution = b;
1504         }
1505
1506     bool BlackBox::bbGlobalGetFreezeExecution() 
1507         { 
1508                 return bbmgFreezeExecution; 
1509         }
1510
1511   void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1512   {  
1513     bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetFullName()<<")"<<std::endl);
1514     if (bbmgGlobalProcessingExecutionList) 
1515       {
1516         bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1517       }
1518     bbmgExecutionList.insert(b); 
1519   } 
1520
1521
1522    //=========================================================================
1523
1524   //=========================================================================
1525   void BlackBox::Check(bool recursive)
1526   {
1527     bbtkMessage("debug",1,"*** Checking Black Box "<<(void*)this<<" ["<<bbGetFullName()
1528                 <<"] ... OK"<<std::endl);
1529   }
1530   //=========================================================================
1531
1532   void BlackBox::bbUserOnShowWidget(std::string nameInput)
1533   {
1534           bbtk::BlackBoxInputConnector *cc;
1535           cc = this->bbGetInputConnectorMap().find( nameInput.c_str() )->second;
1536           if (cc->GetConnection()!=NULL) 
1537           {
1538                   cc->GetConnection()->GetBlackBoxFrom()->bbUserOnShow();
1539           }
1540   }
1541
1542
1543
1544 }  // EO namespace bbtk
1545
1546 // EOF
1547