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