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