]> Creatis software - bbtk.git/blob - kernel/src/bbtkBlackBox.cxx
bb409a1be3297c99c44cd5d4cd698b27fe126a16
[bbtk.git] / kernel / src / bbtkBlackBox.cxx
1 /*=========================================================================
2                                                                                 
3 Program:   bbtk
4 Module:    $RCSfile: bbtkBlackBox.cxx,v $
5 Language:  C++
6 Date:      $Date: 2008/03/11 18:46:47 $
7 Version:   $Revision: 1.7 $
8                                                                                 
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See doc/license.txt or
11 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
12                                                                                 
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18
19
20 /**
21  *  \file 
22  *  \brief Class bbtk::BlackBox : abstract black-box interface. 
23  */
24 #include "bbtkBlackBox.h"
25 #include "bbtkPackage.h"
26 #include "bbtkMessageManager.h"
27 #include "bbtkFactory.h"
28
29 #include "bbtkConfigurationFile.h"
30 #include "bbtkWxBlackBox.h"
31
32 #include <fstream>
33 //#include <vector>
34
35
36 namespace bbtk
37 {
38
39 //EED
40   static bool bbmgSomeBoxExecuting = false;
41   static bool bbmgFreezeExecution = false;
42   static std::set<BlackBox*> bbmgExecutionList;
43
44
45   //=========================================================================
46   BlackBox::BlackBox(const std::string &name) 
47     : bbmName(name), bbmStatus(MODIFIED), 
48       bbmBoxProcessMode("Pipeline"),bbmParent(NULL)
49   {
50     bbtkDebugMessage("Kernel",7,"BlackBox::BlackBox(\""
51                      <<name<<"\")"<<std::endl);
52   }
53   //=========================================================================
54
55
56   //=========================================================================
57   BlackBox::BlackBox(BlackBox& from, const std::string &name) 
58     : bbmName(name), 
59       bbmStatus(from.bbmStatus), 
60       bbmBoxProcessMode(from.bbmBoxProcessMode),bbmParent(NULL)
61   {
62     bbtkDebugMessage("Kernel",7,"BlackBox::BlackBox("
63                      <<from.bbGetFullName()<<",\""
64                      <<name<<"\")"<<std::endl);
65   }
66   //=========================================================================
67
68
69   //=========================================================================
70   BlackBox::~BlackBox()
71   {
72     //    std::cout << "EED BlackBox::~BlackBox 01 [" << bbGetName()<<"]\n";
73     bbtkDebugMessageInc("Kernel",7,"BlackBox::~BlackBox()"<<std::endl);
74     this->bbDesallocateConnectors();
75     //printf("EED BlackBox::~BlackBox 02 \n");
76     bbtkDebugDecTab("Kernel",7);
77   }
78   //=========================================================================
79
80   //=========================================================================
81   /// Destruction method of a black box
82   void BlackBox::bbDelete()
83   {
84     bbtkDebugMessage("Kernel",5,"BlackBox::bbDelete() ["
85                      <<bbGetFullName()<<"]"<<std::endl);    
86     this->bbUserDelete();
87   }
88   //=========================================================================
89
90
91   //=========================================================================
92   /// Main processing method of the box.
93   void BlackBox::bbExecute(bool force)
94   {
95     bbtkDebugMessageInc("Process",1,
96                         "=> BlackBox::bbExecute() ["
97                         <<bbGetFullName()<<"]"<<std::endl);
98
99     Wx::BeginBusyCursor();
100
101     // If execution frozen : return
102     if (bbGlobalGetFreezeExecution()) 
103       {
104         bbtkDebugMessage("Process",1,
105                          " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
106       }
107
108     // If force is true then update is triggered even if the box is UPTODATE
109     if (force) bbSetModifiedStatus();
110
111     // Calls the main recursive update method 
112     bbBackwardUpdate(0);
113
114     Wx::EndBusyCursor();
115
116     bbtkDebugMessageDec("Process",1,
117                         "<= BlackBox::bbExecute() ["
118                         <<bbGetFullName()<<"]"<<std::endl);
119   }
120   //=========================================================================
121
122   //=========================================================================
123   std::string BlackBox::bbGetFullName() const
124   { 
125     return bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
126   }
127   //=========================================================================
128      
129
130
131   //=========================================================================
132   /// Returns the name with the name of the parent prepended if any
133   std::string BlackBox::bbGetNameWithParent() const
134   {
135     if (bbmParent) 
136       {
137         return bbmParent->bbGetNameWithParent() + ":" + bbmName;
138       }
139     else 
140       {
141         return bbmName;
142       }
143   } 
144   //=========================================================================
145
146   //=========================================================================
147   /// Prints the Help on the BlackBox type 
148   void BlackBox::bbGetHelp(bool full) const
149   {
150     bbGetDescriptor()->GetHelp(full); 
151   }
152   //=========================================================================
153
154
155   //=========================================================================
156   /// Returns true if the UserBlackBox has an input of name name
157   bool BlackBox::bbHasInput(const std::string& name) const
158   {
159     bbtkDebugMessageInc("Kernel",8,
160                         "BlackBox::bbHasInput(\""
161                         <<name<<"\") ["<<bbGetFullName()<<"]"
162                         <<std::endl);
163     bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
164                != bbGetDescriptor()->GetInputDescriptorMap().end());
165     bbtkDebugDecTab("Kernel",8);
166     return r;
167   }
168   //=========================================================================
169
170
171   //=========================================================================  
172   /// Returns true if the UserBlackBox has an output of name name
173   bool BlackBox::bbHasOutput(const std::string& name) const
174   {
175     bbtkDebugMessageInc("Kernel",8,"BlackBox::bbHasOutput(\""
176                         <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
177     bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
178                != bbGetDescriptor()->GetOutputDescriptorMap().end());
179     bbtkDebugDecTab("Kernel",8);
180     return r;
181   }
182   //=========================================================================
183
184
185   //=========================================================================  
186   ///  Gets the output type of a given name
187   TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const 
188   {
189     bbtkDebugMessageInc("Kernel",8,
190                         "BlackBox::bbGetOutputType(\""
191                         <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
192     TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
193     bbtkDebugDecTab("Kernel",8); 
194     return r;
195   }
196   //=========================================================================
197
198   //=========================================================================
199   ///  Gets the input type of a given name
200   TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
201   {
202     bbtkDebugMessageInc("Kernel",8,
203                         "BlackBox::bbGetInputType(\""
204                         <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
205     TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
206     bbtkDebugDecTab("Kernel",8);
207     return r;
208   }
209   //=========================================================================
210
211
212   //=========================================================================
213   /// Allocates the i/o connectors of the black box
214   void BlackBox::bbAllocateConnectors()
215   {  
216     bbtkDebugMessageInc("Kernel",8,
217                         "BlackBox::bbAllocateConnectors() ["
218                         <<bbGetFullName()<<"]"
219                         <<std::endl);                                   
220     const BlackBoxDescriptor::InputDescriptorMapType& imap 
221       = bbGetDescriptor()->GetInputDescriptorMap(); 
222     BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;       
223     for ( i = imap.begin(); i != imap.end(); ++i )                      
224       {                                                                 
225         bbtkDebugMessage("Kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
226         bbGetInputConnectorMap()[i->second->GetName()] 
227           = new BlackBoxInputConnector(this);
228       }                                                                 
229     const BlackBoxDescriptor::OutputDescriptorMapType& omap 
230       = bbGetDescriptor()->GetOutputDescriptorMap();                   
231     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
232     for ( o = omap.begin(); o != omap.end(); ++o )
233       {                                                 
234         bbtkDebugMessage("Kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
235         bbGetOutputConnectorMap()[o->second->GetName()] 
236           = new BlackBoxOutputConnector();
237       }
238     bbtkDebugDecTab("Kernel",8);  
239   }
240   //=========================================================================
241
242
243   //=========================================================================
244   /// Desallocates the i/o connectors of the black box
245   void BlackBox::bbDesallocateConnectors()
246   {
247     bbtkDebugMessageInc("Kernel",8,
248                         "BlackBox::bbDesallocateConnectors()"
249                         <<std::endl);                                   
250
251     InputConnectorMapType::const_iterator i;
252     for ( i = bbGetInputConnectorMap().begin();
253           i != bbGetInputConnectorMap().end(); ++i )                   
254       {                                                                 
255         bbtkDebugMessage("Kernel",8,"* Delete \""<<i->first<<"\""<<std::endl);
256         delete (i->second);
257       }                                                                 
258     OutputConnectorMapType::const_iterator o;   
259     for ( o = bbGetOutputConnectorMap().begin(); 
260           o != bbGetOutputConnectorMap().end(); ++o )                   
261       {                                                                 
262         bbtkDebugMessage("Kernel",8,"* Delete \""<<o->first<<"\""<<std::endl);         
263         delete (o->second);
264       }                                                                 
265    
266     bbtkDebugDecTab("Kernel",8);  
267
268   }
269   //=========================================================================
270
271
272   //=========================================================================
273   /// Copies the input / output values from another box
274   void BlackBox::bbCopyIOValues(BlackBox& from)
275   {
276     bbtkDebugMessageInc("Kernel",9,
277                         "BlackBox::bbCopyIOValues("
278                         <<from.bbGetFullName()<<") ["
279                         <<bbGetFullName()<<"]"<<std::endl);
280     // copies the input values
281     const BlackBoxDescriptor::InputDescriptorMapType& imap 
282       = bbGetDescriptor()->GetInputDescriptorMap(); 
283     BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;       
284     for ( i = imap.begin(); i != imap.end(); ++i )                      
285       {         
286         if (! i->second->GetCopyConstruct() ) continue;
287         std::string input = i->second->GetName();
288         this->bbSetInput(input, from.bbGetInput(input) );
289       }                                                                 
290     // copies the output values
291     const BlackBoxDescriptor::OutputDescriptorMapType& omap 
292       = bbGetDescriptor()->GetOutputDescriptorMap();                   
293     BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; 
294     for ( o = omap.begin(); o != omap.end(); ++o )
295       {                                                 
296         if (! o->second->GetCopyConstruct() ) continue;
297         std::string output = o->second->GetName();
298         this->bbSetOutput(output, from.bbGetOutput(output) );
299       }
300
301     bbtkDebugDecTab("Kernel",9);
302
303   }
304   //=========================================================================
305
306
307
308   //=========================================================================
309   bool BlackBox::bbCanReact() const 
310   { 
311     return ( bbGlobalGetSomeBoxExecuting() 
312 #ifdef _USE_WXWIDGETS_
313              || Wx::IsSomeWindowAlive() 
314 #endif
315              ); 
316   }
317   //=========================================================================
318
319
320
321   //=========================================================================
322   /// User overloadable destruction method of a black box
323   void BlackBox::bbUserDelete() 
324   {   
325     bbtkDebugMessage("Process",5,
326                      "=> BlackBox::bbUserDelete() ["
327                      <<bbGetFullName()<<"]"
328                      <<" : not overloaded; using standard deletion"
329                      <<std::endl);
330     delete this;
331   }
332   //=========================================================================
333
334
335   //=========================================================================
336   BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
337   {
338     const std::string& p = bbmBoxProcessMode;
339     if ( (p == "0") ||
340          (p == "P") || (p == "p") ||
341          (p == "Pipeline") || (p == "pipeline") ) return Pipeline;
342     if ( (p == "1") ||
343          (p == "A") || (p == "a") ||
344          (p == "Always") || (p == "always") ) return Always;
345     if ( (p == "2") ||
346          (p == "R") || (p == "r") ||
347          (p == "Reactive") || (p == "reactive") ) return Reactive;
348     bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
349               <<"' unknown. Possible values : "
350               <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
351               <<"'1'/'A'/'a'/'Always'/'always' | "
352               <<"'2'/'R'/'r'/'Reactive'/'reactive'"<<std::endl);
353   }
354   //=========================================================================
355   
356   //=========================================================================
357   bool  BlackBox::bbBoxProcessModeIsReactive() const
358   {
359     return (bbGetBoxProcessModeValue() == Reactive);
360   }
361   //=========================================================================
362
363   //=========================================================================
364   bool  BlackBox::bbBoxProcessModeIsAlways() const
365   {
366     return (bbGetBoxProcessModeValue() == Always);
367   }
368   //=========================================================================
369
370   //=========================================================================
371   ///  Signals that the BlackBox has been modified
372   void BlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
373   {
374     bbtkDebugMessageInc("Process",5,
375                         "=> BlackBox::bbSetModifiedStatus("<<c<<") ["
376                         <<bbGetFullName()<<"]"<<std::endl);
377    
378     if ( (c==bbGetInputConnectorMap().find("WinHide")->second) )
379          //      && (bbCanReact()))
380       {
381         bbtkDebugMessage("Process",9,
382                          "-> Hide triggered by WinHide input change"
383                          <<std::endl);
384         this->bbHideWindow();
385         this->bbSetStatus(MODIFIED); 
386         return;
387       }
388  
389     if ( ( bbBoxProcessModeIsReactive()  ||
390            (c==bbGetInputConnectorMap().find("BoxExecute")->second))
391          && (bbCanReact() ) )
392       {
393         bbtkDebugMessage("Process",9,
394                          "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
395         this->bbSetStatus(MODIFIED); 
396         bbGlobalAddToExecutionList( this );
397       }
398     else if ( bbGetStatus() == MODIFIED ) //! this->bbIsUptodate()) 
399       { 
400         bbtkDebugMessage("Process",5,"-> Already modified"<<std::endl);
401         bbtkDebugDecTab("Process",5);
402         return;
403       }
404     else 
405       {
406         bbtkDebugMessage("Process",5,"-> Status set to modified"<<std::endl);
407         bbtkDebugDecTab("Process",5);
408         this->bbSetStatus(MODIFIED); 
409       }
410  
411     this->bbSignalOutputModification(false);
412
413    bbtkDebugMessageDec("Process",5,
414                         "<= BlackBox::bbSetModifiedStatus("<<c<<") ["
415                         <<bbGetFullName()<<"]"<<std::endl);
416   }  
417   //=========================================================================
418
419   //=========================================================================  
420   void BlackBox::bbSignalOutputModification(bool reaction)
421   {
422     bbtkDebugMessageInc("Process",5,
423                         "=> BlackBox::bbSignalOutputModification() ["
424                         <<bbGetFullName()<<"]"<<std::endl);
425     
426     OutputConnectorMapType::iterator change = bbGetOutputConnectorMap().end();
427     OutputConnectorMapType::iterator i;
428     for ( i  = bbGetOutputConnectorMap().begin(); 
429           i != bbGetOutputConnectorMap().end(); ++i) {
430       /*     if ( i->first == "BoxChange" ) 
431         {
432           change = i;
433           continue;
434         }
435       */
436       i->second->SetModifiedStatus();
437     } 
438     //    if (change != bbGetOutputConnectorMap().end()) 
439     // change->second->SetModifiedStatus();
440
441     if (reaction) bbGlobalProcessExecutionList();
442
443     bbtkDebugMessageDec("Process",5,
444                         "<= BlackBox::bbSignalOutputModification() ["
445                         <<bbGetFullName()<<"]"<<std::endl);
446     
447   }  
448   //=========================================================================   
449   //=========================================================================  
450   void BlackBox::bbSignalOutputModification(const std::string& output,
451         bool reaction)
452   {
453     bbtkDebugMessageInc("Process",5,
454                         "=> BlackBox::bbSignalOutputModification("
455                         <<output<<") ["
456                         <<bbGetFullName()<<"]"<<std::endl);
457     
458     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(output);
459     if ( i == bbGetOutputConnectorMap().end() ) 
460         {
461           bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
462         }
463     i->second->SetModifiedStatus();
464     // Has to notify the output "BoxChange" also
465     if (output != "BoxChange") 
466       {
467         i = bbGetOutputConnectorMap().find("BoxChange");
468         if ( i != bbGetOutputConnectorMap().end() ) 
469           {
470             i->second->SetModifiedStatus();
471           }
472       }
473   if (reaction) bbGlobalProcessExecutionList();
474
475   bbtkDebugMessageDec("Process",5,
476                       "<= BlackBox::bbSignalOutputModification("
477                       <<output<<") ["
478                       <<bbGetFullName()<<"]"<<std::endl);
479
480   }  
481   //=========================================================================   
482   //=========================================================================  
483   void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
484         bool reaction)
485   {
486     bbtkDebugMessageInc("Process",5,
487                         "=> BlackBox::bbSignalOutputModification(vector of outputs) ["
488                         <<bbGetFullName()<<"]"<<std::endl);
489     OutputConnectorMapType::iterator i;
490     std::vector<std::string>::const_iterator o;
491     for (o=output.begin();o!=output.end();++o) 
492       {
493         // the output "BoxChange" must be signaled **AFTER** all others
494         if (*o == "BoxChange") continue;
495         // Look for the connector
496         i = bbGetOutputConnectorMap().find(*o);
497         if ( i == bbGetOutputConnectorMap().end() ) 
498           {
499             bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
500           }
501         i->second->SetModifiedStatus();
502       }
503     // Has to notify the output "BoxChange" also
504     i = bbGetOutputConnectorMap().find("BoxChange");
505     if ( i != bbGetOutputConnectorMap().end() ) 
506       {
507         i->second->SetModifiedStatus();
508       }
509   if (reaction) bbGlobalProcessExecutionList();
510
511    bbtkDebugMessageDec("Process",5,
512                        "<= BlackBox::bbSignalOutputModification(vector of outputs) ["
513                         <<bbGetFullName()<<"]"<<std::endl);
514
515   }  
516   //=========================================================================   
517
518   //=========================================================================
519   /// Updates the BlackBox inputs
520   /// \returns UPTODATE if all inputs are in UPTODATE status after update
521   ///          else MODIFIED 
522   IOStatus BlackBox::bbUpdateInputs(bool excludeParent)
523   {
524     bbtkDebugMessageInc("Process",4,
525                         "=> BlackBox::bbUpdateInputs() ["
526                         <<bbGetFullName()<<"]"
527                         <<std::endl);   
528
529     IOStatus s = UPTODATE;
530
531     InputConnectorMapType::iterator i;
532     for ( i = bbGetInputConnectorMap().begin(); 
533           i!= bbGetInputConnectorMap().end(); ++i) 
534       {
535         if (excludeParent && (i->first=="WinParent")) continue;
536         if (i->first=="WinHide") continue;
537         // If input type is Void : no recurse
538         //if (  bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo() 
539         //      == typeid(Void) ) 
540         //  continue;
541
542         IOStatus t = i->second->BackwardUpdate();
543         if (t==MODIFIED) s = MODIFIED;
544       }
545     
546    bbtkDebugMessageDec("Process",4,
547                         "<= BlackBox::bbUpdateInputs() ["
548                         <<bbGetFullName()<<"]"
549                         <<std::endl);   
550
551
552     return s;
553   }
554   //=========================================================================
555
556  
557   //=========================================================================
558   /// Connects the input <name> to the connection c
559   void BlackBox::bbConnectInput( const std::string& name, Connection* c)
560   {
561     bbtkDebugMessageInc("Kernel",7,
562                         "BlackBox::bbConnectInput(\""<<name<<"\","<<c<<") ["
563                         <<bbGetFullName()<<"]"
564                         <<std::endl);       
565     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
566     if (i==bbGetInputConnectorMap().end())
567       {
568         bbtkError("no input called '"<<name<<"'");
569       }
570     i->second->SetConnection(c);
571     
572     //  bbSetModifiedStatus();
573
574     bbtkDebugDecTab("Kernel",7);
575   }
576   //=========================================================================
577
578
579   //=========================================================================  
580   /// Connects the output <name> to the connection c
581   void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
582   {
583     bbtkDebugMessageInc("Kernel",7,
584                         "BlackBox::bbConnectOutput(\""<<name<<"\","<<c<<") ["
585                         <<bbGetFullName()<<"]"<<std::endl);       
586
587     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
588     if (i==bbGetOutputConnectorMap().end())
589       {
590         bbtkError("no output called '"<<name<<"'");
591       }
592     i->second->SetConnection(c);
593
594     bbtkDebugDecTab("Kernel",7);
595   }
596   //=========================================================================
597
598
599   //=========================================================================
600   /// Disconnects the input <name> from the connection c
601   void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
602   {
603     bbtkDebugMessageInc("Kernel",7,
604                         "BlackBox::bbDisconnectInput(\""<<name
605                         <<"\","<<c<<") ["
606                         <<bbGetFullName()<<"]"
607                         <<std::endl);      
608
609     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
610     if (i==bbGetInputConnectorMap().end())
611       {
612         bbtkError("no input called '"<<name<<"'");
613       }
614     i->second->UnsetConnection(c);
615
616     bbtkDebugDecTab("Kernel",7);
617   }
618   //=========================================================================
619
620
621   //=========================================================================
622   /// Disconnects the output <name> from the connection c
623   void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
624   {
625     bbtkDebugMessageInc("Kernel",7,
626                         "BlackBox::bbDisconnectOutput(\""<<name
627                         <<"\","<<c<<") ["
628                         <<bbGetFullName()<<"]"
629                         <<std::endl);       
630
631     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
632     if (i==bbGetOutputConnectorMap().end())
633       {
634         bbtkError("no output called '"<<name<<"'");
635       }
636     i->second->UnsetConnection(c);
637
638     bbtkDebugDecTab("Kernel",7);
639   } 
640   //=========================================================================
641  
642
643   //=========================================================================
644   /// Virtual
645   void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
646   {
647     fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
648   }
649   //=========================================================================
650
651
652   //=========================================================================
653   std::string BlackBox::bbGetOutputAsString( const std::string &output ) 
654   {
655     std::string v;
656     // Looks for the adaptor
657     if (bbGetOutputType(output).name() != typeid(std::string).name() ) 
658       {
659         // Look for factory 
660         Package* p = bbGetDescriptor()->GetPackage();
661         if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
662           {
663             Factory* f = *p->GetFactorySet().begin();
664             BlackBox* a = 0;
665             try
666               {
667                 a = f->NewAdaptor(  
668                                   bbGetOutputType(output),
669                                   typeid(std::string),
670                                   "");
671               } catch (bbtk::Exception e) 
672               {
673               }
674             if (a!=NULL){
675               //                        bbUpdate();
676               a->bbSetInput("In",bbGetOutput(output));
677               a->bbExecute();
678               v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
679             } else {
680               v="? (no adaptor found)";
681             }
682           }
683         else 
684           {
685             v="? (no factory found)";
686           }
687       } 
688     else 
689       {
690         //         bbUpdate();
691         v = bbGetOutput(output).unsafe_get<std::string>() ;
692       }
693     return v;
694   }
695   //=========================================================================
696
697   //=========================================================================
698   std::string BlackBox::bbGetInputAsString( const std::string &input ) 
699   {
700     std::string v;
701     // Looks for the adaptor
702     if (bbGetInputType(input) != typeid(std::string)) 
703       {
704         // Look for factory 
705         Package* p = bbGetDescriptor()->GetPackage();
706         if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
707           {
708             Factory* f = *p->GetFactorySet().begin();
709             BlackBox* a = 0;
710             try
711               {
712                 a = f->NewAdaptor(  
713                                bbGetInputType(input),
714                                typeid(std::string),
715                                "");
716               }catch (bbtk::Exception e) 
717               {
718               }
719             if (a!=NULL)
720               {
721                 //                      bbUpdate();
722                 a->bbSetInput("In",bbGetInput(input));
723                 a->bbExecute();
724                 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
725               } 
726             else 
727               {
728                 v="? (no adaptor found)";
729               }
730           } 
731         else 
732           {
733             v="? (no factory found)";
734           }
735       }
736     else 
737       {
738         v = bbGetInput(input).unsafe_get<std::string>() ;
739       }
740     return v;
741   }
742   //=======================================================================
743
744   //=======================================================================
745   // Replaces substrings "<" by "["
746   void SubsBrackets ( std::string& s )
747   {
748     //   std::cout << "BEFORE=["<<s<<"]"<<std::endl;
749     std::string ss("<");
750     std::string::size_type pos = 0;
751     pos = s.find(ss,0);
752     char* cr = "[";
753     while ( pos != std::string::npos )
754       {
755         //      std::cout << "*** find one "<<std::endl;
756         s.replace(pos,1,cr,1);
757         pos = s.find(ss, pos);
758       } 
759     ss = ">";
760     pos = 0;
761     pos = s.find(ss,0);
762     cr = "]";
763     while ( pos != std::string::npos )
764       {
765         //      std::cout << "*** find one "<<std::endl;
766         s.replace(pos,1,cr,1);
767         pos = s.find(ss, pos);
768       } 
769     ss = ",";
770     pos = 0;
771     pos = s.find(ss,0);
772     cr = "-";
773     while ( pos != std::string::npos )
774       {
775         //      std::cout << "*** find one "<<std::endl;
776         s.replace(pos,1,cr,1);
777         pos = s.find(ss, pos);
778       }     //    std::cout << "AFTER=["<<s<<"]"<<std::endl;
779   }
780   //=======================================================================
781
782   //=========================================================================
783   /// Write Graphviz-dot description in file
784   void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
785                                         BlackBox *parentblackbox, 
786                                         int detail, int level,
787                                         bool instanceOrtype,
788                                         bool relative_link )
789
790   { 
791     InputConnectorMapType::iterator i;
792     // label
793     std::string labelStr;
794     std::string valueStr("");
795
796         if (detail==0) {
797                 labelStr = bbGetName() ; 
798 //EED 18 Fev 2008
799                 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
800         } else {
801                 labelStr = bbGetName();
802                 labelStr = labelStr + "   [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]  ";
803     }
804
805     SubsBrackets(labelStr);
806     if (detail==1)
807       {
808         labelStr = labelStr + " | {{ "; 
809         std::string tempStrTypeName;
810         bool tmp; 
811         tmp=false;
812         for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
813           {
814             if (tmp==true)
815               {
816                 labelStr=labelStr+" | ";
817               }
818             tmp=true;
819             if (instanceOrtype==true)
820               {
821                 valueStr = this->bbGetInputAsString(i->first) + " = ";
822               } 
823             const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
824             tempStrTypeName=id->GetTypeName();
825             SubsBrackets(tempStrTypeName);
826             std::string Name(i->first);
827             SubsBrackets(Name);
828             labelStr=labelStr + "<"+i->first.c_str()+"> "  + valueStr +  Name.c_str() + "  [" + tempStrTypeName.c_str() + "]";
829           }
830         labelStr=labelStr+ " } | {";
831         tmp = false;
832         OutputConnectorMapType::iterator ii;
833         for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii ) 
834         {
835            if (tmp==true)
836            {
837                    labelStr=labelStr+" | ";
838            }
839            tmp = true;
840            if (instanceOrtype==true)
841            {
842                    valueStr = this->bbGetOutputAsString(ii->first) + " = ";
843            }
844            const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first); 
845            tempStrTypeName=id->GetTypeName();
846            SubsBrackets(tempStrTypeName);
847             std::string Name(ii->first);
848             SubsBrackets(Name);
849            labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + "  ["+tempStrTypeName+"]";
850         }
851         labelStr = labelStr+ "      } }" ;
852 } // detail
853
854     fprintf(ff,"  " );
855     bbWriteDotInputOutputName(ff,true,detail,level);
856     std::string tmp ( bbGetTypeName() );
857     SubsBrackets(tmp);
858     std::string url;
859     if (relative_link) 
860       url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
861     else 
862       url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
863   
864     fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
865     //    std::cout  << labelStr << std::endl;
866
867     // Relation Input
868     if (this!=parentblackbox){
869       for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
870         {
871           if (i->second)
872             {
873               Connection* con = i->second->GetConnection();
874               if (con!=NULL){
875                 BlackBox *a=con->GetBlackBoxFrom();
876                 BlackBox *b=con->GetBlackBoxTo();
877                 fprintf(ff,"  ");
878                 a->bbWriteDotInputOutputName(ff,false,detail,level);
879                 if (detail==1)
880                   {
881                     fprintf(ff,":%s",con->GetBlackBoxFromOutput().c_str());
882                   }
883                 fprintf(ff,"->");
884                 b->bbWriteDotInputOutputName(ff,true,detail,level);
885                 if (detail==1)
886                   {
887                     fprintf(ff,":%s",con->GetBlackBoxToInput().c_str());
888                   }
889                 fprintf(ff,"%s\n",";");
890               }  // if con
891             } // if second
892         } // for
893     } // if parentblackbox
894   }
895   //=========================================================================
896
897
898
899
900   //=========================================================================
901   void BlackBox::bbShowRelations(BlackBox *parentblackbox, 
902                                  int detail, int level
903                                  /*,Factory *factory*/ )
904   {
905      
906     if (this->bbGetDescriptor()->GetPackage()) 
907       {
908         bbtkMessage("Help",1,"Black Box '"<<bbGetName()<<"' <"<<
909                     this->bbGetDescriptor()->GetPackage()->GetName()
910                     <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
911       }
912     else 
913       {
914         bbtkMessage("Help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
915       }
916     //    bbtkMessage("Help",1," "<<GetDescription()<<std::endl);
917     //    bbtkMessage("Help",1," By : "<<GetAuthor()<<std::endl);
918
919     std::vector<std::string> iname;
920     std::vector<std::string> ivalue;
921     std::vector<std::string> iconn;
922
923     InputConnectorMapType::iterator i;
924     unsigned int namelmax = 0;
925     unsigned int valuelmax = 0;
926     unsigned int connlmax = 0;
927     for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
928       {
929         iname.push_back(i->first);
930         if (iname.back().size()>namelmax) namelmax = iname.back().size();
931         ivalue.push_back(bbGetInputAsString(i->first));
932         if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
933         std::string s("");
934         Connection* con = i->second->GetConnection();
935         if (con!=0){
936           s = con->GetBlackBoxFrom()->bbGetName();
937           s += ".";
938           s += con->GetBlackBoxFromOutput();
939         }  // if con
940         iconn.push_back(s);
941       }
942     OutputConnectorMapType::iterator o;
943     std::vector<std::string> oname;
944     std::vector<std::string> ovalue;
945     std::vector<std::vector<std::string> > oconn;
946     for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o ) 
947       {
948         oname.push_back(o->first);
949         if (oname.back().size()>namelmax) namelmax = oname.back().size();
950         ovalue.push_back(bbGetOutputAsString(o->first));
951         if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size();
952         std::vector<std::string> ss;
953         const std::vector<Connection*>& con = o->second->GetConnectionVector();
954         std::vector<Connection*>::const_iterator c;
955         for (c=con.begin();c!=con.end();++c) 
956           {
957             std::string s;
958             s = (*c)->GetBlackBoxTo()->bbGetName();
959             s += ".";
960             s += (*c)->GetBlackBoxToInput();
961             ss.push_back(s);
962         }  // if con
963         oconn.push_back(ss);
964       }
965
966     if (iname.size()) 
967       bbtkMessage("Help",1," * Inputs : "<<std::endl);
968     else 
969       bbtkMessage("Help",1," * No inputs"<<std::endl);
970
971     std::vector<std::string>::iterator i1,i2,i3;
972     for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin();
973          i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end();
974          ++i1,++i2,++i3)
975       {
976         std::string name(*i1);
977         name += "'";
978         name.append(1+namelmax-name.size(),' ');
979         std::string value(*i2);
980         value += "'";
981         value.append(1+valuelmax-value.size(),' ');
982         if (i3->size()) 
983           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<" <-- '"<<*i3<<"'"<<std::endl);
984         else 
985           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<std::endl);
986       }
987
988     if (oname.size()) 
989       bbtkMessage("Help",1," * Outputs : "<<std::endl);
990     else 
991       bbtkMessage("Help",1," * No outputs"<<std::endl);
992
993     std::vector<std::vector<std::string> >::iterator i4;
994
995     for (i1=oname.begin(),i2=ovalue.begin(),i4=oconn.begin();
996          i1!=oname.end(),i2!=ovalue.end(),i4!=oconn.end();
997          ++i1,++i2,++i4)
998       {
999         std::string name(*i1);
1000         name += "'";
1001         name.append(1+namelmax-name.size(),' ');
1002         std::string value(*i2);
1003         value += "'";
1004         value.append(1+valuelmax-value.size(),' ');
1005         if (!(*i4).size())
1006           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<std::endl);
1007         else 
1008           {
1009             std::string pref = "    '"+name+" = '"+value;
1010             for (i3=i4->begin();i3!=i4->end();++i3)
1011               {
1012                 bbtkMessage("Help",1,pref<<" --> '"<<*i3<<"'"<<std::endl);
1013                 pref.replace(0,pref.size(),pref.size(),' ');
1014               }
1015           }
1016       }
1017
1018    }
1019   //=========================================================================
1020
1021
1022   //=========================================================================
1023    void BlackBox::bbGlobalProcessExecutionList()
1024    {   
1025      bbtkDebugMessageInc("Process",1,
1026                          "=> BlackBox::bbGlobalProcessExecutionList()"
1027                          <<std::endl);     
1028      
1029      std::set<BlackBox*>::iterator i;
1030      for (i=bbmgExecutionList.begin();
1031           i!=bbmgExecutionList.end();
1032           ++i)
1033        {
1034          bbtkDebugMessage("Process",2,
1035                           " -> Executing "<<(*i)->bbGetFullName()<<std::endl);
1036          (*i)->bbExecute(true);
1037        }
1038      
1039      bbmgExecutionList.clear();
1040      bbtkDebugMessageDec("Process",1,
1041                          "<= BlackBox::bbGlobalProcessExecutionList()"
1042                          <<std::endl);     
1043      
1044      
1045    }
1046   //=========================================================================
1047
1048     bool BlackBox::bbGlobalGetSomeBoxExecuting()
1049         { 
1050                 return bbmgSomeBoxExecuting; 
1051         }
1052
1053     void BlackBox::bbGlobalSetSomeBoxExecuting(bool b) 
1054         { 
1055                 bbmgSomeBoxExecuting = b; 
1056         }
1057
1058     void BlackBox::bbGlobalSetFreezeExecution(bool b) 
1059         { 
1060                 bbmgFreezeExecution = b;
1061         }
1062
1063     bool BlackBox::bbGlobalGetFreezeExecution() 
1064         { 
1065                 return bbmgFreezeExecution; 
1066         }
1067
1068     void BlackBox::bbGlobalAddToExecutionList( BlackBox* b )
1069         {  
1070                 bbmgExecutionList.insert(b); 
1071         } 
1072
1073
1074   //=========================================================================
1075   // Static members initialization
1076 /*EED
1077   bool BlackBox::bbmgSomeBoxExecuting = false;
1078   bool BlackBox::bbmgFreezeExecution = false;
1079   std::set<BlackBox*> BlackBox::bbmgExecutionList;
1080 */
1081    //=========================================================================
1082
1083
1084 }  // EO namespace bbtk
1085
1086 // EOF
1087