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