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