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