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