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