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