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