]> Creatis software - bbtk.git/blob - kernel/src/bbtkBlackBox.cxx
#2696 BBTK Bug New Normal - BoxChange BoxExecute not responding at the second actio...
[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
467     OutputConnectorMapType::const_iterator o;   
468     for ( o = bbGetOutputConnectorMap().begin(); 
469           o != bbGetOutputConnectorMap().end(); ++o )                   
470       {
471
472
473         if (o->first=="BoxChange")
474         {
475                 o->second->SetStatus(UPTODATE);
476         }
477
478
479
480 //EED 24/08/2015
481 // EED CASPITAS 2
482         if (o->second->GetStatus()==UPTODATE)
483 //      if ((o->second->GetStatus()==UPTODATE) || (o->second->GetStatus()==OUTOFDATE))
484 //      if ((o->second->GetStatus()==UPTODATE) || (o->second->GetStatus()==MODIFIED))
485           {
486             o->second->SetStatus(OUTOFDATE);
487             o->second->SignalChange(GetThisPointer<BlackBox>(),o->first); 
488           } // if
489         } // for                                                        
490     
491
492     if (  ( bbBoxProcessModeIsReactive()
493            || (c==bbGetInputConnectorMap().find("BoxExecute")->second))
494            && (bbCanReact() ) )
495       {
496         bbtkBlackBoxDebugMessage("change",2,
497                          "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
498         bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
499       } // if
500     bbtkBlackBoxDebugMessage("change",5,
501                              "<= BlackBox::bbSetStatusAndPropagate(input)"
502                              <<std::endl);
503   }
504   //=========================================================================
505
506
507   //=========================================================================  
508   void BlackBox::bbSignalOutputModification(bool reaction)
509   {
510     bbtkBlackBoxDebugMessage("change",5,
511                              "=> BlackBox::bbSignalOutputModification("
512                              <<reaction<<")"
513                              <<"]"<<std::endl);
514
515     OutputConnectorMapType::iterator i;
516     for ( i  = bbGetOutputConnectorMap().begin(); 
517           i != bbGetOutputConnectorMap().end(); ++i) 
518       {
519         //      std::cout << "Stat = "
520         //<<GetIOStatusString(i->second->GetStatus())
521         //                <<std::endl;
522         // LG : CANNOT SIGNAL ONLY WHEN UPTODATE 
523         // See bbtkSampleOutputObserver
524         //      if (i->second->GetStatus()==UPTODATE) 
525         //        {
526             i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
527             //    }
528       } // for
529
530     if (reaction) bbGlobalProcessExecutionList();
531
532     bbtkBlackBoxDebugMessage("change",5,
533                              "<= BlackBox::bbSignalOutputModification()"
534                              <<std::endl);
535   }  
536   //=========================================================================   
537
538
539   //=========================================================================  
540   void BlackBox::bbSignalOutputModification(const std::string& output,
541                                             bool reaction)
542   {
543     bbtkBlackBoxDebugMessage("change",5,
544                              "=> BlackBox::bbSignalOutputModification("
545                              <<output<<","<<reaction<<")"
546                              <<std::endl);
547     
548     OutputConnectorMapType::iterator i = 
549       bbGetOutputConnectorMap().find(output);
550
551
552     if ( i == bbGetOutputConnectorMap().end() ) 
553         {
554           bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
555         }
556
557     //    if (i->second->GetStatus()==UPTODATE) 
558     //      {
559         i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
560         // Has to notify the output "BoxChange" also
561         if (output != "BoxChange") 
562           {
563             i = bbGetOutputConnectorMap().find("BoxChange");
564             if ( i != bbGetOutputConnectorMap().end() ) 
565               {
566                 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
567               }
568           }
569         if (reaction) bbGlobalProcessExecutionList();
570         //      }
571
572         bbtkBlackBoxDebugMessage("change",5,
573                              "<= BlackBox::bbSignalOutputModification("
574                              <<output<<")"
575                              <<std::endl);
576   }  
577   //=========================================================================   
578   //=========================================================================  
579   void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
580         bool reaction)
581   {
582     bbtkBlackBoxDebugMessage("change",5,
583                         "=> BlackBox::bbSignalOutputModification(vector of outputs)"
584 <<std::endl);
585     OutputConnectorMapType::iterator i;
586     std::vector<std::string>::const_iterator o;
587     bool changed = false;
588     for (o=output.begin();o!=output.end();++o) 
589       {
590         // the output "BoxChange" must be signaled **AFTER** all others
591         if (*o == "BoxChange") continue;
592         // Look for the connector
593         i = bbGetOutputConnectorMap().find(*o);
594         if ( i == bbGetOutputConnectorMap().end() ) 
595           {
596             bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
597           }
598
599         //      if (i->second->GetStatus()==UPTODATE)
600         //        {
601             i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
602             changed = true;
603             //  }
604       }
605     // Has to notify the output "BoxChange" also
606     i = bbGetOutputConnectorMap().find("BoxChange");
607     if ( changed && (i != bbGetOutputConnectorMap().end())) 
608       {
609         // if (i->second->GetStatus()==UPTODATE) 
610         //        {
611             i->second->SignalChange(GetThisPointer<BlackBox>(),i->first); 
612             if (reaction) bbGlobalProcessExecutionList();
613             //  }
614       }
615
616     bbtkBlackBoxDebugMessage("change",5,
617                              "<= BlackBox::bbSignalOutputModification(vector of outputs)"
618                              <<std::endl);
619   }  
620   //=========================================================================   
621
622
623
624
625
626
627
628   //=========================================================================
629   /// Main processing method of the box.
630   void BlackBox::bbExecute(bool force)
631   {
632     bbtkBlackBoxDebugMessage("process",2,
633                              "=> BlackBox::bbExecute("<<(int)force<<")"
634                              <<std::endl);
635  
636     // If already executing : return
637     /*
638     if (bbGetExecuting()) 
639       {
640         bbtkBlackBoxDebugMessage("process",2,
641                          " -> already executing : abort"<<std::endl);
642         return;
643       }
644     */
645
646     // If execution frozen : return
647     if (bbGlobalGetFreezeExecution()) 
648       {
649         bbtkBlackBoxDebugMessage("process",2,
650                          " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
651       }
652
653     BBTK_BUSY_CURSOR;
654
655     // If force is true then update is triggered even if the box is UPTODATE
656     //    if (force) bbSetModifiedStatus();
657
658         if ( bbBoxProcessModeIsManual() ) 
659         {
660                 bbLetRecursiveExecuteManualMode = true;
661     }
662           
663           
664     // Calls the main recursive execution method 
665     bbRecursiveExecute(Connection::Pointer());
666
667           
668         if ( bbBoxProcessModeIsManual() ) 
669         {
670                 bbLetRecursiveExecuteManualMode = false;
671         }
672           
673           
674     bbtkBlackBoxDebugMessage("process",2,
675                              "<= BlackBox::bbExecute()"
676                              <<std::endl);
677   }
678   //=========================================================================
679
680   //=========================================================================
681   void BlackBox::bbInitializeProcessing()
682   {
683     if (!bbmInitialized) 
684       {
685         bbtkBlackBoxDebugMessage("process",2,"** Initialize processing"
686                                  <<std::endl);
687         this->bbRecursiveInitializeProcessing();
688         bbmInitialized = true;
689       }
690   }
691   //=========================================================================
692
693   //=========================================================================
694   void BlackBox::bbFinalizeProcessing()
695   {
696     if (bbmInitialized) 
697       {
698         bbtkBlackBoxDebugMessage("process",2,"** Finalize processing"
699                                  <<std::endl);
700         this->bbRecursiveFinalizeProcessing();
701         bbmInitialized = false;
702       }
703   }
704   //=========================================================================
705
706   
707   //=========================================================================
708   void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
709   {
710
711     bbtkBlackBoxDebugMessage("process",3,
712                         "=> BlackBox::bbRecursiveExecute("
713                         <<(caller?caller->GetFullName():"0")<<")"
714                         <<std::endl);
715
716     // If already executing : return
717     if (bbGetExecuting()) 
718       {
719         bbtkBlackBoxDebugMessage("process",3,
720                          " -> already executing : abort"<<std::endl);
721         return; 
722       }
723     
724     // If not initialized do it
725     bbInitializeProcessing();
726
727     bbSetExecuting(true);
728     bool wasExecuting = bbGlobalGetSomeBoxExecuting();
729     bbGlobalSetSomeBoxExecuting(true);
730     
731     // Creates the window if the black box has one
732     this->bbCreateWindow();
733     
734     // Updates its inputs
735           
736 //        IOStatus s;
737           IOStatus s=UPTODATE;
738 //        IOStatus s=OUTOFDATE;
739 //        IOStatus s=MODIFIED;
740                   
741
742           if ( ( bbBoxProcessModeIsManual()==false )  || 
743                    ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) ) )
744           {
745                   s = bbUpdateInputs();
746           }       
747                   
748     if ( (s != UPTODATE) ||  bbBoxProcessModeIsAlways() )
749       {
750           // Displays the window (WxBlackbox)
751           //    bbShowWindow(caller);
752
753           // Actual processing (virtual)
754                   if ( ( bbBoxProcessModeIsManual()==false )  || 
755                            ( (bbBoxProcessModeIsManual()==true)&&(bbLetRecursiveExecuteManualMode==true) ) 
756                          )
757                         {
758                                 this->bbProcess();              
759                     } // Manual analysis
760                   
761 //EED ups                       if ((bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false))
762 //EED ups                       {
763 //EED ups                         bbSignalOutputModification(true);
764 //EED ups                       }
765                   
766                   
767                   // Update the I/O statuses
768                   bbComputePostProcessStatus();
769       }
770     else 
771       {
772         // Test output status...
773         OutputConnectorMapType::iterator o;
774         for ( o = bbGetOutputConnectorMap().begin(); 
775               o!= bbGetOutputConnectorMap().end(); ++o) 
776           {
777             if (o->second->GetStatus() != UPTODATE)
778               {
779                 bbtkWarning("BlackBox::bbRecursiveExecute: "
780                             <<"all inputs are Up-to-date but output '"
781                             <<o->first<<"' is Out-of-date ???");
782               }
783           }
784         
785         bbtkBlackBoxDebugMessage("process",3," -> Up-to-date : nothing to do"
786                          <<std::endl);
787       }
788
789     // Shows the window if the black box has one
790     this->bbShowWindow(); 
791
792           
793     bbtkBlackBoxDebugMessage("process",3,
794             "<= BlackBox::bbRecursiveExecute()"
795             <<std::endl);
796
797     bbSetExecuting(false);
798     bbGlobalSetSomeBoxExecuting(wasExecuting);
799
800
801     return;
802   }
803   //=========================================================================
804   
805    
806
807
808
809   //=========================================================================
810   IOStatus BlackBox::bbUpdateInputs()
811   {
812     bbtkBlackBoxDebugMessage("process",4,
813                         "=> BlackBox::bbUpdateInputs()"
814                         <<std::endl);   
815
816     IOStatus s = UPTODATE;
817
818     InputConnectorMapType::iterator i;
819     for ( i = bbGetInputConnectorMap().begin(); 
820           i!= bbGetInputConnectorMap().end(); ++i) 
821       {
822         //      if (i->first=="WinHide") continue;
823         // If input type is Void : no recurse
824         //if (  bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo() 
825         //      == typeid(Void) ) 
826         //  continue;
827         bbtkBlackBoxDebugMessage("change",2,
828                             "Input '"<<i->first
829                             <<"': status before update = '"
830                             <<GetIOStatusString(i->second->GetStatus())
831                             <<"'"<<std::endl);
832         i->second->RecursiveExecute();
833         IOStatus t = i->second->GetStatus();
834         if (t > s) s = t;
835         bbtkBlackBoxDebugMessage("change",2,
836                                  "Input '"<<i->first
837                                  <<"': status before process = '"
838                                  <<GetIOStatusString(i->second->GetStatus())
839                                  <<"'"<<std::endl);
840       }
841     
842     bbtkBlackBoxDebugMessage("process",4,
843                         "<= BlackBox::bbUpdateInputs()"
844                         <<std::endl);
845     return s;
846   }
847   //=========================================================================
848
849   //==================================================================
850    void BlackBox::bbComputePostProcessStatus()
851   {
852     bbtkBlackBoxDebugMessage("process",4,
853                         "=> BlackBox::bbComputePostProcessStatus()"
854                         <<std::endl);   
855
856     IOStatus new_output_status = UPTODATE;
857     if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
858
859     // Update the input statuses
860     InputConnectorMapType::iterator i;
861     for ( i = bbGetInputConnectorMap().begin(); 
862           i!= bbGetInputConnectorMap().end(); ++i) 
863       {
864         IOStatus t = i->second->GetStatus();
865         if (t == OUTOFDATE) new_output_status = OUTOFDATE;
866         // A previously MODIFIED status turns to UPTODATE
867         if (t==MODIFIED) i->second->SetStatus(UPTODATE);
868         bbtkBlackBoxDebugMessage("change",2,
869                          "Input '"<<i->first<<"' : "
870                          << GetIOStatusString(t) << " -> "
871                          << GetIOStatusString(i->second->GetStatus())
872                          << std::endl);
873       }
874     bbtkBlackBoxDebugMessage("change",2,
875                              "New output status : "
876                              << GetIOStatusString(new_output_status)
877                              <<std::endl);
878     // Update the output statuses
879     OutputConnectorMapType::iterator o;
880     for ( o = bbGetOutputConnectorMap().begin(); 
881           o!= bbGetOutputConnectorMap().end(); ++o) 
882       {
883                 
884 //EED             if  ( ( bbBoxProcessModeIsManual()==false )  || 
885 //EED                       ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) ) 
886 //EED                     )
887 //EED             {
888                           o->second->SetStatus(new_output_status);
889 //EED             }  else  {
890 //EED                     if  (( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false) )  ) 
891 //EED                     {
892 //EED                             o->second->SetStatus(UPTODATE);
893 //EED                     }
894 //EED             } // Manual analysis
895                           
896       }
897
898     bbtkBlackBoxDebugMessage("process",4,
899                         "<= BlackBox::bbComputePostProcessStatus()"
900                         <<std::endl);
901   }
902   //==================================================================
903
904   //=========================================================================
905   void BlackBox::bbConnectInput( const std::string& name, Connection* c)
906   {
907     bbtkBlackBoxDebugMessage("connection",2,
908                         "==> BlackBox::bbConnectInput(\""
909                         <<name<<"\","<<c->GetFullName()<<")"
910                         <<std::endl);       
911
912     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
913     if (i==bbGetInputConnectorMap().end())
914       {
915         bbtkError("no input called '"<<name<<"'");
916       }
917     i->second->SetConnection(c);
918     // The input *MUST* be set OUTOFDATE to update its input on next execution
919     bbSetStatusAndPropagate(i->second,OUTOFDATE);
920
921     bbtkBlackBoxDebugMessage("connection",2,
922                         "<== BlackBox::bbConnectInput(\""
923                         <<name<<"\","<<c->GetFullName()<<")"
924                         <<std::endl);
925   }
926   //=========================================================================
927
928
929   //=========================================================================  
930   void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
931   {
932     bbtkBlackBoxDebugMessage("connection",2,
933                              "==> BlackBox::bbConnectOutput(\""<<name<<"\","
934                              <<c->GetFullName()<<")"
935                              <<std::endl);       
936
937     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
938     if (i==bbGetOutputConnectorMap().end())
939       {
940         bbtkError("no output called '"<<name<<"'");
941       }
942     i->second->SetConnection(c);
943
944     bbtkBlackBoxDebugMessage("connection",2,
945                              "<== BlackBox::bbConnectOutput(\""<<name<<"\","
946                              <<c->GetFullName()<<")"
947                              <<std::endl);
948   }
949   //=========================================================================
950
951
952   //=========================================================================
953    void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
954   {
955
956     bbtkBlackBoxDebugMessage("connection",2,
957                      "==> BlackBox::bbDisconnectInput(\""<<name
958                      <<"\","<<c->GetFullName()<<")"
959                      <<std::endl);
960     if (!c) 
961       {
962
963         bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);     
964         return;
965       }
966
967     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
968     if (i==bbGetInputConnectorMap().end())
969       {
970         bbtkError("no input called '"<<name<<"'");
971       }
972     i->second->UnsetConnection(c);
973
974     bbtkBlackBoxDebugMessage("connection",2,
975                      "<== BlackBox::bbDisconnectInput(\""<<name
976                      <<"\","<<c->GetFullName()<<")"
977                      <<std::endl);      
978
979   }
980   //=========================================================================
981
982
983   //=========================================================================
984    void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
985   {
986     bbtkBlackBoxDebugMessage("connection",2,
987                      "==> BlackBox::bbDisconnectOutput(\""<<name
988                      <<"\","<<c->GetFullName()<<")"
989                      <<std::endl);       
990     if (!c) 
991       {
992
993         bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);     
994         return;
995       }
996
997     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
998     if (i==bbGetOutputConnectorMap().end())
999       {
1000         bbtkError("no output called '"<<name<<"'");
1001       }
1002     i->second->UnsetConnection(c);
1003
1004     bbtkBlackBoxDebugMessage("connection",2,
1005                      "<== BlackBox::bbDisconnectOutput(\""<<name
1006                      <<"\","<<c->GetFullName()<<")"
1007                      <<std::endl);       
1008   } 
1009   //=========================================================================
1010  
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033   //=========================================================================
1034   void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
1035   {
1036     fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
1037   }
1038   //=========================================================================
1039
1040
1041   //=========================================================================
1042   std::string BlackBox::bbGetOutputAsString( const std::string &output ) 
1043   {
1044     std::string v;
1045     // Looks for the adaptor
1046     if (bbGetOutputType(output).name() != typeid(std::string).name() ) 
1047       {
1048         // Look for factory 
1049         Package::Pointer p = bbGetDescriptor()->GetPackage();
1050         if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1051           {
1052             Factory::Pointer f = p->GetFactorySet().begin()->lock();
1053             BlackBox::Pointer a;
1054             try
1055               {
1056                 a = f->NewAdaptor(  
1057                                   bbGetOutputType(output),
1058                                   typeid(std::string),
1059                                   "");
1060               } catch (bbtk::Exception e) 
1061               {
1062               }
1063             if (a){
1064               //                        bbUpdate();
1065               a->bbSetInput("In",bbGetOutput(output));
1066               a->bbExecute();
1067               v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1068             } else {
1069               v="? (no adaptor found)";
1070             }
1071           }
1072         else 
1073           {
1074             v="? (no factory found)";
1075           }
1076       } 
1077     else 
1078       {
1079         //         bbUpdate();
1080         v = bbGetOutput(output).unsafe_get<std::string>() ;
1081       }
1082     return v;
1083   }
1084   //=========================================================================
1085
1086   //=========================================================================
1087   std::string BlackBox::bbGetInputAsString( const std::string &input ) 
1088   {
1089     std::string v;
1090     // Looks for the adaptor
1091     if (bbGetInputType(input) != typeid(std::string)) 
1092       {
1093         // Look for factory 
1094         Package::Pointer p = bbGetDescriptor()->GetPackage();
1095         if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1096           {
1097             Factory::Pointer f = p->GetFactorySet().begin()->lock();
1098             BlackBox::Pointer a;
1099             try
1100               {
1101                 a = f->NewAdaptor(  
1102                                bbGetInputType(input),
1103                                typeid(std::string),
1104                                "");
1105               }catch (bbtk::Exception e) 
1106               {
1107               }
1108             if (a)
1109               {
1110                 //                      bbUpdate();
1111                 a->bbSetInput("In",bbGetInput(input));
1112                 a->bbExecute();
1113                 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1114               } 
1115             else 
1116               {
1117                 v="? (no adaptor found)";
1118               }
1119           } 
1120         else 
1121           {
1122             v="? (no factory found)";
1123           }
1124       }
1125     else 
1126       {
1127         v = bbGetInput(input).unsafe_get<std::string>() ;
1128       }
1129     return v;
1130   }
1131   //=======================================================================
1132
1133   //=======================================================================
1134   // Replaces substrings "<" by "["
1135   void SubsBrackets ( std::string& s )
1136   {
1137     //   std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1138     std::string ss("<");
1139     std::string::size_type pos = 0;
1140     pos = s.find(ss,0);
1141     std::string cr("[");
1142     while ( pos != std::string::npos )
1143       {
1144         //      std::cout << "*** find one "<<std::endl;
1145         s.replace(pos,1,cr.c_str(),1);
1146         pos = s.find(ss, pos);
1147       } 
1148     ss = ">";
1149     pos = 0;
1150     pos = s.find(ss,0);
1151     cr = "]";
1152     while ( pos != std::string::npos )
1153       {
1154         //      std::cout << "*** find one "<<std::endl;
1155         s.replace(pos,1,cr.c_str(),1);
1156         pos = s.find(ss, pos);
1157       } 
1158     ss = ",";
1159     pos = 0;
1160     pos = s.find(ss,0);
1161     cr = "-";
1162     while ( pos != std::string::npos )
1163       {
1164         //      std::cout << "*** find one "<<std::endl;
1165         s.replace(pos,1,cr.c_str(),1);
1166         pos = s.find(ss, pos);
1167       }     //    std::cout << "AFTER=["<<s<<"]"<<std::endl;
1168   }
1169   //=======================================================================
1170
1171   //=========================================================================
1172   /// Write Graphviz-dot description in file
1173   void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1174                                         BlackBox::Pointer parentblackbox, 
1175                                         int detail, int level,
1176                                         bool instanceOrtype,
1177                                         bool relative_link )
1178
1179   { 
1180     InputConnectorMapType::iterator i;
1181     // label
1182     std::string labelStr;
1183     std::string valueStr("");
1184
1185         if (detail==0) {
1186                 labelStr = bbGetName() ; 
1187 //EED 18 Fev 2008
1188                 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1189         } else {
1190                 labelStr = bbGetName();
1191                 labelStr = labelStr + "   [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]  ";
1192     }
1193
1194     SubsBrackets(labelStr);
1195     if (detail==1)
1196       {
1197         labelStr = labelStr + " | {{ "; 
1198         std::string tempStrTypeName;
1199         bool tmp; 
1200         tmp=false;
1201         for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
1202           {
1203             if (tmp==true)
1204               {
1205                 labelStr=labelStr+" | ";
1206               }
1207             tmp=true;
1208             if (instanceOrtype==true)
1209               {
1210                 valueStr = this->bbGetInputAsString(i->first) + " = ";
1211               } 
1212             const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1213             tempStrTypeName=id->GetTypeName();
1214             SubsBrackets(tempStrTypeName);
1215             std::string Name(i->first);
1216             SubsBrackets(Name);
1217             labelStr=labelStr + "<"+i->first.c_str()+"> "  + valueStr +  Name.c_str() + "  [" + tempStrTypeName.c_str() + "]";
1218           }
1219         labelStr=labelStr+ " } | {";
1220         tmp = false;
1221         OutputConnectorMapType::iterator ii;
1222         for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii ) 
1223         {
1224            if (tmp==true)
1225            {
1226                    labelStr=labelStr+" | ";
1227            }
1228            tmp = true;
1229            if (instanceOrtype==true)
1230            {
1231                    valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1232            }
1233            const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first); 
1234            tempStrTypeName=id->GetTypeName();
1235            SubsBrackets(tempStrTypeName);
1236            std::string Name(ii->first);
1237            SubsBrackets(Name);
1238            labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + "  ["+tempStrTypeName+"]";
1239         }
1240         labelStr = labelStr+ "      } }" ;
1241 } // detail
1242
1243     fprintf(ff,"  " );
1244     bbWriteDotInputOutputName(ff,true,detail,level);
1245     std::string tmp ( bbGetTypeName() );
1246     SubsBrackets(tmp);
1247     std::string url;
1248     if (relative_link) 
1249       url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1250     else 
1251       url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1252   
1253     fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1254     //    std::cout  << labelStr << std::endl;
1255
1256     // Relation Input
1257     if (GetThisPointer<BlackBox>()!=parentblackbox){
1258       for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
1259         {
1260           if (i->second)
1261             {
1262               Connection* con = i->second->GetConnection();
1263               if (con!=NULL){
1264                 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1265                 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1266                 fprintf(ff,"  ");
1267                 a->bbWriteDotInputOutputName(ff,false,detail,level);
1268                 if (detail==1)
1269                   {
1270                     fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1271                   }
1272                 fprintf(ff,"->");
1273                 b->bbWriteDotInputOutputName(ff,true,detail,level);
1274                 if (detail==1)
1275                   {
1276                     fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1277                   }
1278                 fprintf(ff,"%s\n",";");
1279               }  // if con
1280             } // if second
1281         } // for
1282     } // if parentblackbox
1283   }
1284   //=========================================================================
1285
1286
1287
1288
1289   //=========================================================================
1290   void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox, 
1291                                  int detail, int level
1292                                  /*,Factory *factory*/ )
1293   {
1294      
1295     if (this->bbGetDescriptor()->GetPackage()) 
1296       {
1297              bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
1298                     this->bbGetDescriptor()->GetPackage()->GetName()
1299                     <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1300       }
1301     else 
1302       {
1303              bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1304       }
1305     /*
1306     if (bbIsUpToDate())
1307       {
1308              bbtkBlackBoxMessage("help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1309                     <<mMinOutputChangeTime<<"]"<<std::endl);
1310       }
1311     else 
1312       {
1313              bbtkBlackBoxMessage("help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1314                     <<mMinOutputChangeTime<<"]"<<std::endl);
1315       }
1316     */
1317     //    bbtkBlackBoxMessage("help",1," "<<GetDescription()<<std::endl);
1318     //    bbtkBlackBoxMessage("help",1," By : "<<GetAuthor()<<std::endl);
1319
1320     std::vector<std::string> iname;
1321     std::vector<std::string> ivalue;
1322     std::vector<std::string> iconn;
1323     std::vector<std::string> istatus;
1324
1325     InputConnectorMapType::iterator i;
1326     unsigned int namelmax = 0;
1327     unsigned int valuelmax = 0;
1328     //   unsigned int connlmax = 0;
1329     for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
1330     {
1331            iname.push_back(i->first);
1332            if (iname.back().size()>namelmax) namelmax = iname.back().size();
1333            ivalue.push_back(bbGetInputAsString(i->first));
1334            if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1335            std::string s("");
1336            Connection* con = i->second->GetConnection();
1337            if (con!=0){
1338               s = con->GetOriginalBlackBoxFrom()->bbGetName();
1339               s += ".";
1340               s += con->GetOriginalBlackBoxFromOutput();
1341            }  // if con
1342            iconn.push_back(s);
1343            istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1344     }
1345     OutputConnectorMapType::iterator o;
1346     std::vector<std::string> oname;
1347     std::vector<std::string> ovalue;
1348     std::vector<std::vector<std::string> > oconn;
1349     std::vector<std::string> ostatus;
1350     for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o ) 
1351     {
1352            oname.push_back(o->first);
1353            if (oname.back().size()>namelmax)
1354           namelmax = oname.back().size();
1355            ovalue.push_back(bbGetOutputAsString(o->first));
1356            if (ovalue.back().size()>valuelmax) 
1357           valuelmax = ovalue.back().size();
1358            std::vector<std::string> ss;
1359            const std::vector<Connection*>& con 
1360                                     = o->second->GetConnectionVector();
1361            std::vector<Connection*>::const_iterator c;
1362            for (c=con.begin();c!=con.end();++c) 
1363            {
1364                std::string s;
1365                s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1366                s += ".";
1367                s += (*c)->GetOriginalBlackBoxToInput();
1368                ss.push_back(s);
1369             }  // if con
1370             oconn.push_back(ss);
1371             ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1372     }
1373
1374     if (iname.size()) 
1375       bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
1376     else 
1377       bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
1378
1379     std::vector<std::string>::iterator i1,i2,i3,i4;
1380     for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1381              i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1382            ++i1,++i2,++i3,++i4)
1383      {
1384             std::string name(*i1);
1385             name += "'";
1386             name.append(1+namelmax-name.size(),' ');
1387             std::string value(*i2);
1388             value += "'";
1389             value.append(1+valuelmax-value.size(),' ');
1390             if (i3->size()) 
1391               bbtkBlackBoxMessage("help",1,"    '"<<name<<" = '"<<value<<" <-- '" <<*i3<<"'");
1392             else 
1393               bbtkBlackBoxMessage("help",1,"    '"<<name<<" = '"<<value);
1394             bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1395      }
1396
1397     if (oname.size()) 
1398        bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
1399     else 
1400        bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
1401
1402     std::vector<std::vector<std::string> >::iterator i5;
1403
1404     for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1405              i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1406            ++i1,++i2,++i4,++i5)
1407     {
1408             std::string name(*i1);
1409             name += "'";
1410             name.append(1+namelmax-name.size(),' ');
1411             std::string value(*i2);
1412             value += "'";
1413             value.append(1+valuelmax-value.size(),' ');
1414             if (!(*i5).size())
1415               bbtkBlackBoxMessage("help",1,"    '"<<name<<" = '"<<value);
1416             else 
1417             {
1418                std::string pref = "    '"+name+" = '"+value;
1419                for (i3=i5->begin();i3!=i5->end();++i3)
1420                {
1421                       bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
1422                       pref.replace(0,pref.size(),pref.size(),' ');
1423                }
1424             }
1425             bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1426     }
1427
1428    }
1429   //=========================================================================
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448   static bool bbmgGlobalProcessingExecutionList = false;
1449
1450   //=========================================================================
1451    void BlackBox::bbGlobalProcessExecutionList()
1452    {   
1453      bbtkDebugMessage("process",3,
1454                       "=> BlackBox::bbGlobalProcessExecutionList()"
1455                       <<std::endl);    
1456      if (bbmgGlobalProcessingExecutionList) 
1457        {
1458          bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1459          return;
1460        }
1461      bbmgGlobalProcessingExecutionList = true;
1462
1463      std::set<BlackBox::WeakPointer>::iterator i; 
1464      while (bbmgExecutionList.size()>0)
1465        {
1466          i = bbmgExecutionList.begin();
1467          BlackBox::WeakPointer p = *i;
1468          bbmgExecutionList.erase(i);
1469          if (p.lock())
1470            {
1471              bbtkDebugMessage("process",4,
1472                               " -> Executing '"<<
1473                               p.lock()->bbGetName()<<"'"<<std::endl);
1474              p.lock()->bbExecute(true);
1475            }
1476          else 
1477            {
1478              bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1479            }
1480        }
1481      
1482      bbmgExecutionList.clear();
1483      bbtkDebugMessage("process",3,
1484                          "<= BlackBox::bbGlobalProcessExecutionList()"
1485                          <<std::endl);     
1486      
1487      bbmgGlobalProcessingExecutionList = false;
1488
1489      
1490    }
1491   //=========================================================================
1492
1493     bool BlackBox::bbGlobalGetSomeBoxExecuting()
1494         { 
1495                 return bbmgSomeBoxExecuting; 
1496         }
1497
1498     void BlackBox::bbGlobalSetSomeBoxExecuting(bool b) 
1499         { 
1500                 bbmgSomeBoxExecuting = b; 
1501         }
1502
1503     void BlackBox::bbGlobalSetFreezeExecution(bool b) 
1504         { 
1505                 bbmgFreezeExecution = b;
1506         }
1507
1508     bool BlackBox::bbGlobalGetFreezeExecution() 
1509         { 
1510                 return bbmgFreezeExecution; 
1511         }
1512
1513   void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1514   {  
1515     bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
1516     if (bbmgGlobalProcessingExecutionList) 
1517       {
1518         bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1519       }
1520     bbmgExecutionList.insert(b); 
1521   } 
1522
1523
1524    //=========================================================================
1525
1526   //=========================================================================
1527   void BlackBox::Check(bool recursive)
1528   {
1529     bbtkBlackBoxMessage("debug",1,"*** Checking"
1530                         <<" ... OK"<<std::endl);
1531   }
1532   //=========================================================================
1533
1534
1535
1536
1537 }  // EO namespace bbtk
1538
1539 // EOF
1540