1 /*=========================================================================
3 Module: $RCSfile: bbtkBlackBox.cxx,v $
5 Date: $Date: 2011/07/22 17:42:50 $
6 Version: $Revision: 1.54 $
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"
39 #include "bbtkBlackBoxOutputConnector.h"
41 #include "bbtkConfigurationFile.h"
42 #include "bbtkWxBlackBox.h"
51 static bool bbmgSomeBoxExecuting = false;
52 static bool bbmgFreezeExecution = false;
53 static std::set<BlackBox::WeakPointer> bbmgExecutionList;
55 //=========================================================================
57 BlackBox::Deleter::Deleter()
60 //=========================================================================
62 //=========================================================================
63 int BlackBox::Deleter::Delete(Object* p)
65 BlackBox* b = dynamic_cast<BlackBox*>(p);
68 bbtkInternalError("BlackBox::Deleter::Delete("<<p->GetObjectName()
70 <<"dynamic cast to BlackBox* failed !");
72 std::string name = p->GetObjectName();//b->bbGetNameWithParent();
73 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
76 BlackBoxDescriptor::WeakPointer desc = b->bbGetDescriptor();
77 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : deleting black box"<<std::endl);
79 int refs = b->bbDelete();
81 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : releasing descriptor"<<std::endl);
85 Package::WeakPointer pack = desc.lock()->GetPackage();
88 Package::ReleaseBlackBoxDescriptor(pack,desc);
92 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor package expired (was not held by a package and the box was the last instance)"<<std::endl);
97 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);
99 bbtkDebugMessage("object",2,"<## BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
102 //=========================================================================
104 //=========================================================================
105 BlackBox::BlackBox(const std::string &name)
107 // bbmStatus(MODIFIED),
108 bbmInitialized(false),
111 bbmBoxProcessMode("Pipeline"),
116 // bbmBoxProcessMode = "Pipeline";
117 //std::cout<<"JCP BlackBox::BlackBox(const std::string &name) name=" <<name
118 // <<"bbmBoxProcessMode="<<bbmBoxProcessMode<<std::endl;
119 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox(\""
120 <<name<<"\")"<<std::endl);
121 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox(\""
122 <<name<<"\")"<<std::endl);
124 //=========================================================================
126 //=========================================================================
127 BlackBox::BlackBox(const BlackBox&)
130 //=========================================================================
131 BlackBox::BlackBox(BlackBox& from, const std::string &name)
133 // bbmStatus(from.bbmStatus),
134 bbmInitialized(false),
137 bbmBoxProcessMode(from.bbmBoxProcessMode),
142 //bbmBoxProcessMode = from.bbmBoxProcessMode;
143 //std::cout<<"JCP BlackBox::BlackBox(const std::string &name) name=" <<name
144 // <<"bbmBoxProcessMode="<<bbmBoxProcessMode<<std::endl;
145 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox("
146 <<from.bbGetFullName()<<",\""
147 <<name<<"\")"<<std::endl);
148 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox("
149 <<from.bbGetFullName()<<",\""
150 <<name<<"\")"<<std::endl);
152 //=========================================================================
155 //=========================================================================
156 BlackBox::~BlackBox()
158 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::~BlackBox() ["<<bbmName
160 this->bbDesallocateConnectors();
161 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::~BlackBox() ["<<bbmName
164 //=========================================================================
168 //=========================================================================
169 std::string BlackBox::bbGetFullName() const
171 return this->bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
173 //=========================================================================
177 //=========================================================================
178 std::string BlackBox::bbGetNameWithParent() const
180 if (bbmParent.lock())
182 return bbmParent.lock()->bbGetNameWithParent() + ":" + bbmName;
189 //=========================================================================
191 //=========================================================================
192 void BlackBox::bbGetHelp(bool full) const
194 bbGetDescriptor()->GetHelp(full);
196 //=========================================================================
199 //=========================================================================
200 bool BlackBox::bbHasInput(const std::string& name) const
202 bbtkBlackBoxDebugMessage("kernel",8,
203 "BlackBox::bbHasInput(\""
206 bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
207 != bbGetDescriptor()->GetInputDescriptorMap().end());
208 bbtkDebugDecTab("kernel",8);
211 //=========================================================================
214 //=========================================================================
215 bool BlackBox::bbHasOutput(const std::string& name) const
217 bbtkBlackBoxDebugMessage("kernel",8,"BlackBox::bbHasOutput(\""
220 bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
221 != bbGetDescriptor()->GetOutputDescriptorMap().end());
222 bbtkDebugDecTab("kernel",8);
225 //=========================================================================
228 //=========================================================================
229 TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const
231 bbtkBlackBoxDebugMessage("kernel",8,
232 "BlackBox::bbGetOutputType(\""
235 TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
236 bbtkDebugDecTab("kernel",8);
239 //=========================================================================
241 //=========================================================================
242 TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
244 bbtkBlackBoxDebugMessage("kernel",8,
245 "BlackBox::bbGetInputType(\""
248 TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
249 bbtkDebugDecTab("kernel",8);
252 //=========================================================================
255 //=========================================================================
256 void BlackBox::bbAllocateConnectors()
258 bbtkBlackBoxDebugMessage("kernel",8,
259 "BlackBox::bbAllocateConnectors()"
262 MakeBlackBoxPointer(this,true);
264 const BlackBoxDescriptor::InputDescriptorMapType& imap
265 = bbGetDescriptor()->GetInputDescriptorMap();
266 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
267 for ( i = imap.begin(); i != imap.end(); ++i )
269 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
270 bbGetInputConnectorMap()[i->second->GetName()]
271 = new BlackBoxInputConnector(GetThisPointer<BlackBox>());
273 const BlackBoxDescriptor::OutputDescriptorMapType& omap
274 = bbGetDescriptor()->GetOutputDescriptorMap();
275 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
276 for ( o = omap.begin(); o != omap.end(); ++o )
278 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
279 bbGetOutputConnectorMap()[o->second->GetName()]
280 = new BlackBoxOutputConnector(GetThisPointer<BlackBox>());
283 //=========================================================================
286 //=========================================================================
287 void BlackBox::bbDesallocateConnectors()
289 bbtkBlackBoxDebugMessage("kernel",8,
290 "BlackBox::bbDesallocateConnectors()"
293 InputConnectorMapType::const_iterator i;
294 for ( i = bbGetInputConnectorMap().begin();
295 i != bbGetInputConnectorMap().end(); ++i )
297 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<i->first<<"\""<<std::endl);
300 OutputConnectorMapType::const_iterator o;
301 for ( o = bbGetOutputConnectorMap().begin();
302 o != bbGetOutputConnectorMap().end(); ++o )
304 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<o->first<<"\""<<std::endl);
308 bbtkDebugDecTab("kernel",8);
310 //=========================================================================
313 //=========================================================================
314 void BlackBox::bbCopyIOValues(BlackBox& from)
316 bbtkBlackBoxDebugMessage("kernel",1,
317 "BlackBox::bbCopyIOValues("
318 <<from.bbGetFullName()<<")"
320 // copies the input values
321 const BlackBoxDescriptor::InputDescriptorMapType& imap
322 = bbGetDescriptor()->GetInputDescriptorMap();
323 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
324 for ( i = imap.begin(); i != imap.end(); ++i )
326 if (! i->second->GetCopyConstruct() ) continue;
327 std::string input = i->second->GetName();
328 bbtkBlackBoxDebugMessage("kernel",2,"* Copying input "<<input<<std::endl);
329 this->bbSetInput(input, from.bbGetInput(input) );
331 // copies the output values
332 const BlackBoxDescriptor::OutputDescriptorMapType& omap
333 = bbGetDescriptor()->GetOutputDescriptorMap();
334 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
335 for ( o = omap.begin(); o != omap.end(); ++o )
337 if (! o->second->GetCopyConstruct() ) continue;
338 std::string output = o->second->GetName();
339 bbtkBlackBoxDebugMessage("kernel",2,"* Copying output "<<output<<std::endl);
340 this->bbSetOutput(output, from.bbGetOutput(output) );
343 bbtkDebugDecTab("kernel",9);
345 //=========================================================================
349 //=========================================================================
350 bool BlackBox::bbCanReact() const
352 return ( bbGlobalGetSomeBoxExecuting()
354 || Wx::IsSomeWindowAlive()
358 //=========================================================================
362 //=========================================================================
363 BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
365 const std::string& p = bbmBoxProcessMode;
367 (p == "P") || (p == "p") ||
368 (p == "Pipeline") || (p == "pipeline") ) return bbPipeline;
370 (p == "A") || (p == "a") ||
371 (p == "Always") || (p == "always") ) return bbAlways;
373 (p == "R") || (p == "r") ||
374 (p == "Reactive") || (p == "reactive") )
378 (p == "F") || (p == "f") ||
379 (p == "Flash") || (p == "flash") ) return Flash;
381 bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
382 <<"' unknown. Possible values : "
383 <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
384 <<"'1'/'A'/'a'/'Always'/'always' | "
385 <<"'2'/'R'/'r'/'Reactive'/'reactive'"
386 // <<"'3'/'F'/'f'/'Flash'/'flash'"
389 //=========================================================================
391 //=========================================================================
392 bool BlackBox::bbBoxProcessModeIsReactive() const
394 return (bbGetBoxProcessModeValue() == bbReactive);
396 //=========================================================================
398 //=========================================================================
399 bool BlackBox::bbBoxProcessModeIsAlways() const
401 return (bbGetBoxProcessModeValue() == bbAlways);
403 //=========================================================================
408 //=========================================================================
409 void BlackBox::bbAddOutputObserver(const std::string& output,
410 OutputChangeCallbackType f)
412 bbGetOutputConnector(output).AddChangeObserver(f);
414 //=========================================================================
416 //=========================================================================
417 void BlackBox::bbRemoveOutputObserver(const std::string& output_name,
418 OutputChangeCallbackType f)
420 bbtkError("BlackBox::RemoveChangeObserver NOT IMPLEMENTED");
422 //=========================================================================
425 //=========================================================================
426 void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
429 bbtkBlackBoxDebugMessage("change",5,
430 "=> BlackBox::bbSetStatusAndPropagate(input,"
431 <<GetIOStatusString(s)<<")"
434 if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
439 if (bbGetBoxProcessModeValue() == Flash)
445 OutputConnectorMapType::const_iterator o;
446 for ( o = bbGetOutputConnectorMap().begin();
447 o != bbGetOutputConnectorMap().end(); ++o )
449 if (o->second->GetStatus()==UPTODATE)
451 o->second->SetStatus(OUTOFDATE);
452 o->second->SignalChange(GetThisPointer<BlackBox>(),o->first);
456 if ( ( bbBoxProcessModeIsReactive()
457 || (c==bbGetInputConnectorMap().find("BoxExecute")->second))
460 bbtkBlackBoxDebugMessage("change",2,
461 "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
462 bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
464 bbtkBlackBoxDebugMessage("change",5,
465 "<= BlackBox::bbSetStatusAndPropagate(input)"
468 //=========================================================================
471 //=========================================================================
472 void BlackBox::bbSignalOutputModification(bool reaction)
474 bbtkBlackBoxDebugMessage("change",5,
475 "=> BlackBox::bbSignalOutputModification("
479 OutputConnectorMapType::iterator i;
480 for ( i = bbGetOutputConnectorMap().begin();
481 i != bbGetOutputConnectorMap().end(); ++i)
483 // std::cout << "Stat = "
484 //<<GetIOStatusString(i->second->GetStatus())
486 // LG : CANNOT SIGNAL ONLY WHEN UPTODATE
487 // See bbtkSampleOutputObserver
488 // if (i->second->GetStatus()==UPTODATE)
490 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
494 if (reaction) bbGlobalProcessExecutionList();
496 bbtkBlackBoxDebugMessage("change",5,
497 "<= BlackBox::bbSignalOutputModification()"
500 //=========================================================================
503 //=========================================================================
504 void BlackBox::bbSignalOutputModification(const std::string& output,
507 bbtkBlackBoxDebugMessage("change",5,
508 "=> BlackBox::bbSignalOutputModification("
509 <<output<<","<<reaction<<")"
512 OutputConnectorMapType::iterator i =
513 bbGetOutputConnectorMap().find(output);
516 if ( i == bbGetOutputConnectorMap().end() )
518 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
521 // if (i->second->GetStatus()==UPTODATE)
523 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
524 // Has to notify the output "BoxChange" also
525 if (output != "BoxChange")
527 i = bbGetOutputConnectorMap().find("BoxChange");
528 if ( i != bbGetOutputConnectorMap().end() )
530 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
533 if (reaction) bbGlobalProcessExecutionList();
536 bbtkBlackBoxDebugMessage("change",5,
537 "<= BlackBox::bbSignalOutputModification("
541 //=========================================================================
542 //=========================================================================
543 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
546 bbtkBlackBoxDebugMessage("change",5,
547 "=> BlackBox::bbSignalOutputModification(vector of outputs)"
549 OutputConnectorMapType::iterator i;
550 std::vector<std::string>::const_iterator o;
551 bool changed = false;
552 for (o=output.begin();o!=output.end();++o)
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() )
560 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
563 // if (i->second->GetStatus()==UPTODATE)
565 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
569 // Has to notify the output "BoxChange" also
570 i = bbGetOutputConnectorMap().find("BoxChange");
571 if ( changed && (i != bbGetOutputConnectorMap().end()))
573 // if (i->second->GetStatus()==UPTODATE)
575 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
576 if (reaction) bbGlobalProcessExecutionList();
580 bbtkBlackBoxDebugMessage("change",5,
581 "<= BlackBox::bbSignalOutputModification(vector of outputs)"
584 //=========================================================================
592 //=========================================================================
593 /// Main processing method of the box.
594 void BlackBox::bbExecute(bool force)
596 bbtkBlackBoxDebugMessage("process",2,
597 "=> BlackBox::bbExecute("<<(int)force<<")"
600 // If already executing : return
602 if (bbGetExecuting())
604 bbtkBlackBoxDebugMessage("process",2,
605 " -> already executing : abort"<<std::endl);
610 // If execution frozen : return
611 if (bbGlobalGetFreezeExecution())
613 bbtkBlackBoxDebugMessage("process",2,
614 " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
619 // If force is true then update is triggered even if the box is UPTODATE
620 // if (force) bbSetModifiedStatus();
622 // Calls the main recursive execution method
623 bbRecursiveExecute(Connection::Pointer());
625 bbtkBlackBoxDebugMessage("process",2,
626 "<= BlackBox::bbExecute()"
629 //=========================================================================
631 //=========================================================================
632 void BlackBox::bbInitializeProcessing()
636 bbtkBlackBoxDebugMessage("process",2,"** Initialize processing"
638 this->bbRecursiveInitializeProcessing();
639 bbmInitialized = true;
642 //=========================================================================
644 //=========================================================================
645 void BlackBox::bbFinalizeProcessing()
649 bbtkBlackBoxDebugMessage("process",2,"** Finalize processing"
651 this->bbRecursiveFinalizeProcessing();
652 bbmInitialized = false;
655 //=========================================================================
658 //=========================================================================
659 void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
661 bbtkBlackBoxDebugMessage("process",3,
662 "=> BlackBox::bbRecursiveExecute("
663 <<(caller?caller->GetFullName():"0")<<")"
666 // If already executing : return
667 if (bbGetExecuting())
669 bbtkBlackBoxDebugMessage("process",3,
670 " -> already executing : abort"<<std::endl);
674 // If not initialized do it
675 bbInitializeProcessing();
677 bbSetExecuting(true);
678 bool wasExecuting = bbGlobalGetSomeBoxExecuting();
679 bbGlobalSetSomeBoxExecuting(true);
681 // Creates the window if the black box has one
682 this->bbCreateWindow();
684 // Updates its inputs
685 IOStatus s = bbUpdateInputs();
687 if ( (s != UPTODATE) ||
688 bbBoxProcessModeIsAlways() )
690 // Displays the window (WxBlackbox)
691 // bbShowWindow(caller);
693 // Actual processing (virtual)
697 // Update the I/O statuses
698 bbComputePostProcessStatus();
702 // Test output status...
703 OutputConnectorMapType::iterator o;
704 for ( o = bbGetOutputConnectorMap().begin();
705 o!= bbGetOutputConnectorMap().end(); ++o)
707 if (o->second->GetStatus() != UPTODATE)
709 bbtkWarning("BlackBox::bbRecursiveExecute: "
710 <<"all inputs are Up-to-date but output '"
711 <<o->first<<"' is Out-of-date ???");
715 bbtkBlackBoxDebugMessage("process",3," -> Up-to-date : nothing to do"
719 // Shows the window if the black box has one
720 this->bbShowWindow();
723 bbtkBlackBoxDebugMessage("process",3,
724 "<= BlackBox::bbRecursiveExecute()"
727 bbSetExecuting(false);
728 bbGlobalSetSomeBoxExecuting(wasExecuting);
732 //=========================================================================
738 //=========================================================================
739 IOStatus BlackBox::bbUpdateInputs()
741 bbtkBlackBoxDebugMessage("process",4,
742 "=> BlackBox::bbUpdateInputs()"
745 IOStatus s = UPTODATE;
747 InputConnectorMapType::iterator i;
748 for ( i = bbGetInputConnectorMap().begin();
749 i!= bbGetInputConnectorMap().end(); ++i)
751 // if (i->first=="WinHide") continue;
752 // If input type is Void : no recurse
753 //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo()
756 bbtkBlackBoxDebugMessage("change",2,
758 <<"': status before update = '"
759 <<GetIOStatusString(i->second->GetStatus())
761 i->second->RecursiveExecute();
762 IOStatus t = i->second->GetStatus();
764 bbtkBlackBoxDebugMessage("change",2,
766 <<"': status before process = '"
767 <<GetIOStatusString(i->second->GetStatus())
771 bbtkBlackBoxDebugMessage("process",4,
772 "<= BlackBox::bbUpdateInputs()"
776 //=========================================================================
778 //==================================================================
779 void BlackBox::bbComputePostProcessStatus()
781 bbtkBlackBoxDebugMessage("process",4,
782 "=> BlackBox::bbComputePostProcessStatus()"
785 IOStatus new_output_status = UPTODATE;
786 if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
788 // Update the input statuses
789 InputConnectorMapType::iterator i;
790 for ( i = bbGetInputConnectorMap().begin();
791 i!= bbGetInputConnectorMap().end(); ++i)
793 IOStatus t = i->second->GetStatus();
794 if (t == OUTOFDATE) new_output_status = OUTOFDATE;
795 // A previously MODIFIED status turns to UPTODATE
796 if (t==MODIFIED) i->second->SetStatus(UPTODATE);
797 bbtkBlackBoxDebugMessage("change",2,
798 "Input '"<<i->first<<"' : "
799 << GetIOStatusString(t) << " -> "
800 << GetIOStatusString(i->second->GetStatus())
803 bbtkBlackBoxDebugMessage("change",2,
804 "New output status : "
805 << GetIOStatusString(new_output_status)
807 // Update the output statuses
808 OutputConnectorMapType::iterator o;
809 for ( o = bbGetOutputConnectorMap().begin();
810 o!= bbGetOutputConnectorMap().end(); ++o)
812 o->second->SetStatus(new_output_status);
815 bbtkBlackBoxDebugMessage("process",4,
816 "<= BlackBox::bbComputePostProcessStatus()"
819 //==================================================================
821 //=========================================================================
822 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
824 bbtkBlackBoxDebugMessage("connection",2,
825 "==> BlackBox::bbConnectInput(\""
826 <<name<<"\","<<c->GetFullName()<<")"
829 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
830 if (i==bbGetInputConnectorMap().end())
832 bbtkError("no input called '"<<name<<"'");
834 i->second->SetConnection(c);
835 // The input *MUST* be set OUTOFDATE to update its input on next execution
836 bbSetStatusAndPropagate(i->second,OUTOFDATE);
838 bbtkBlackBoxDebugMessage("connection",2,
839 "<== BlackBox::bbConnectInput(\""
840 <<name<<"\","<<c->GetFullName()<<")"
843 //=========================================================================
846 //=========================================================================
847 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
849 bbtkBlackBoxDebugMessage("connection",2,
850 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
851 <<c->GetFullName()<<")"
854 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
855 if (i==bbGetOutputConnectorMap().end())
857 bbtkError("no output called '"<<name<<"'");
859 i->second->SetConnection(c);
861 bbtkBlackBoxDebugMessage("connection",2,
862 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
863 <<c->GetFullName()<<")"
866 //=========================================================================
869 //=========================================================================
870 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
873 bbtkBlackBoxDebugMessage("connection",2,
874 "==> BlackBox::bbDisconnectInput(\""<<name
875 <<"\","<<c->GetFullName()<<")"
880 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
884 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
885 if (i==bbGetInputConnectorMap().end())
887 bbtkError("no input called '"<<name<<"'");
889 i->second->UnsetConnection(c);
891 bbtkBlackBoxDebugMessage("connection",2,
892 "<== BlackBox::bbDisconnectInput(\""<<name
893 <<"\","<<c->GetFullName()<<")"
897 //=========================================================================
900 //=========================================================================
901 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
903 bbtkBlackBoxDebugMessage("connection",2,
904 "==> BlackBox::bbDisconnectOutput(\""<<name
905 <<"\","<<c->GetFullName()<<")"
910 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
914 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
915 if (i==bbGetOutputConnectorMap().end())
917 bbtkError("no output called '"<<name<<"'");
919 i->second->UnsetConnection(c);
921 bbtkBlackBoxDebugMessage("connection",2,
922 "<== BlackBox::bbDisconnectOutput(\""<<name
923 <<"\","<<c->GetFullName()<<")"
926 //=========================================================================
950 //=========================================================================
951 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
953 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
955 //=========================================================================
958 //=========================================================================
959 std::string BlackBox::bbGetOutputAsString( const std::string &output )
962 // Looks for the adaptor
963 if (bbGetOutputType(output).name() != typeid(std::string).name() )
966 Package::Pointer p = bbGetDescriptor()->GetPackage();
967 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
969 Factory::Pointer f = p->GetFactorySet().begin()->lock();
974 bbGetOutputType(output),
977 } catch (bbtk::Exception e)
982 a->bbSetInput("In",bbGetOutput(output));
984 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
986 v="? (no adaptor found)";
991 v="? (no factory found)";
997 v = bbGetOutput(output).unsafe_get<std::string>() ;
1001 //=========================================================================
1003 //=========================================================================
1004 std::string BlackBox::bbGetInputAsString( const std::string &input )
1007 // Looks for the adaptor
1008 if (bbGetInputType(input) != typeid(std::string))
1011 Package::Pointer p = bbGetDescriptor()->GetPackage();
1012 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1014 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1015 BlackBox::Pointer a;
1019 bbGetInputType(input),
1020 typeid(std::string),
1022 }catch (bbtk::Exception e)
1028 a->bbSetInput("In",bbGetInput(input));
1030 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1034 v="? (no adaptor found)";
1039 v="? (no factory found)";
1044 v = bbGetInput(input).unsafe_get<std::string>() ;
1048 //=======================================================================
1050 //=======================================================================
1051 // Replaces substrings "<" by "["
1052 void SubsBrackets ( std::string& s )
1054 // std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1055 std::string ss("<");
1056 std::string::size_type pos = 0;
1058 std::string cr("[");
1059 while ( pos != std::string::npos )
1061 // std::cout << "*** find one "<<std::endl;
1062 s.replace(pos,1,cr.c_str(),1);
1063 pos = s.find(ss, pos);
1069 while ( pos != std::string::npos )
1071 // std::cout << "*** find one "<<std::endl;
1072 s.replace(pos,1,cr.c_str(),1);
1073 pos = s.find(ss, pos);
1079 while ( pos != std::string::npos )
1081 // std::cout << "*** find one "<<std::endl;
1082 s.replace(pos,1,cr.c_str(),1);
1083 pos = s.find(ss, pos);
1084 } // std::cout << "AFTER=["<<s<<"]"<<std::endl;
1086 //=======================================================================
1088 //=========================================================================
1089 /// Write Graphviz-dot description in file
1090 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1091 BlackBox::Pointer parentblackbox,
1092 int detail, int level,
1093 bool instanceOrtype,
1094 bool relative_link )
1097 InputConnectorMapType::iterator i;
1099 std::string labelStr;
1100 std::string valueStr("");
1103 labelStr = bbGetName() ;
1105 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1107 labelStr = bbGetName();
1108 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
1111 SubsBrackets(labelStr);
1114 labelStr = labelStr + " | {{ ";
1115 std::string tempStrTypeName;
1118 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1122 labelStr=labelStr+" | ";
1125 if (instanceOrtype==true)
1127 valueStr = this->bbGetInputAsString(i->first) + " = ";
1129 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1130 tempStrTypeName=id->GetTypeName();
1131 SubsBrackets(tempStrTypeName);
1132 std::string Name(i->first);
1134 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
1136 labelStr=labelStr+ " } | {";
1138 OutputConnectorMapType::iterator ii;
1139 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
1143 labelStr=labelStr+" | ";
1146 if (instanceOrtype==true)
1148 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1150 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
1151 tempStrTypeName=id->GetTypeName();
1152 SubsBrackets(tempStrTypeName);
1153 std::string Name(ii->first);
1155 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
1157 labelStr = labelStr+ " } }" ;
1161 bbWriteDotInputOutputName(ff,true,detail,level);
1162 std::string tmp ( bbGetTypeName() );
1166 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1168 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1170 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1171 // std::cout << labelStr << std::endl;
1174 if (GetThisPointer<BlackBox>()!=parentblackbox){
1175 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1179 Connection* con = i->second->GetConnection();
1181 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1182 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1184 a->bbWriteDotInputOutputName(ff,false,detail,level);
1187 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1190 b->bbWriteDotInputOutputName(ff,true,detail,level);
1193 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1195 fprintf(ff,"%s\n",";");
1199 } // if parentblackbox
1201 //=========================================================================
1206 //=========================================================================
1207 void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox,
1208 int detail, int level
1209 /*,Factory *factory*/ )
1212 if (this->bbGetDescriptor()->GetPackage())
1214 bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
1215 this->bbGetDescriptor()->GetPackage()->GetName()
1216 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1220 bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1225 bbtkBlackBoxMessage("help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1226 <<mMinOutputChangeTime<<"]"<<std::endl);
1230 bbtkBlackBoxMessage("help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1231 <<mMinOutputChangeTime<<"]"<<std::endl);
1234 // bbtkBlackBoxMessage("help",1," "<<GetDescription()<<std::endl);
1235 // bbtkBlackBoxMessage("help",1," By : "<<GetAuthor()<<std::endl);
1237 std::vector<std::string> iname;
1238 std::vector<std::string> ivalue;
1239 std::vector<std::string> iconn;
1240 std::vector<std::string> istatus;
1242 InputConnectorMapType::iterator i;
1243 unsigned int namelmax = 0;
1244 unsigned int valuelmax = 0;
1245 // unsigned int connlmax = 0;
1246 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1248 iname.push_back(i->first);
1249 if (iname.back().size()>namelmax) namelmax = iname.back().size();
1250 ivalue.push_back(bbGetInputAsString(i->first));
1251 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1253 Connection* con = i->second->GetConnection();
1255 s = con->GetOriginalBlackBoxFrom()->bbGetName();
1257 s += con->GetOriginalBlackBoxFromOutput();
1260 istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1262 OutputConnectorMapType::iterator o;
1263 std::vector<std::string> oname;
1264 std::vector<std::string> ovalue;
1265 std::vector<std::vector<std::string> > oconn;
1266 std::vector<std::string> ostatus;
1267 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
1269 oname.push_back(o->first);
1270 if (oname.back().size()>namelmax)
1271 namelmax = oname.back().size();
1272 ovalue.push_back(bbGetOutputAsString(o->first));
1273 if (ovalue.back().size()>valuelmax)
1274 valuelmax = ovalue.back().size();
1275 std::vector<std::string> ss;
1276 const std::vector<Connection*>& con
1277 = o->second->GetConnectionVector();
1278 std::vector<Connection*>::const_iterator c;
1279 for (c=con.begin();c!=con.end();++c)
1282 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1284 s += (*c)->GetOriginalBlackBoxToInput();
1287 oconn.push_back(ss);
1288 ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1292 bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
1294 bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
1296 std::vector<std::string>::iterator i1,i2,i3,i4;
1297 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1298 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1299 ++i1,++i2,++i3,++i4)
1301 std::string name(*i1);
1303 name.append(1+namelmax-name.size(),' ');
1304 std::string value(*i2);
1306 value.append(1+valuelmax-value.size(),' ');
1308 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value<<" <-- '" <<*i3<<"'");
1310 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1311 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1315 bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
1317 bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
1319 std::vector<std::vector<std::string> >::iterator i5;
1321 for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1322 i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1323 ++i1,++i2,++i4,++i5)
1325 std::string name(*i1);
1327 name.append(1+namelmax-name.size(),' ');
1328 std::string value(*i2);
1330 value.append(1+valuelmax-value.size(),' ');
1332 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1335 std::string pref = " '"+name+" = '"+value;
1336 for (i3=i5->begin();i3!=i5->end();++i3)
1338 bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
1339 pref.replace(0,pref.size(),pref.size(),' ');
1342 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1346 //=========================================================================
1365 static bool bbmgGlobalProcessingExecutionList = false;
1367 //=========================================================================
1368 void BlackBox::bbGlobalProcessExecutionList()
1370 bbtkDebugMessage("process",3,
1371 "=> BlackBox::bbGlobalProcessExecutionList()"
1373 if (bbmgGlobalProcessingExecutionList)
1375 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1378 bbmgGlobalProcessingExecutionList = true;
1380 std::set<BlackBox::WeakPointer>::iterator i;
1381 while (bbmgExecutionList.size()>0)
1383 i = bbmgExecutionList.begin();
1384 BlackBox::WeakPointer p = *i;
1385 bbmgExecutionList.erase(i);
1388 bbtkDebugMessage("process",4,
1390 p.lock()->bbGetName()<<"'"<<std::endl);
1391 p.lock()->bbExecute(true);
1395 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1399 bbmgExecutionList.clear();
1400 bbtkDebugMessage("process",3,
1401 "<= BlackBox::bbGlobalProcessExecutionList()"
1404 bbmgGlobalProcessingExecutionList = false;
1407 //=========================================================================
1409 bool BlackBox::bbGlobalGetSomeBoxExecuting()
1411 return bbmgSomeBoxExecuting;
1414 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
1416 bbmgSomeBoxExecuting = b;
1419 void BlackBox::bbGlobalSetFreezeExecution(bool b)
1421 bbmgFreezeExecution = b;
1424 bool BlackBox::bbGlobalGetFreezeExecution()
1426 return bbmgFreezeExecution;
1429 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1431 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
1432 if (bbmgGlobalProcessingExecutionList)
1434 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1436 bbmgExecutionList.insert(b);
1440 //=========================================================================
1442 //=========================================================================
1443 void BlackBox::Check(bool recursive)
1445 bbtkBlackBoxMessage("debug",1,"*** Checking"
1446 <<" ... OK"<<std::endl);
1448 //=========================================================================
1453 } // EO namespace bbtk