1 /*=========================================================================
3 Module: $RCSfile: bbtkBlackBox.cxx,v $
5 Date: $Date: 2008/12/03 13:35:22 $
6 Version: $Revision: 1.31 $
7 =========================================================================*/
9 /* ---------------------------------------------------------------------
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 * This software is governed by the CeCILL-B license under French law and
15 * abiding by the rules of distribution of free software. You can use,
16 * modify and/ or redistribute the software under the terms of the CeCILL-B
17 * license as circulated by CEA, CNRS and INRIA at the following URL
18 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
19 * or in the file LICENSE.txt.
21 * As a counterpart to the access to the source code and rights to copy,
22 * modify and redistribute granted by the license, users are provided only
23 * with a limited warranty and the software's author, the holder of the
24 * economic rights, and the successive licensors have only limited
27 * The fact that you are presently reading this means that you have had
28 * knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */
33 * \brief Class bbtk::BlackBox : abstract black-box interface.
35 #include "bbtkBlackBox.h"
36 #include "bbtkPackage.h"
37 #include "bbtkMessageManager.h"
38 #include "bbtkFactory.h"
40 #include "bbtkConfigurationFile.h"
41 #include "bbtkWxBlackBox.h"
51 static bool bbmgSomeBoxExecuting = false;
52 static bool bbmgFreezeExecution = false;
53 static std::set<BlackBox::WeakPointer> bbmgExecutionList;
55 //=========================================================================
56 BlackBox::Deleter::Deleter()
59 //=========================================================================
61 //=========================================================================
62 void BlackBox::Deleter::Delete(Object* p)
64 BlackBox* b = dynamic_cast<BlackBox*>(p);
67 bbtkInternalError("BlackBox::Deleter::Delete("<<p->GetObjectName()
69 <<"dynamic cast to BlackBox* failed !");
71 std::string name = p->GetObjectName();//b->bbGetNameWithParent();
72 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
75 BlackBoxDescriptor::WeakPointer desc = b->bbGetDescriptor();
76 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : deleting black box"<<std::endl);
80 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : releasing descriptor ["<<desc.lock()<<"]"<<std::endl);
84 Package::WeakPointer pack = desc.lock()->GetPackage();
87 Package::ReleaseBlackBoxDescriptor(pack,desc);
91 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor package expired (was not held by a package and the box was the last instance)"<<std::endl);
96 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);
98 bbtkDebugMessage("object",2,"<## BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
100 //=========================================================================
102 //=========================================================================
103 BlackBox::BlackBox(const std::string &name)
108 bbmBoxProcessMode("Pipeline"),
112 bbtkDebugMessage("object",4,"==> BlackBox::BlackBox(\""
113 <<name<<"\")"<<std::endl);
114 bbtkDebugMessage("object",4,"<== BlackBox::BlackBox(\""
115 <<name<<"\")"<<std::endl);
117 //=========================================================================
119 //=========================================================================
120 BlackBox::BlackBox(const BlackBox&)
123 //=========================================================================
124 BlackBox::BlackBox(BlackBox& from, const std::string &name)
126 bbmStatus(from.bbmStatus),
129 bbmBoxProcessMode(from.bbmBoxProcessMode),
133 bbtkDebugMessage("object",4,"==> BlackBox::BlackBox("
134 <<from.bbGetFullName()<<",\""
135 <<name<<"\")"<<std::endl);
136 bbtkDebugMessage("object",4,"<== BlackBox::BlackBox("
137 <<from.bbGetFullName()<<",\""
138 <<name<<"\")"<<std::endl);
140 //=========================================================================
143 //=========================================================================
144 BlackBox::~BlackBox()
146 bbtkDebugMessage("object",4,"==> BlackBox::~BlackBox() ["<<bbmName
148 this->bbDesallocateConnectors();
149 bbtkDebugMessage("object",4,"<== BlackBox::~BlackBox() ["<<bbmName
152 //=========================================================================
155 //=========================================================================
156 /// Main processing method of the box.
157 void BlackBox::bbExecute(bool force)
159 bbtkDebugMessageInc("process",2,
160 "=> BlackBox::bbExecute("<<(int)force<<") ["
161 <<bbGetFullName()<<"]"<<std::endl);
163 // If already executing : return
164 if (bbGetExecuting())
166 bbtkDebugMessage("process",2,
167 " -> already executing : bailing out"<<std::endl);
171 // If execution frozen : return
172 if (bbGlobalGetFreezeExecution())
174 bbtkDebugMessage("process",2,
175 " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
180 // If force is true then update is triggered even if the box is UPTODATE
181 if (force) bbSetModifiedStatus();
183 // Calls the main recursive update method
184 bbBackwardUpdate(Connection::Pointer());
186 bbtkDebugMessageDec("process",2,
187 "<= BlackBox::bbExecute() ["
188 <<bbGetFullName()<<"]"<<std::endl);
190 //=========================================================================
192 //=========================================================================
193 std::string BlackBox::bbGetFullName() const
195 return this->bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
197 //=========================================================================
201 //=========================================================================
202 /// Returns the name with the name of the parent prepended if any
203 std::string BlackBox::bbGetNameWithParent() const
205 if (bbmParent.lock())
207 return bbmParent.lock()->bbGetNameWithParent() + ":" + bbmName;
214 //=========================================================================
216 //=========================================================================
217 /// Prints the Help on the BlackBox type
218 void BlackBox::bbGetHelp(bool full) const
220 bbGetDescriptor()->GetHelp(full);
222 //=========================================================================
225 //=========================================================================
226 /// Returns true if the UserBlackBox has an input of name name
227 bool BlackBox::bbHasInput(const std::string& name) const
229 bbtkDebugMessageInc("Kernel",8,
230 "BlackBox::bbHasInput(\""
231 <<name<<"\") ["<<bbGetFullName()<<"]"
233 bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
234 != bbGetDescriptor()->GetInputDescriptorMap().end());
235 bbtkDebugDecTab("Kernel",8);
238 //=========================================================================
241 //=========================================================================
242 /// Returns true if the UserBlackBox has an output of name name
243 bool BlackBox::bbHasOutput(const std::string& name) const
245 bbtkDebugMessageInc("Kernel",8,"BlackBox::bbHasOutput(\""
246 <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
247 bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
248 != bbGetDescriptor()->GetOutputDescriptorMap().end());
249 bbtkDebugDecTab("Kernel",8);
252 //=========================================================================
255 //=========================================================================
256 /// Gets the output type of a given name
257 TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const
259 bbtkDebugMessageInc("Kernel",8,
260 "BlackBox::bbGetOutputType(\""
261 <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
262 TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
263 bbtkDebugDecTab("Kernel",8);
266 //=========================================================================
268 //=========================================================================
269 /// Gets the input type of a given name
270 TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
272 bbtkDebugMessageInc("Kernel",8,
273 "BlackBox::bbGetInputType(\""
274 <<name<<"\") ["<<bbGetFullName()<<"]"<<std::endl);
275 TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
276 bbtkDebugDecTab("Kernel",8);
279 //=========================================================================
282 //=========================================================================
283 /// Allocates the i/o connectors of the black box
284 void BlackBox::bbAllocateConnectors()
286 bbtkDebugMessageInc("Kernel",8,
287 "BlackBox::bbAllocateConnectors() ["
288 <<bbGetFullName()<<"]"
290 const BlackBoxDescriptor::InputDescriptorMapType& imap
291 = bbGetDescriptor()->GetInputDescriptorMap();
292 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
293 for ( i = imap.begin(); i != imap.end(); ++i )
295 bbtkDebugMessage("Kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
296 bbGetInputConnectorMap()[i->second->GetName()]
297 = new BlackBoxInputConnector(GetThisPointer<BlackBox>());
299 const BlackBoxDescriptor::OutputDescriptorMapType& omap
300 = bbGetDescriptor()->GetOutputDescriptorMap();
301 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
302 for ( o = omap.begin(); o != omap.end(); ++o )
304 bbtkDebugMessage("Kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
305 bbGetOutputConnectorMap()[o->second->GetName()]
306 = new BlackBoxOutputConnector();
308 bbtkDebugDecTab("Kernel",8);
310 //=========================================================================
313 //=========================================================================
314 /// Desallocates the i/o connectors of the black box
315 void BlackBox::bbDesallocateConnectors()
317 bbtkDebugMessageInc("Kernel",8,
318 "BlackBox::bbDesallocateConnectors()"
321 InputConnectorMapType::const_iterator i;
322 for ( i = bbGetInputConnectorMap().begin();
323 i != bbGetInputConnectorMap().end(); ++i )
325 bbtkDebugMessage("Kernel",8,"* Delete \""<<i->first<<"\""<<std::endl);
328 OutputConnectorMapType::const_iterator o;
329 for ( o = bbGetOutputConnectorMap().begin();
330 o != bbGetOutputConnectorMap().end(); ++o )
332 bbtkDebugMessage("Kernel",8,"* Delete \""<<o->first<<"\""<<std::endl);
336 bbtkDebugDecTab("Kernel",8);
339 //=========================================================================
342 //=========================================================================
343 /// Copies the input / output values from another box
344 void BlackBox::bbCopyIOValues(BlackBox& from)
346 bbtkDebugMessageInc("Kernel",1,
347 "BlackBox::bbCopyIOValues("
348 <<from.bbGetFullName()<<") ["
349 <<bbGetFullName()<<"]"<<std::endl);
350 // copies the input values
351 const BlackBoxDescriptor::InputDescriptorMapType& imap
352 = bbGetDescriptor()->GetInputDescriptorMap();
353 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
354 for ( i = imap.begin(); i != imap.end(); ++i )
356 if (! i->second->GetCopyConstruct() ) continue;
357 std::string input = i->second->GetName();
358 bbtkDebugMessage("Kernel",2,"* Copying input "<<input<<std::endl);
359 this->bbSetInput(input, from.bbGetInput(input) );
361 // copies the output values
362 const BlackBoxDescriptor::OutputDescriptorMapType& omap
363 = bbGetDescriptor()->GetOutputDescriptorMap();
364 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
365 for ( o = omap.begin(); o != omap.end(); ++o )
367 if (! o->second->GetCopyConstruct() ) continue;
368 std::string output = o->second->GetName();
369 bbtkDebugMessage("Kernel",2,"* Copying output "<<output<<std::endl);
370 this->bbSetOutput(output, from.bbGetOutput(output) );
373 bbtkDebugDecTab("Kernel",9);
376 //=========================================================================
380 //=========================================================================
381 bool BlackBox::bbCanReact() const
383 return ( bbGlobalGetSomeBoxExecuting()
384 #ifdef _USE_WXWIDGETS_
385 || Wx::IsSomeWindowAlive()
389 //=========================================================================
393 //=========================================================================
394 /// User overloadable destruction method of a black box
395 void BlackBox::bbUserDelete()
397 bbtkDebugMessage("process",5,
398 "=> BlackBox::bbUserDelete() ["
399 <<bbGetFullName()<<"]"
400 <<" : not overloaded; using standard deletion"
404 //=========================================================================
407 //=========================================================================
408 BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
410 const std::string& p = bbmBoxProcessMode;
412 (p == "P") || (p == "p") ||
413 (p == "Pipeline") || (p == "pipeline") ) return Pipeline;
415 (p == "A") || (p == "a") ||
416 (p == "Always") || (p == "always") ) return Always;
418 (p == "R") || (p == "r") ||
419 (p == "Reactive") || (p == "reactive") ) return Reactive;
420 bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
421 <<"' unknown. Possible values : "
422 <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
423 <<"'1'/'A'/'a'/'Always'/'always' | "
424 <<"'2'/'R'/'r'/'Reactive'/'reactive'"<<std::endl);
426 //=========================================================================
428 //=========================================================================
429 bool BlackBox::bbBoxProcessModeIsReactive() const
431 return (bbGetBoxProcessModeValue() == Reactive);
433 //=========================================================================
435 //=========================================================================
436 bool BlackBox::bbBoxProcessModeIsAlways() const
438 return (bbGetBoxProcessModeValue() == Always);
440 //=========================================================================
442 //=========================================================================
443 /// Signals that the BlackBox has been modified
444 void BlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
446 bbtkDebugMessage("modified",1,
447 "==> BlackBox::bbSetModifiedStatus("<<c<<") ["
448 <<bbGetFullName()<<"]"<<std::endl);
450 if ( (c==bbGetInputConnectorMap().find("WinHide")->second) )
451 // && (bbCanReact()))
453 bbtkDebugMessage("modified",2,
454 "-> Hide triggered by WinHide input change"
456 this->bbHideWindow();
457 this->bbSetStatus(MODIFIED);
460 if ( (c==bbGetInputConnectorMap().find("WinClose")->second) )
461 // && (bbCanReact()))
463 bbtkDebugMessage("modified",2,
464 "-> Close triggered by WinClose input change"
466 this->bbHideWindow();
467 this->bbSetStatus(MODIFIED);
471 if ( ( bbBoxProcessModeIsReactive() ||
472 (c==bbGetInputConnectorMap().find("BoxExecute")->second))
475 bbtkDebugMessage("modified",2,
476 "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
477 this->bbSetStatus(MODIFIED);
478 bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
481 else if ( bbGetStatus() == MODIFIED ) //! this->bbIsUptodate())
483 bbtkDebugMessage("modified",2,"-> Already modified"<<std::endl);
489 bbtkDebugMessage("modified",2,"-> Status set to modified"<<std::endl);
490 this->bbSetStatus(MODIFIED);
493 this->bbSignalOutputModification(false);
496 bbtkDebugMessageDec("process",5,
497 "<= BlackBox::bbSetModifiedStatus("<<c<<") ["
498 <<bbGetFullName()<<"]"<<std::endl);
501 //=========================================================================
503 //=========================================================================
504 void BlackBox::bbSignalOutputModification(bool reaction)
506 bbtkDebugMessageInc("process",5,
507 "=> BlackBox::bbSignalOutputModification("
509 <<bbGetFullName()<<"]"<<std::endl);
511 OutputConnectorMapType::iterator change = bbGetOutputConnectorMap().end();
512 OutputConnectorMapType::iterator i;
513 for ( i = bbGetOutputConnectorMap().begin();
514 i != bbGetOutputConnectorMap().end(); ++i) {
515 /* if ( i->first == "BoxChange" )
521 i->second->SetModifiedStatus();
523 // if (change != bbGetOutputConnectorMap().end())
524 // change->second->SetModifiedStatus();
526 if (reaction) bbGlobalProcessExecutionList();
528 bbtkDebugMessageDec("process",5,
529 "<= BlackBox::bbSignalOutputModification() ["
530 <<bbGetFullName()<<"]"<<std::endl);
533 //=========================================================================
534 //=========================================================================
535 void BlackBox::bbSignalOutputModification(const std::string& output,
538 bbtkDebugMessageInc("process",5,
539 "=> BlackBox::bbSignalOutputModification("
540 <<output<<","<<reaction<<") ["
541 <<bbGetFullName()<<"]"<<std::endl);
543 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(output);
544 if ( i == bbGetOutputConnectorMap().end() )
546 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
548 i->second->SetModifiedStatus();
549 // Has to notify the output "BoxChange" also
550 if (output != "BoxChange")
552 i = bbGetOutputConnectorMap().find("BoxChange");
553 if ( i != bbGetOutputConnectorMap().end() )
555 i->second->SetModifiedStatus();
558 if (reaction) bbGlobalProcessExecutionList();
560 bbtkDebugMessageDec("process",5,
561 "<= BlackBox::bbSignalOutputModification("
563 <<bbGetFullName()<<"]"<<std::endl);
566 //=========================================================================
567 //=========================================================================
568 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
571 bbtkDebugMessageInc("process",5,
572 "=> BlackBox::bbSignalOutputModification(vector of outputs) ["
573 <<bbGetFullName()<<"]"<<std::endl);
574 OutputConnectorMapType::iterator i;
575 std::vector<std::string>::const_iterator o;
576 for (o=output.begin();o!=output.end();++o)
578 // the output "BoxChange" must be signaled **AFTER** all others
579 if (*o == "BoxChange") continue;
580 // Look for the connector
581 i = bbGetOutputConnectorMap().find(*o);
582 if ( i == bbGetOutputConnectorMap().end() )
584 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
586 i->second->SetModifiedStatus();
588 // Has to notify the output "BoxChange" also
589 i = bbGetOutputConnectorMap().find("BoxChange");
590 if ( i != bbGetOutputConnectorMap().end() )
592 i->second->SetModifiedStatus();
594 if (reaction) bbGlobalProcessExecutionList();
596 bbtkDebugMessageDec("process",5,
597 "<= BlackBox::bbSignalOutputModification(vector of outputs) ["
598 <<bbGetFullName()<<"]"<<std::endl);
601 //=========================================================================
603 //=========================================================================
604 /// Updates the BlackBox inputs
605 /// \returns UPTODATE if all inputs are in UPTODATE status after update
607 IOStatus BlackBox::bbUpdateInputs(bool excludeParent)
609 bbtkDebugMessageInc("process",4,
610 "=> BlackBox::bbUpdateInputs() ["
611 <<bbGetFullName()<<"]"
614 IOStatus s = UPTODATE;
616 InputConnectorMapType::iterator i;
617 for ( i = bbGetInputConnectorMap().begin();
618 i!= bbGetInputConnectorMap().end(); ++i)
620 if (excludeParent && (i->first=="WinParent")) continue;
621 if (i->first=="WinHide") continue;
622 // If input type is Void : no recurse
623 //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo()
627 IOStatus t = i->second->BackwardUpdate();
628 if (t==MODIFIED) s = MODIFIED;
631 bbtkDebugMessageDec("process",4,
632 "<= BlackBox::bbUpdateInputs() ["
633 <<bbGetFullName()<<"]"
639 //=========================================================================
642 //=========================================================================
643 /// Connects the input <name> to the connection c
644 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
646 bbtkDebugMessage("connection",2,
647 "==> BlackBox::bbConnectInput(\""
648 <<name<<"\","<<c->GetFullName()<<") ["
649 <<bbGetFullName()<<"]"
653 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
654 if (i==bbGetInputConnectorMap().end())
656 bbtkError("no input called '"<<name<<"'");
658 i->second->SetConnection(c);
660 bbtkDebugMessage("connection",2,
661 "<== BlackBox::bbConnectInput(\""
662 <<name<<"\","<<c->GetFullName()<<") ["
663 <<bbGetFullName()<<"]"
665 // bbSetModifiedStatus();
668 //=========================================================================
671 //=========================================================================
672 /// Connects the output <name> to the connection c
673 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
675 bbtkDebugMessage("connection",2,
676 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
677 <<c->GetFullName()<<") ["
678 <<bbGetFullName()<<"]"<<std::endl);
680 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
681 if (i==bbGetOutputConnectorMap().end())
683 bbtkError("no output called '"<<name<<"'");
685 i->second->SetConnection(c);
687 bbtkDebugMessage("connection",2,
688 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
689 <<c->GetFullName()<<") ["
690 <<bbGetFullName()<<"]"<<std::endl);
693 //=========================================================================
696 //=========================================================================
697 /// Disconnects the input <name> from the connection c
698 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
701 bbtkDebugMessage("connection",2,
702 "==> BlackBox::bbDisconnectInput(\""<<name
703 <<"\","<<c->GetFullName()<<") ["
704 <<bbGetFullName()<<"]"
710 bbtkDebugMessage("connection",2,"c==0"<<std::endl);
714 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
715 if (i==bbGetInputConnectorMap().end())
717 bbtkError("no input called '"<<name<<"'");
719 i->second->UnsetConnection(c);
721 bbtkDebugMessage("connection",2,
722 "<== BlackBox::bbDisconnectInput(\""<<name
723 <<"\","<<c->GetFullName()<<") ["
724 <<bbGetFullName()<<"]"
728 //=========================================================================
731 //=========================================================================
732 /// Disconnects the output <name> from the connection c
733 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
735 bbtkDebugMessage("connection",2,
736 "==> BlackBox::bbDisconnectOutput(\""<<name
737 <<"\","<<c->GetFullName()<<") ["
738 <<bbGetFullName()<<"]"
743 bbtkDebugMessage("connection",2,"c==0"<<std::endl);
747 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
748 if (i==bbGetOutputConnectorMap().end())
750 bbtkError("no output called '"<<name<<"'");
752 i->second->UnsetConnection(c);
754 bbtkDebugMessage("connection",2,
755 "<== BlackBox::bbDisconnectOutput(\""<<name
756 <<"\","<<c->GetFullName()<<") ["
757 <<bbGetFullName()<<"]"
760 //=========================================================================
763 //=========================================================================
765 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
767 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
769 //=========================================================================
772 //=========================================================================
773 std::string BlackBox::bbGetOutputAsString( const std::string &output )
776 // Looks for the adaptor
777 if (bbGetOutputType(output).name() != typeid(std::string).name() )
780 Package::Pointer p = bbGetDescriptor()->GetPackage();
781 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
783 Factory::Pointer f = p->GetFactorySet().begin()->lock();
788 bbGetOutputType(output),
791 } catch (bbtk::Exception e)
796 a->bbSetInput("In",bbGetOutput(output));
798 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
800 v="? (no adaptor found)";
805 v="? (no factory found)";
811 v = bbGetOutput(output).unsafe_get<std::string>() ;
815 //=========================================================================
817 //=========================================================================
818 std::string BlackBox::bbGetInputAsString( const std::string &input )
821 // Looks for the adaptor
822 if (bbGetInputType(input) != typeid(std::string))
825 Package::Pointer p = bbGetDescriptor()->GetPackage();
826 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
828 Factory::Pointer f = p->GetFactorySet().begin()->lock();
833 bbGetInputType(input),
836 }catch (bbtk::Exception e)
842 a->bbSetInput("In",bbGetInput(input));
844 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
848 v="? (no adaptor found)";
853 v="? (no factory found)";
858 v = bbGetInput(input).unsafe_get<std::string>() ;
862 //=======================================================================
864 //=======================================================================
865 // Replaces substrings "<" by "["
866 void SubsBrackets ( std::string& s )
868 // std::cout << "BEFORE=["<<s<<"]"<<std::endl;
870 std::string::size_type pos = 0;
873 while ( pos != std::string::npos )
875 // std::cout << "*** find one "<<std::endl;
876 s.replace(pos,1,cr,1);
877 pos = s.find(ss, pos);
883 while ( pos != std::string::npos )
885 // std::cout << "*** find one "<<std::endl;
886 s.replace(pos,1,cr,1);
887 pos = s.find(ss, pos);
893 while ( pos != std::string::npos )
895 // std::cout << "*** find one "<<std::endl;
896 s.replace(pos,1,cr,1);
897 pos = s.find(ss, pos);
898 } // std::cout << "AFTER=["<<s<<"]"<<std::endl;
900 //=======================================================================
902 //=========================================================================
903 /// Write Graphviz-dot description in file
904 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
905 BlackBox::Pointer parentblackbox,
906 int detail, int level,
911 InputConnectorMapType::iterator i;
913 std::string labelStr;
914 std::string valueStr("");
917 labelStr = bbGetName() ;
919 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
921 labelStr = bbGetName();
922 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
925 SubsBrackets(labelStr);
928 labelStr = labelStr + " | {{ ";
929 std::string tempStrTypeName;
932 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
936 labelStr=labelStr+" | ";
939 if (instanceOrtype==true)
941 valueStr = this->bbGetInputAsString(i->first) + " = ";
943 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
944 tempStrTypeName=id->GetTypeName();
945 SubsBrackets(tempStrTypeName);
946 std::string Name(i->first);
948 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
950 labelStr=labelStr+ " } | {";
952 OutputConnectorMapType::iterator ii;
953 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
957 labelStr=labelStr+" | ";
960 if (instanceOrtype==true)
962 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
964 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
965 tempStrTypeName=id->GetTypeName();
966 SubsBrackets(tempStrTypeName);
967 std::string Name(ii->first);
969 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
971 labelStr = labelStr+ " } }" ;
975 bbWriteDotInputOutputName(ff,true,detail,level);
976 std::string tmp ( bbGetTypeName() );
980 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
982 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
984 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
985 // std::cout << labelStr << std::endl;
988 if (GetThisPointer<BlackBox>()!=parentblackbox){
989 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
993 Connection* con = i->second->GetConnection();
995 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
996 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
998 a->bbWriteDotInputOutputName(ff,false,detail,level);
1001 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1004 b->bbWriteDotInputOutputName(ff,true,detail,level);
1007 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1009 fprintf(ff,"%s\n",";");
1013 } // if parentblackbox
1015 //=========================================================================
1020 //=========================================================================
1021 void BlackBox::bbShowRelations(BlackBox::Pointer parentblackbox,
1022 int detail, int level
1023 /*,Factory *factory*/ )
1026 if (this->bbGetDescriptor()->GetPackage())
1028 bbtkMessage("Help",1,"Black Box '"<<bbGetName()<<"' <"<<
1029 this->bbGetDescriptor()->GetPackage()->GetName()
1030 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1034 bbtkMessage("Help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1036 // bbtkMessage("Help",1," "<<GetDescription()<<std::endl);
1037 // bbtkMessage("Help",1," By : "<<GetAuthor()<<std::endl);
1039 std::vector<std::string> iname;
1040 std::vector<std::string> ivalue;
1041 std::vector<std::string> iconn;
1043 InputConnectorMapType::iterator i;
1044 unsigned int namelmax = 0;
1045 unsigned int valuelmax = 0;
1046 // unsigned int connlmax = 0;
1047 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1049 iname.push_back(i->first);
1050 if (iname.back().size()>namelmax) namelmax = iname.back().size();
1051 ivalue.push_back(bbGetInputAsString(i->first));
1052 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1054 Connection* con = i->second->GetConnection();
1056 s = con->GetOriginalBlackBoxFrom()->bbGetName();
1058 s += con->GetOriginalBlackBoxFromOutput();
1062 OutputConnectorMapType::iterator o;
1063 std::vector<std::string> oname;
1064 std::vector<std::string> ovalue;
1065 std::vector<std::vector<std::string> > oconn;
1066 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
1068 oname.push_back(o->first);
1069 if (oname.back().size()>namelmax) namelmax = oname.back().size();
1070 ovalue.push_back(bbGetOutputAsString(o->first));
1071 if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size();
1072 std::vector<std::string> ss;
1073 const std::vector<Connection*>& con
1074 = o->second->GetConnectionVector();
1075 std::vector<Connection*>::const_iterator c;
1076 for (c=con.begin();c!=con.end();++c)
1079 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1081 s += (*c)->GetOriginalBlackBoxToInput();
1084 oconn.push_back(ss);
1088 bbtkMessage("Help",1," * Inputs : "<<std::endl);
1090 bbtkMessage("Help",1," * No inputs"<<std::endl);
1092 std::vector<std::string>::iterator i1,i2,i3;
1093 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin();
1094 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end();
1097 std::string name(*i1);
1099 name.append(1+namelmax-name.size(),' ');
1100 std::string value(*i2);
1102 value.append(1+valuelmax-value.size(),' ');
1104 bbtkMessage("Help",1," '"<<name<<" = '"<<value<<" <-- '"<<*i3<<"'"<<std::endl);
1106 bbtkMessage("Help",1," '"<<name<<" = '"<<value<<std::endl);
1110 bbtkMessage("Help",1," * Outputs : "<<std::endl);
1112 bbtkMessage("Help",1," * No outputs"<<std::endl);
1114 std::vector<std::vector<std::string> >::iterator i4;
1116 for (i1=oname.begin(),i2=ovalue.begin(),i4=oconn.begin();
1117 i1!=oname.end(),i2!=ovalue.end(),i4!=oconn.end();
1120 std::string name(*i1);
1122 name.append(1+namelmax-name.size(),' ');
1123 std::string value(*i2);
1125 value.append(1+valuelmax-value.size(),' ');
1127 bbtkMessage("Help",1," '"<<name<<" = '"<<value<<std::endl);
1130 std::string pref = " '"+name+" = '"+value;
1131 for (i3=i4->begin();i3!=i4->end();++i3)
1133 bbtkMessage("Help",1,pref<<" --> '"<<*i3<<"'"<<std::endl);
1134 pref.replace(0,pref.size(),pref.size(),' ');
1140 //=========================================================================
1142 static bool bbmgGlobalProcessingExecutionList = false;
1144 //=========================================================================
1145 void BlackBox::bbGlobalProcessExecutionList()
1147 bbtkDebugMessageInc("process",3,
1148 "=> BlackBox::bbGlobalProcessExecutionList()"
1150 if (bbmgGlobalProcessingExecutionList)
1152 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1155 bbmgGlobalProcessingExecutionList = true;
1157 std::set<BlackBox::WeakPointer>::iterator i;
1158 while (bbmgExecutionList.size()>0)
1160 i = bbmgExecutionList.begin();
1161 BlackBox::WeakPointer p = *i;
1162 bbmgExecutionList.erase(i);
1165 bbtkDebugMessage("process",4,
1167 p.lock()->bbGetFullName()<<std::endl);
1168 p.lock()->bbExecute(true);
1172 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1176 bbmgExecutionList.clear();
1177 bbtkDebugMessageDec("process",3,
1178 "<= BlackBox::bbGlobalProcessExecutionList()"
1181 bbmgGlobalProcessingExecutionList = false;
1184 //=========================================================================
1186 bool BlackBox::bbGlobalGetSomeBoxExecuting()
1188 return bbmgSomeBoxExecuting;
1191 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
1193 bbmgSomeBoxExecuting = b;
1196 void BlackBox::bbGlobalSetFreezeExecution(bool b)
1198 bbmgFreezeExecution = b;
1201 bool BlackBox::bbGlobalGetFreezeExecution()
1203 return bbmgFreezeExecution;
1206 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1208 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetFullName()<<")"<<std::endl);
1209 if (bbmgGlobalProcessingExecutionList)
1211 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1213 bbmgExecutionList.insert(b);
1217 //=========================================================================
1219 //=========================================================================
1220 void BlackBox::Check(bool recursive)
1222 bbtkMessage("debug",1,"*** Checking Black Box "<<(void*)this<<" ["<<bbGetFullName()
1223 <<"] ... OK"<<std::endl);
1225 //=========================================================================
1227 void BlackBox::bbUserOnShowWidget(std::string nameInput)
1229 bbtk::BlackBoxInputConnector *cc;
1230 cc = this->bbGetInputConnectorMap().find( nameInput.c_str() )->second;
1231 if (cc->GetConnection()!=NULL)
1233 cc->GetConnection()->GetBlackBoxFrom()->bbUserOnShow();
1239 } // EO namespace bbtk