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