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