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