1 /*=========================================================================
3 Module: $RCSfile: bbtkBlackBox.cxx,v $
5 Date: $Date: 2011/03/03 14:37:57 $
6 Version: $Revision: 1.52 $
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 //=========================================================================
501 //=========================================================================
502 void BlackBox::bbSignalOutputModification(const std::string& output,
505 bbtkBlackBoxDebugMessage("change",5,
506 "=> BlackBox::bbSignalOutputModification("
507 <<output<<","<<reaction<<")"
510 OutputConnectorMapType::iterator i =
511 bbGetOutputConnectorMap().find(output);
514 if ( i == bbGetOutputConnectorMap().end() )
516 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
519 // if (i->second->GetStatus()==UPTODATE)
521 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
522 // Has to notify the output "BoxChange" also
523 if (output != "BoxChange")
525 i = bbGetOutputConnectorMap().find("BoxChange");
526 if ( i != bbGetOutputConnectorMap().end() )
528 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
531 if (reaction) bbGlobalProcessExecutionList();
534 bbtkBlackBoxDebugMessage("change",5,
535 "<= BlackBox::bbSignalOutputModification("
539 //=========================================================================
540 //=========================================================================
541 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
544 bbtkBlackBoxDebugMessage("change",5,
545 "=> BlackBox::bbSignalOutputModification(vector of outputs)"
547 OutputConnectorMapType::iterator i;
548 std::vector<std::string>::const_iterator o;
549 bool changed = false;
550 for (o=output.begin();o!=output.end();++o)
552 // the output "BoxChange" must be signaled **AFTER** all others
553 if (*o == "BoxChange") continue;
554 // Look for the connector
555 i = bbGetOutputConnectorMap().find(*o);
556 if ( i == bbGetOutputConnectorMap().end() )
558 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
561 // if (i->second->GetStatus()==UPTODATE)
563 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
567 // Has to notify the output "BoxChange" also
568 i = bbGetOutputConnectorMap().find("BoxChange");
569 if ( changed && (i != bbGetOutputConnectorMap().end()))
571 // if (i->second->GetStatus()==UPTODATE)
573 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
574 if (reaction) bbGlobalProcessExecutionList();
578 bbtkBlackBoxDebugMessage("change",5,
579 "<= BlackBox::bbSignalOutputModification(vector of outputs)"
582 //=========================================================================
590 //=========================================================================
591 /// Main processing method of the box.
592 void BlackBox::bbExecute(bool force)
594 bbtkBlackBoxDebugMessage("process",2,
595 "=> BlackBox::bbExecute("<<(int)force<<")"
598 // If already executing : return
600 if (bbGetExecuting())
602 bbtkBlackBoxDebugMessage("process",2,
603 " -> already executing : abort"<<std::endl);
608 // If execution frozen : return
609 if (bbGlobalGetFreezeExecution())
611 bbtkBlackBoxDebugMessage("process",2,
612 " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
617 // If force is true then update is triggered even if the box is UPTODATE
618 // if (force) bbSetModifiedStatus();
620 // Calls the main recursive execution method
621 bbRecursiveExecute(Connection::Pointer());
623 bbtkBlackBoxDebugMessage("process",2,
624 "<= BlackBox::bbExecute()"
627 //=========================================================================
629 //=========================================================================
630 void BlackBox::bbInitializeProcessing()
634 bbtkBlackBoxDebugMessage("process",2,"** Initialize processing"
636 this->bbRecursiveInitializeProcessing();
637 bbmInitialized = true;
640 //=========================================================================
642 //=========================================================================
643 void BlackBox::bbFinalizeProcessing()
647 bbtkBlackBoxDebugMessage("process",2,"** Finalize processing"
649 this->bbRecursiveFinalizeProcessing();
650 bbmInitialized = false;
653 //=========================================================================
656 //=========================================================================
657 void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
659 bbtkBlackBoxDebugMessage("process",3,
660 "=> BlackBox::bbRecursiveExecute("
661 <<(caller?caller->GetFullName():"0")<<")"
664 // If already executing : return
665 if (bbGetExecuting())
667 bbtkBlackBoxDebugMessage("process",3,
668 " -> already executing : abort"<<std::endl);
672 // If not initialized do it
673 bbInitializeProcessing();
675 bbSetExecuting(true);
676 bool wasExecuting = bbGlobalGetSomeBoxExecuting();
677 bbGlobalSetSomeBoxExecuting(true);
679 // Creates the window if the black box has one
680 this->bbCreateWindow();
682 // Updates its inputs
683 IOStatus s = bbUpdateInputs();
685 if ( (s != UPTODATE) ||
686 bbBoxProcessModeIsAlways() )
688 // Displays the window (WxBlackbox)
689 // bbShowWindow(caller);
691 // Actual processing (virtual)
695 // Update the I/O statuses
696 bbComputePostProcessStatus();
700 // Test output status...
701 OutputConnectorMapType::iterator o;
702 for ( o = bbGetOutputConnectorMap().begin();
703 o!= bbGetOutputConnectorMap().end(); ++o)
705 if (o->second->GetStatus() != UPTODATE)
707 bbtkWarning("BlackBox::bbRecursiveExecute: "
708 <<"all inputs are Up-to-date but output '"
709 <<o->first<<"' is Out-of-date ???");
713 bbtkBlackBoxDebugMessage("process",3," -> Up-to-date : nothing to do"
717 // Shows the window if the black box has one
718 this->bbShowWindow();
721 bbtkBlackBoxDebugMessage("process",3,
722 "<= BlackBox::bbRecursiveExecute()"
725 bbSetExecuting(false);
726 bbGlobalSetSomeBoxExecuting(wasExecuting);
730 //=========================================================================
736 //=========================================================================
737 IOStatus BlackBox::bbUpdateInputs()
739 bbtkBlackBoxDebugMessage("process",4,
740 "=> BlackBox::bbUpdateInputs()"
743 IOStatus s = UPTODATE;
745 InputConnectorMapType::iterator i;
746 for ( i = bbGetInputConnectorMap().begin();
747 i!= bbGetInputConnectorMap().end(); ++i)
749 // if (i->first=="WinHide") continue;
750 // If input type is Void : no recurse
751 //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo()
754 bbtkBlackBoxDebugMessage("change",2,
756 <<"': status before update = '"
757 <<GetIOStatusString(i->second->GetStatus())
759 i->second->RecursiveExecute();
760 IOStatus t = i->second->GetStatus();
762 bbtkBlackBoxDebugMessage("change",2,
764 <<"': status before process = '"
765 <<GetIOStatusString(i->second->GetStatus())
769 bbtkBlackBoxDebugMessage("process",4,
770 "<= BlackBox::bbUpdateInputs()"
774 //=========================================================================
776 //==================================================================
777 void BlackBox::bbComputePostProcessStatus()
779 bbtkBlackBoxDebugMessage("process",4,
780 "=> BlackBox::bbComputePostProcessStatus()"
783 IOStatus new_output_status = UPTODATE;
784 if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
786 // Update the input statuses
787 InputConnectorMapType::iterator i;
788 for ( i = bbGetInputConnectorMap().begin();
789 i!= bbGetInputConnectorMap().end(); ++i)
791 IOStatus t = i->second->GetStatus();
792 if (t == OUTOFDATE) new_output_status = OUTOFDATE;
793 // A previously MODIFIED status turns to UPTODATE
794 if (t==MODIFIED) i->second->SetStatus(UPTODATE);
795 bbtkBlackBoxDebugMessage("change",2,
796 "Input '"<<i->first<<"' : "
797 << GetIOStatusString(t) << " -> "
798 << GetIOStatusString(i->second->GetStatus())
801 bbtkBlackBoxDebugMessage("change",2,
802 "New output status : "
803 << GetIOStatusString(new_output_status)
805 // Update the output statuses
806 OutputConnectorMapType::iterator o;
807 for ( o = bbGetOutputConnectorMap().begin();
808 o!= bbGetOutputConnectorMap().end(); ++o)
810 o->second->SetStatus(new_output_status);
813 bbtkBlackBoxDebugMessage("process",4,
814 "<= BlackBox::bbComputePostProcessStatus()"
817 //==================================================================
819 //=========================================================================
820 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
822 bbtkBlackBoxDebugMessage("connection",2,
823 "==> BlackBox::bbConnectInput(\""
824 <<name<<"\","<<c->GetFullName()<<")"
827 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
828 if (i==bbGetInputConnectorMap().end())
830 bbtkError("no input called '"<<name<<"'");
832 i->second->SetConnection(c);
833 // The input *MUST* be set OUTOFDATE to update its input on next execution
834 bbSetStatusAndPropagate(i->second,OUTOFDATE);
836 bbtkBlackBoxDebugMessage("connection",2,
837 "<== BlackBox::bbConnectInput(\""
838 <<name<<"\","<<c->GetFullName()<<")"
841 //=========================================================================
844 //=========================================================================
845 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
847 bbtkBlackBoxDebugMessage("connection",2,
848 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
849 <<c->GetFullName()<<")"
852 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
853 if (i==bbGetOutputConnectorMap().end())
855 bbtkError("no output called '"<<name<<"'");
857 i->second->SetConnection(c);
859 bbtkBlackBoxDebugMessage("connection",2,
860 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
861 <<c->GetFullName()<<")"
864 //=========================================================================
867 //=========================================================================
868 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
871 bbtkBlackBoxDebugMessage("connection",2,
872 "==> BlackBox::bbDisconnectInput(\""<<name
873 <<"\","<<c->GetFullName()<<")"
878 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
882 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
883 if (i==bbGetInputConnectorMap().end())
885 bbtkError("no input called '"<<name<<"'");
887 i->second->UnsetConnection(c);
889 bbtkBlackBoxDebugMessage("connection",2,
890 "<== BlackBox::bbDisconnectInput(\""<<name
891 <<"\","<<c->GetFullName()<<")"
895 //=========================================================================
898 //=========================================================================
899 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
901 bbtkBlackBoxDebugMessage("connection",2,
902 "==> BlackBox::bbDisconnectOutput(\""<<name
903 <<"\","<<c->GetFullName()<<")"
908 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
912 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
913 if (i==bbGetOutputConnectorMap().end())
915 bbtkError("no output called '"<<name<<"'");
917 i->second->UnsetConnection(c);
919 bbtkBlackBoxDebugMessage("connection",2,
920 "<== BlackBox::bbDisconnectOutput(\""<<name
921 <<"\","<<c->GetFullName()<<")"
924 //=========================================================================
948 //=========================================================================
949 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
951 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
953 //=========================================================================
956 //=========================================================================
957 std::string BlackBox::bbGetOutputAsString( const std::string &output )
960 // Looks for the adaptor
961 if (bbGetOutputType(output).name() != typeid(std::string).name() )
964 Package::Pointer p = bbGetDescriptor()->GetPackage();
965 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
967 Factory::Pointer f = p->GetFactorySet().begin()->lock();
972 bbGetOutputType(output),
975 } catch (bbtk::Exception e)
980 a->bbSetInput("In",bbGetOutput(output));
982 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
984 v="? (no adaptor found)";
989 v="? (no factory found)";
995 v = bbGetOutput(output).unsafe_get<std::string>() ;
999 //=========================================================================
1001 //=========================================================================
1002 std::string BlackBox::bbGetInputAsString( const std::string &input )
1005 // Looks for the adaptor
1006 if (bbGetInputType(input) != typeid(std::string))
1009 Package::Pointer p = bbGetDescriptor()->GetPackage();
1010 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1012 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1013 BlackBox::Pointer a;
1017 bbGetInputType(input),
1018 typeid(std::string),
1020 }catch (bbtk::Exception e)
1026 a->bbSetInput("In",bbGetInput(input));
1028 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1032 v="? (no adaptor found)";
1037 v="? (no factory found)";
1042 v = bbGetInput(input).unsafe_get<std::string>() ;
1046 //=======================================================================
1048 //=======================================================================
1049 // Replaces substrings "<" by "["
1050 void SubsBrackets ( std::string& s )
1052 // std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1053 std::string ss("<");
1054 std::string::size_type pos = 0;
1056 std::string cr("[");
1057 while ( pos != std::string::npos )
1059 // std::cout << "*** find one "<<std::endl;
1060 s.replace(pos,1,cr.c_str(),1);
1061 pos = s.find(ss, pos);
1067 while ( pos != std::string::npos )
1069 // std::cout << "*** find one "<<std::endl;
1070 s.replace(pos,1,cr.c_str(),1);
1071 pos = s.find(ss, pos);
1077 while ( pos != std::string::npos )
1079 // std::cout << "*** find one "<<std::endl;
1080 s.replace(pos,1,cr.c_str(),1);
1081 pos = s.find(ss, pos);
1082 } // std::cout << "AFTER=["<<s<<"]"<<std::endl;
1084 //=======================================================================
1086 //=========================================================================
1087 /// Write Graphviz-dot description in file
1088 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1089 BlackBox::Pointer parentblackbox,
1090 int detail, int level,
1091 bool instanceOrtype,
1092 bool relative_link )
1095 InputConnectorMapType::iterator i;
1097 std::string labelStr;
1098 std::string valueStr("");
1101 labelStr = bbGetName() ;
1103 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1105 labelStr = bbGetName();
1106 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
1109 SubsBrackets(labelStr);
1112 labelStr = labelStr + " | {{ ";
1113 std::string tempStrTypeName;
1116 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1120 labelStr=labelStr+" | ";
1123 if (instanceOrtype==true)
1125 valueStr = this->bbGetInputAsString(i->first) + " = ";
1127 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1128 tempStrTypeName=id->GetTypeName();
1129 SubsBrackets(tempStrTypeName);
1130 std::string Name(i->first);
1132 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
1134 labelStr=labelStr+ " } | {";
1136 OutputConnectorMapType::iterator ii;
1137 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
1141 labelStr=labelStr+" | ";
1144 if (instanceOrtype==true)
1146 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1148 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
1149 tempStrTypeName=id->GetTypeName();
1150 SubsBrackets(tempStrTypeName);
1151 std::string Name(ii->first);
1153 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
1155 labelStr = labelStr+ " } }" ;
1159 bbWriteDotInputOutputName(ff,true,detail,level);
1160 std::string tmp ( bbGetTypeName() );
1164 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1166 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1168 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1169 // std::cout << labelStr << std::endl;
1172 if (GetThisPointer<BlackBox>()!=parentblackbox){
1173 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1177 Connection* con = i->second->GetConnection();
1179 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1180 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1182 a->bbWriteDotInputOutputName(ff,false,detail,level);
1185 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1188 b->bbWriteDotInputOutputName(ff,true,detail,level);
1191 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1193 fprintf(ff,"%s\n",";");
1197 } // if parentblackbox
1199 //=========================================================================
1204 //=========================================================================
1205 void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox,
1206 int detail, int level
1207 /*,Factory *factory*/ )
1210 if (this->bbGetDescriptor()->GetPackage())
1212 bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
1213 this->bbGetDescriptor()->GetPackage()->GetName()
1214 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1218 bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1223 bbtkBlackBoxMessage("help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1224 <<mMinOutputChangeTime<<"]"<<std::endl);
1228 bbtkBlackBoxMessage("help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1229 <<mMinOutputChangeTime<<"]"<<std::endl);
1232 // bbtkBlackBoxMessage("help",1," "<<GetDescription()<<std::endl);
1233 // bbtkBlackBoxMessage("help",1," By : "<<GetAuthor()<<std::endl);
1235 std::vector<std::string> iname;
1236 std::vector<std::string> ivalue;
1237 std::vector<std::string> iconn;
1238 std::vector<std::string> istatus;
1240 InputConnectorMapType::iterator i;
1241 unsigned int namelmax = 0;
1242 unsigned int valuelmax = 0;
1243 // unsigned int connlmax = 0;
1244 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1246 iname.push_back(i->first);
1247 if (iname.back().size()>namelmax) namelmax = iname.back().size();
1248 ivalue.push_back(bbGetInputAsString(i->first));
1249 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1251 Connection* con = i->second->GetConnection();
1253 s = con->GetOriginalBlackBoxFrom()->bbGetName();
1255 s += con->GetOriginalBlackBoxFromOutput();
1258 istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1260 OutputConnectorMapType::iterator o;
1261 std::vector<std::string> oname;
1262 std::vector<std::string> ovalue;
1263 std::vector<std::vector<std::string> > oconn;
1264 std::vector<std::string> ostatus;
1265 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
1267 oname.push_back(o->first);
1268 if (oname.back().size()>namelmax) namelmax = oname.back().size();
1269 ovalue.push_back(bbGetOutputAsString(o->first));
1270 if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size();
1271 std::vector<std::string> ss;
1272 const std::vector<Connection*>& con
1273 = o->second->GetConnectionVector();
1274 std::vector<Connection*>::const_iterator c;
1275 for (c=con.begin();c!=con.end();++c)
1278 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1280 s += (*c)->GetOriginalBlackBoxToInput();
1283 oconn.push_back(ss);
1284 ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1288 bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
1290 bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
1292 std::vector<std::string>::iterator i1,i2,i3,i4;
1293 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1294 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1295 ++i1,++i2,++i3,++i4)
1297 std::string name(*i1);
1299 name.append(1+namelmax-name.size(),' ');
1300 std::string value(*i2);
1302 value.append(1+valuelmax-value.size(),' ');
1304 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value<<" <-- '"
1307 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1308 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1312 bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
1314 bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
1316 std::vector<std::vector<std::string> >::iterator i5;
1318 for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1319 i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1320 ++i1,++i2,++i4,++i5)
1322 std::string name(*i1);
1324 name.append(1+namelmax-name.size(),' ');
1325 std::string value(*i2);
1327 value.append(1+valuelmax-value.size(),' ');
1329 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1332 std::string pref = " '"+name+" = '"+value;
1333 for (i3=i5->begin();i3!=i5->end();++i3)
1335 bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
1336 pref.replace(0,pref.size(),pref.size(),' ');
1339 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1343 //=========================================================================
1362 static bool bbmgGlobalProcessingExecutionList = false;
1364 //=========================================================================
1365 void BlackBox::bbGlobalProcessExecutionList()
1367 bbtkDebugMessage("process",3,
1368 "=> BlackBox::bbGlobalProcessExecutionList()"
1370 if (bbmgGlobalProcessingExecutionList)
1372 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1375 bbmgGlobalProcessingExecutionList = true;
1377 std::set<BlackBox::WeakPointer>::iterator i;
1378 while (bbmgExecutionList.size()>0)
1380 i = bbmgExecutionList.begin();
1381 BlackBox::WeakPointer p = *i;
1382 bbmgExecutionList.erase(i);
1385 bbtkDebugMessage("process",4,
1387 p.lock()->bbGetName()<<"'"<<std::endl);
1388 p.lock()->bbExecute(true);
1392 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1396 bbmgExecutionList.clear();
1397 bbtkDebugMessage("process",3,
1398 "<= BlackBox::bbGlobalProcessExecutionList()"
1401 bbmgGlobalProcessingExecutionList = false;
1404 //=========================================================================
1406 bool BlackBox::bbGlobalGetSomeBoxExecuting()
1408 return bbmgSomeBoxExecuting;
1411 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
1413 bbmgSomeBoxExecuting = b;
1416 void BlackBox::bbGlobalSetFreezeExecution(bool b)
1418 bbmgFreezeExecution = b;
1421 bool BlackBox::bbGlobalGetFreezeExecution()
1423 return bbmgFreezeExecution;
1426 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1428 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
1429 if (bbmgGlobalProcessingExecutionList)
1431 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1433 bbmgExecutionList.insert(b);
1437 //=========================================================================
1439 //=========================================================================
1440 void BlackBox::Check(bool recursive)
1442 bbtkBlackBoxMessage("debug",1,"*** Checking"
1443 <<" ... OK"<<std::endl);
1445 //=========================================================================
1450 } // EO namespace bbtk