]> 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/06/19 09:46:41 $
7 Version:   $Revision: 1.21 $
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     : bbmName(name), 
94       bbmStatus(MODIFIED), 
95       bbmBoxProcessMode("Pipeline"),
96       bbmParent()
97
98   {
99     bbtkDebugMessage("object",4,"==> BlackBox::BlackBox(\""
100                      <<name<<"\")"<<std::endl);
101     bbtkDebugMessage("object",4,"<== BlackBox::BlackBox(\""
102                      <<name<<"\")"<<std::endl);
103   }
104   //=========================================================================
105
106   //=========================================================================
107   BlackBox::BlackBox(const BlackBox&)
108   {}
109
110   //=========================================================================
111   BlackBox::BlackBox(BlackBox& from, const std::string &name) 
112     : bbmName(name), 
113       bbmStatus(from.bbmStatus), 
114       bbmBoxProcessMode(from.bbmBoxProcessMode),
115       bbmParent()
116
117   {
118     bbtkDebugMessage("object",4,"==> BlackBox::BlackBox("
119                      <<from.bbGetFullName()<<",\""
120                      <<name<<"\")"<<std::endl);
121     bbtkDebugMessage("object",4,"<== BlackBox::BlackBox("
122                      <<from.bbGetFullName()<<",\""
123                      <<name<<"\")"<<std::endl);
124   }
125   //=========================================================================
126
127
128   //=========================================================================
129   BlackBox::~BlackBox()
130   {
131     bbtkDebugMessage("object",4,"==> BlackBox::~BlackBox() ["<<bbmName
132                      <<"]"<<std::endl);
133     this->bbDesallocateConnectors();
134     bbtkDebugMessage("object",4,"<== BlackBox::~BlackBox() ["<<bbmName
135                      <<"]"<<std::endl);
136   }
137   //=========================================================================
138
139
140   //=========================================================================
141   /// Main processing method of the box.
142   void BlackBox::bbExecute(bool force)
143   {
144     bbtkDebugMessageInc("process",2,
145                         "=> BlackBox::bbExecute() ["
146                         <<bbGetFullName()<<"]"<<std::endl);
147  
148         wxBusyCursor wait;
149     //EED Wx::BeginBusyCursor();
150
151     // If execution frozen : return
152     if (bbGlobalGetFreezeExecution()) 
153       {
154         bbtkDebugMessage("process",2,
155                          " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
156       }
157
158     // If force is true then update is triggered even if the box is UPTODATE
159     if (force) bbSetModifiedStatus();
160
161     // Calls the main recursive update method 
162     bbBackwardUpdate(Connection::Pointer());
163
164     //EED Wx::EndBusyCursor();
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     else if ( bbGetStatus() == MODIFIED ) //! this->bbIsUptodate()) 
459       { 
460         bbtkDebugMessage("modified",2,"-> Already modified"<<std::endl);
461         return;
462       }
463     else 
464       {
465         bbtkDebugMessage("modified",2,"-> Status set to modified"<<std::endl);
466         this->bbSetStatus(MODIFIED); 
467       }
468  
469     this->bbSignalOutputModification(false);
470
471     /* 
472   bbtkDebugMessageDec("process",5,
473                         "<= BlackBox::bbSetModifiedStatus("<<c<<") ["
474                         <<bbGetFullName()<<"]"<<std::endl);
475     */
476   }  
477   //=========================================================================
478
479   //=========================================================================  
480   void BlackBox::bbSignalOutputModification(bool reaction)
481   {
482     bbtkDebugMessageInc("process",5,
483                         "=> BlackBox::bbSignalOutputModification() ["
484                         <<bbGetFullName()<<"]"<<std::endl);
485     
486     OutputConnectorMapType::iterator change = bbGetOutputConnectorMap().end();
487     OutputConnectorMapType::iterator i;
488     for ( i  = bbGetOutputConnectorMap().begin(); 
489           i != bbGetOutputConnectorMap().end(); ++i) {
490       /*     if ( i->first == "BoxChange" ) 
491         {
492           change = i;
493           continue;
494         }
495       */
496       i->second->SetModifiedStatus();
497     } 
498     //    if (change != bbGetOutputConnectorMap().end()) 
499     // change->second->SetModifiedStatus();
500
501     if (reaction) bbGlobalProcessExecutionList();
502
503     bbtkDebugMessageDec("process",5,
504                         "<= BlackBox::bbSignalOutputModification() ["
505                         <<bbGetFullName()<<"]"<<std::endl);
506     
507   }  
508   //=========================================================================   
509   //=========================================================================  
510   void BlackBox::bbSignalOutputModification(const std::string& output,
511         bool reaction)
512   {
513     bbtkDebugMessageInc("process",5,
514                         "=> BlackBox::bbSignalOutputModification("
515                         <<output<<") ["
516                         <<bbGetFullName()<<"]"<<std::endl);
517     
518     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(output);
519     if ( i == bbGetOutputConnectorMap().end() ) 
520         {
521           bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
522         }
523     i->second->SetModifiedStatus();
524     // Has to notify the output "BoxChange" also
525     if (output != "BoxChange") 
526       {
527         i = bbGetOutputConnectorMap().find("BoxChange");
528         if ( i != bbGetOutputConnectorMap().end() ) 
529           {
530             i->second->SetModifiedStatus();
531           }
532       }
533   if (reaction) bbGlobalProcessExecutionList();
534
535   bbtkDebugMessageDec("process",5,
536                       "<= BlackBox::bbSignalOutputModification("
537                       <<output<<") ["
538                       <<bbGetFullName()<<"]"<<std::endl);
539
540   }  
541   //=========================================================================   
542   //=========================================================================  
543   void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
544         bool reaction)
545   {
546     bbtkDebugMessageInc("process",5,
547                         "=> BlackBox::bbSignalOutputModification(vector of outputs) ["
548                         <<bbGetFullName()<<"]"<<std::endl);
549     OutputConnectorMapType::iterator i;
550     std::vector<std::string>::const_iterator o;
551     for (o=output.begin();o!=output.end();++o) 
552       {
553         // the output "BoxChange" must be signaled **AFTER** all others
554         if (*o == "BoxChange") continue;
555         // Look for the connector
556         i = bbGetOutputConnectorMap().find(*o);
557         if ( i == bbGetOutputConnectorMap().end() ) 
558           {
559             bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
560           }
561         i->second->SetModifiedStatus();
562       }
563     // Has to notify the output "BoxChange" also
564     i = bbGetOutputConnectorMap().find("BoxChange");
565     if ( i != bbGetOutputConnectorMap().end() ) 
566       {
567         i->second->SetModifiedStatus();
568       }
569   if (reaction) bbGlobalProcessExecutionList();
570
571    bbtkDebugMessageDec("process",5,
572                        "<= BlackBox::bbSignalOutputModification(vector of outputs) ["
573                         <<bbGetFullName()<<"]"<<std::endl);
574
575   }  
576   //=========================================================================   
577
578   //=========================================================================
579   /// Updates the BlackBox inputs
580   /// \returns UPTODATE if all inputs are in UPTODATE status after update
581   ///          else MODIFIED 
582   IOStatus BlackBox::bbUpdateInputs(bool excludeParent)
583   {
584     bbtkDebugMessageInc("process",4,
585                         "=> BlackBox::bbUpdateInputs() ["
586                         <<bbGetFullName()<<"]"
587                         <<std::endl);   
588
589     IOStatus s = UPTODATE;
590
591     InputConnectorMapType::iterator i;
592     for ( i = bbGetInputConnectorMap().begin(); 
593           i!= bbGetInputConnectorMap().end(); ++i) 
594       {
595         if (excludeParent && (i->first=="WinParent")) continue;
596         if (i->first=="WinHide") continue;
597         // If input type is Void : no recurse
598         //if (  bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo() 
599         //      == typeid(Void) ) 
600         //  continue;
601
602         IOStatus t = i->second->BackwardUpdate();
603         if (t==MODIFIED) s = MODIFIED;
604       }
605     
606    bbtkDebugMessageDec("process",4,
607                         "<= BlackBox::bbUpdateInputs() ["
608                         <<bbGetFullName()<<"]"
609                         <<std::endl);   
610
611
612     return s;
613   }
614   //=========================================================================
615
616  
617   //=========================================================================
618   /// Connects the input <name> to the connection c
619   void BlackBox::bbConnectInput( const std::string& name, Connection* c)
620   {
621     bbtkDebugMessage("connection",2,
622                         "==> BlackBox::bbConnectInput(\""
623                         <<name<<"\","<<c->GetFullName()<<") ["
624                         <<bbGetFullName()<<"]"
625                         <<std::endl);       
626
627
628     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
629     if (i==bbGetInputConnectorMap().end())
630       {
631         bbtkError("no input called '"<<name<<"'");
632       }
633     i->second->SetConnection(c);
634     
635     bbtkDebugMessage("connection",2,
636                         "<== BlackBox::bbConnectInput(\""
637                         <<name<<"\","<<c->GetFullName()<<") ["
638                         <<bbGetFullName()<<"]"
639                         <<std::endl);       
640     //  bbSetModifiedStatus();
641
642   }
643   //=========================================================================
644
645
646   //=========================================================================  
647   /// Connects the output <name> to the connection c
648   void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
649   {
650     bbtkDebugMessage("connection",2,
651                      "==> BlackBox::bbConnectOutput(\""<<name<<"\","
652                      <<c->GetFullName()<<") ["
653                      <<bbGetFullName()<<"]"<<std::endl);       
654     
655     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
656     if (i==bbGetOutputConnectorMap().end())
657       {
658         bbtkError("no output called '"<<name<<"'");
659       }
660     i->second->SetConnection(c);
661
662     bbtkDebugMessage("connection",2,
663                      "<== BlackBox::bbConnectOutput(\""<<name<<"\","
664                      <<c->GetFullName()<<") ["
665                      <<bbGetFullName()<<"]"<<std::endl);       
666
667   }
668   //=========================================================================
669
670
671   //=========================================================================
672   /// Disconnects the input <name> from the connection c
673   void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
674   {
675
676     bbtkDebugMessage("connection",2,
677                      "==> BlackBox::bbDisconnectInput(\""<<name
678                      <<"\","<<c->GetFullName()<<") ["
679                      <<bbGetFullName()<<"]"
680                      <<std::endl);      
681
682     if (!c) 
683       {
684
685         bbtkDebugMessage("connection",2,"c==0"<<std::endl);     
686         return;
687       }
688
689     InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
690     if (i==bbGetInputConnectorMap().end())
691       {
692         bbtkError("no input called '"<<name<<"'");
693       }
694     i->second->UnsetConnection(c);
695
696     bbtkDebugMessage("connection",2,
697                      "<== BlackBox::bbDisconnectInput(\""<<name
698                      <<"\","<<c->GetFullName()<<") ["
699                      <<bbGetFullName()<<"]"
700                      <<std::endl);      
701
702   }
703   //=========================================================================
704
705
706   //=========================================================================
707   /// Disconnects the output <name> from the connection c
708   void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
709   {
710     bbtkDebugMessage("connection",2,
711                      "==> BlackBox::bbDisconnectOutput(\""<<name
712                      <<"\","<<c->GetFullName()<<") ["
713                      <<bbGetFullName()<<"]"
714                      <<std::endl);       
715     if (!c) 
716       {
717
718         bbtkDebugMessage("connection",2,"c==0"<<std::endl);     
719         return;
720       }
721
722     OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
723     if (i==bbGetOutputConnectorMap().end())
724       {
725         bbtkError("no output called '"<<name<<"'");
726       }
727     i->second->UnsetConnection(c);
728
729     bbtkDebugMessage("connection",2,
730                      "<== BlackBox::bbDisconnectOutput(\""<<name
731                      <<"\","<<c->GetFullName()<<") ["
732                      <<bbGetFullName()<<"]"
733                      <<std::endl);       
734   } 
735   //=========================================================================
736  
737
738   //=========================================================================
739   /// Virtual
740   void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
741   {
742     fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
743   }
744   //=========================================================================
745
746
747   //=========================================================================
748   std::string BlackBox::bbGetOutputAsString( const std::string &output ) 
749   {
750     std::string v;
751     // Looks for the adaptor
752     if (bbGetOutputType(output).name() != typeid(std::string).name() ) 
753       {
754         // Look for factory 
755         Package::Pointer p = bbGetDescriptor()->GetPackage();
756         if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
757           {
758             Factory::Pointer f = p->GetFactorySet().begin()->lock();
759             BlackBox::Pointer a;
760             try
761               {
762                 a = f->NewAdaptor(  
763                                   bbGetOutputType(output),
764                                   typeid(std::string),
765                                   "");
766               } catch (bbtk::Exception e) 
767               {
768               }
769             if (a){
770               //                        bbUpdate();
771               a->bbSetInput("In",bbGetOutput(output));
772               a->bbExecute();
773               v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
774             } else {
775               v="? (no adaptor found)";
776             }
777           }
778         else 
779           {
780             v="? (no factory found)";
781           }
782       } 
783     else 
784       {
785         //         bbUpdate();
786         v = bbGetOutput(output).unsafe_get<std::string>() ;
787       }
788     return v;
789   }
790   //=========================================================================
791
792   //=========================================================================
793   std::string BlackBox::bbGetInputAsString( const std::string &input ) 
794   {
795     std::string v;
796     // Looks for the adaptor
797     if (bbGetInputType(input) != typeid(std::string)) 
798       {
799         // Look for factory 
800         Package::Pointer p = bbGetDescriptor()->GetPackage();
801         if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
802           {
803             Factory::Pointer f = p->GetFactorySet().begin()->lock();
804             BlackBox::Pointer a;
805             try
806               {
807                 a = f->NewAdaptor(  
808                                bbGetInputType(input),
809                                typeid(std::string),
810                                "");
811               }catch (bbtk::Exception e) 
812               {
813               }
814             if (a)
815               {
816                 //                      bbUpdate();
817                 a->bbSetInput("In",bbGetInput(input));
818                 a->bbExecute();
819                 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
820               } 
821             else 
822               {
823                 v="? (no adaptor found)";
824               }
825           } 
826         else 
827           {
828             v="? (no factory found)";
829           }
830       }
831     else 
832       {
833         v = bbGetInput(input).unsafe_get<std::string>() ;
834       }
835     return v;
836   }
837   //=======================================================================
838
839   //=======================================================================
840   // Replaces substrings "<" by "["
841   void SubsBrackets ( std::string& s )
842   {
843     //   std::cout << "BEFORE=["<<s<<"]"<<std::endl;
844     std::string ss("<");
845     std::string::size_type pos = 0;
846     pos = s.find(ss,0);
847     char* cr = "[";
848     while ( pos != std::string::npos )
849       {
850         //      std::cout << "*** find one "<<std::endl;
851         s.replace(pos,1,cr,1);
852         pos = s.find(ss, pos);
853       } 
854     ss = ">";
855     pos = 0;
856     pos = s.find(ss,0);
857     cr = "]";
858     while ( pos != std::string::npos )
859       {
860         //      std::cout << "*** find one "<<std::endl;
861         s.replace(pos,1,cr,1);
862         pos = s.find(ss, pos);
863       } 
864     ss = ",";
865     pos = 0;
866     pos = s.find(ss,0);
867     cr = "-";
868     while ( pos != std::string::npos )
869       {
870         //      std::cout << "*** find one "<<std::endl;
871         s.replace(pos,1,cr,1);
872         pos = s.find(ss, pos);
873       }     //    std::cout << "AFTER=["<<s<<"]"<<std::endl;
874   }
875   //=======================================================================
876
877   //=========================================================================
878   /// Write Graphviz-dot description in file
879   void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
880                                         BlackBox::Pointer parentblackbox, 
881                                         int detail, int level,
882                                         bool instanceOrtype,
883                                         bool relative_link )
884
885   { 
886     InputConnectorMapType::iterator i;
887     // label
888     std::string labelStr;
889     std::string valueStr("");
890
891         if (detail==0) {
892                 labelStr = bbGetName() ; 
893 //EED 18 Fev 2008
894                 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
895         } else {
896                 labelStr = bbGetName();
897                 labelStr = labelStr + "   [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]  ";
898     }
899
900     SubsBrackets(labelStr);
901     if (detail==1)
902       {
903         labelStr = labelStr + " | {{ "; 
904         std::string tempStrTypeName;
905         bool tmp; 
906         tmp=false;
907         for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
908           {
909             if (tmp==true)
910               {
911                 labelStr=labelStr+" | ";
912               }
913             tmp=true;
914             if (instanceOrtype==true)
915               {
916                 valueStr = this->bbGetInputAsString(i->first) + " = ";
917               } 
918             const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
919             tempStrTypeName=id->GetTypeName();
920             SubsBrackets(tempStrTypeName);
921             std::string Name(i->first);
922             SubsBrackets(Name);
923             labelStr=labelStr + "<"+i->first.c_str()+"> "  + valueStr +  Name.c_str() + "  [" + tempStrTypeName.c_str() + "]";
924           }
925         labelStr=labelStr+ " } | {";
926         tmp = false;
927         OutputConnectorMapType::iterator ii;
928         for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii ) 
929         {
930            if (tmp==true)
931            {
932                    labelStr=labelStr+" | ";
933            }
934            tmp = true;
935            if (instanceOrtype==true)
936            {
937                    valueStr = this->bbGetOutputAsString(ii->first) + " = ";
938            }
939            const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first); 
940            tempStrTypeName=id->GetTypeName();
941            SubsBrackets(tempStrTypeName);
942             std::string Name(ii->first);
943             SubsBrackets(Name);
944            labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + "  ["+tempStrTypeName+"]";
945         }
946         labelStr = labelStr+ "      } }" ;
947 } // detail
948
949     fprintf(ff,"  " );
950     bbWriteDotInputOutputName(ff,true,detail,level);
951     std::string tmp ( bbGetTypeName() );
952     SubsBrackets(tmp);
953     std::string url;
954     if (relative_link) 
955       url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
956     else 
957       url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
958   
959     fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
960     //    std::cout  << labelStr << std::endl;
961
962     // Relation Input
963     if (GetThisPointer<BlackBox>()!=parentblackbox){
964       for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
965         {
966           if (i->second)
967             {
968               Connection* con = i->second->GetConnection();
969               if (con!=NULL){
970                 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
971                 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
972                 fprintf(ff,"  ");
973                 a->bbWriteDotInputOutputName(ff,false,detail,level);
974                 if (detail==1)
975                   {
976                     fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
977                   }
978                 fprintf(ff,"->");
979                 b->bbWriteDotInputOutputName(ff,true,detail,level);
980                 if (detail==1)
981                   {
982                     fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
983                   }
984                 fprintf(ff,"%s\n",";");
985               }  // if con
986             } // if second
987         } // for
988     } // if parentblackbox
989   }
990   //=========================================================================
991
992
993
994
995   //=========================================================================
996   void BlackBox::bbShowRelations(BlackBox::Pointer parentblackbox, 
997                                  int detail, int level
998                                  /*,Factory *factory*/ )
999   {
1000      
1001     if (this->bbGetDescriptor()->GetPackage()) 
1002       {
1003         bbtkMessage("Help",1,"Black Box '"<<bbGetName()<<"' <"<<
1004                     this->bbGetDescriptor()->GetPackage()->GetName()
1005                     <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1006       }
1007     else 
1008       {
1009         bbtkMessage("Help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1010       }
1011     //    bbtkMessage("Help",1," "<<GetDescription()<<std::endl);
1012     //    bbtkMessage("Help",1," By : "<<GetAuthor()<<std::endl);
1013
1014     std::vector<std::string> iname;
1015     std::vector<std::string> ivalue;
1016     std::vector<std::string> iconn;
1017
1018     InputConnectorMapType::iterator i;
1019     unsigned int namelmax = 0;
1020     unsigned int valuelmax = 0;
1021     unsigned int connlmax = 0;
1022     for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) 
1023       {
1024         iname.push_back(i->first);
1025         if (iname.back().size()>namelmax) namelmax = iname.back().size();
1026         ivalue.push_back(bbGetInputAsString(i->first));
1027         if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1028         std::string s("");
1029         Connection* con = i->second->GetConnection();
1030         if (con!=0){
1031           s = con->GetOriginalBlackBoxFrom()->bbGetName();
1032           s += ".";
1033           s += con->GetOriginalBlackBoxFromOutput();
1034         }  // if con
1035         iconn.push_back(s);
1036       }
1037     OutputConnectorMapType::iterator o;
1038     std::vector<std::string> oname;
1039     std::vector<std::string> ovalue;
1040     std::vector<std::vector<std::string> > oconn;
1041     for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o ) 
1042       {
1043         oname.push_back(o->first);
1044         if (oname.back().size()>namelmax) namelmax = oname.back().size();
1045         ovalue.push_back(bbGetOutputAsString(o->first));
1046         if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size();
1047         std::vector<std::string> ss;
1048         const std::vector<Connection*>& con 
1049           = o->second->GetConnectionVector();
1050         std::vector<Connection*>::const_iterator c;
1051         for (c=con.begin();c!=con.end();++c) 
1052           {
1053             std::string s;
1054             s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1055             s += ".";
1056             s += (*c)->GetOriginalBlackBoxToInput();
1057             ss.push_back(s);
1058         }  // if con
1059         oconn.push_back(ss);
1060       }
1061
1062     if (iname.size()) 
1063       bbtkMessage("Help",1," * Inputs : "<<std::endl);
1064     else 
1065       bbtkMessage("Help",1," * No inputs"<<std::endl);
1066
1067     std::vector<std::string>::iterator i1,i2,i3;
1068     for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin();
1069          i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end();
1070          ++i1,++i2,++i3)
1071       {
1072         std::string name(*i1);
1073         name += "'";
1074         name.append(1+namelmax-name.size(),' ');
1075         std::string value(*i2);
1076         value += "'";
1077         value.append(1+valuelmax-value.size(),' ');
1078         if (i3->size()) 
1079           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<" <-- '"<<*i3<<"'"<<std::endl);
1080         else 
1081           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<std::endl);
1082       }
1083
1084     if (oname.size()) 
1085       bbtkMessage("Help",1," * Outputs : "<<std::endl);
1086     else 
1087       bbtkMessage("Help",1," * No outputs"<<std::endl);
1088
1089     std::vector<std::vector<std::string> >::iterator i4;
1090
1091     for (i1=oname.begin(),i2=ovalue.begin(),i4=oconn.begin();
1092          i1!=oname.end(),i2!=ovalue.end(),i4!=oconn.end();
1093          ++i1,++i2,++i4)
1094       {
1095         std::string name(*i1);
1096         name += "'";
1097         name.append(1+namelmax-name.size(),' ');
1098         std::string value(*i2);
1099         value += "'";
1100         value.append(1+valuelmax-value.size(),' ');
1101         if (!(*i4).size())
1102           bbtkMessage("Help",1,"    '"<<name<<" = '"<<value<<std::endl);
1103         else 
1104           {
1105             std::string pref = "    '"+name+" = '"+value;
1106             for (i3=i4->begin();i3!=i4->end();++i3)
1107               {
1108                 bbtkMessage("Help",1,pref<<" --> '"<<*i3<<"'"<<std::endl);
1109                 pref.replace(0,pref.size(),pref.size(),' ');
1110               }
1111           }
1112       }
1113
1114    }
1115   //=========================================================================
1116
1117
1118   //=========================================================================
1119    void BlackBox::bbGlobalProcessExecutionList()
1120    {   
1121      bbtkDebugMessageInc("process",3,
1122                          "=> BlackBox::bbGlobalProcessExecutionList()"
1123                          <<std::endl);     
1124      
1125      std::set<BlackBox::Pointer>::iterator i;
1126      for (i=bbmgExecutionList.begin();
1127           i!=bbmgExecutionList.end();
1128           ++i)
1129        {
1130          bbtkDebugMessage("process",4,
1131                           " -> Executing "<<(*i)->bbGetFullName()<<std::endl);
1132          (*i)->bbExecute(true);
1133        }
1134      
1135      bbmgExecutionList.clear();
1136      bbtkDebugMessageDec("process",3,
1137                          "<= BlackBox::bbGlobalProcessExecutionList()"
1138                          <<std::endl);     
1139      
1140      
1141    }
1142   //=========================================================================
1143
1144     bool BlackBox::bbGlobalGetSomeBoxExecuting()
1145         { 
1146                 return bbmgSomeBoxExecuting; 
1147         }
1148
1149     void BlackBox::bbGlobalSetSomeBoxExecuting(bool b) 
1150         { 
1151                 bbmgSomeBoxExecuting = b; 
1152         }
1153
1154     void BlackBox::bbGlobalSetFreezeExecution(bool b) 
1155         { 
1156                 bbmgFreezeExecution = b;
1157         }
1158
1159     bool BlackBox::bbGlobalGetFreezeExecution() 
1160         { 
1161                 return bbmgFreezeExecution; 
1162         }
1163
1164   void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1165         {  
1166                 bbmgExecutionList.insert(b); 
1167         } 
1168
1169
1170    //=========================================================================
1171
1172   //=========================================================================
1173   void BlackBox::Check(bool recursive)
1174   {
1175     bbtkMessage("debug",1,"*** Checking Black Box "<<(void*)this<<" ["<<bbGetFullName()
1176                 <<"] ... OK"<<std::endl);
1177   }
1178   //=========================================================================
1179
1180   void BlackBox::bbUserOnShowWidget(std::string nameInput)
1181   {
1182           bbtk::BlackBoxInputConnector *cc;
1183           cc = this->bbGetInputConnectorMap().find( nameInput.c_str() )->second;
1184           if (cc->GetConnection()!=NULL) 
1185           {
1186                   cc->GetConnection()->GetBlackBoxFrom()->bbUserOnShow();
1187           }
1188   }
1189
1190
1191
1192 }  // EO namespace bbtk
1193
1194 // EOF
1195