1 /*=========================================================================
3 Module: $RCSfile: bbtkBlackBox.cxx,v $
5 Date: $Date: 2010/01/21 16:03:17 $
6 Version: $Revision: 1.49 $
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"
53 static bool bbmgSomeBoxExecuting = false;
54 static bool bbmgFreezeExecution = false;
55 static std::set<BlackBox::WeakPointer> bbmgExecutionList;
57 //=========================================================================
59 BlackBox::Deleter::Deleter()
62 //=========================================================================
64 //=========================================================================
65 int BlackBox::Deleter::Delete(Object* p)
67 BlackBox* b = dynamic_cast<BlackBox*>(p);
70 bbtkInternalError("BlackBox::Deleter::Delete("<<p->GetObjectName()
72 <<"dynamic cast to BlackBox* failed !");
74 std::string name = p->GetObjectName();//b->bbGetNameWithParent();
75 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
78 BlackBoxDescriptor::WeakPointer desc = b->bbGetDescriptor();
79 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : deleting black box"<<std::endl);
81 int refs = b->bbDelete();
83 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : releasing descriptor"<<std::endl);
87 Package::WeakPointer pack = desc.lock()->GetPackage();
90 Package::ReleaseBlackBoxDescriptor(pack,desc);
94 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor package expired (was not held by a package and the box was the last instance)"<<std::endl);
99 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);
101 bbtkDebugMessage("object",2,"<## BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
104 //=========================================================================
106 //=========================================================================
107 BlackBox::BlackBox(const std::string &name)
109 // bbmStatus(MODIFIED),
110 bbmInitialized(false),
113 bbmBoxProcessMode("Pipeline"),
118 // bbmBoxProcessMode = "Pipeline";
119 //std::cout<<"JCP BlackBox::BlackBox(const std::string &name) name=" <<name
120 // <<"bbmBoxProcessMode="<<bbmBoxProcessMode<<std::endl;
121 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox(\""
122 <<name<<"\")"<<std::endl);
123 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox(\""
124 <<name<<"\")"<<std::endl);
126 //=========================================================================
128 //=========================================================================
129 BlackBox::BlackBox(const BlackBox&)
132 //=========================================================================
133 BlackBox::BlackBox(BlackBox& from, const std::string &name)
135 // bbmStatus(from.bbmStatus),
136 bbmInitialized(false),
139 bbmBoxProcessMode(from.bbmBoxProcessMode),
144 //bbmBoxProcessMode = from.bbmBoxProcessMode;
145 //std::cout<<"JCP BlackBox::BlackBox(const std::string &name) name=" <<name
146 // <<"bbmBoxProcessMode="<<bbmBoxProcessMode<<std::endl;
147 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox("
148 <<from.bbGetFullName()<<",\""
149 <<name<<"\")"<<std::endl);
150 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox("
151 <<from.bbGetFullName()<<",\""
152 <<name<<"\")"<<std::endl);
154 //=========================================================================
157 //=========================================================================
158 BlackBox::~BlackBox()
160 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::~BlackBox() ["<<bbmName
162 this->bbDesallocateConnectors();
163 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::~BlackBox() ["<<bbmName
166 //=========================================================================
170 //=========================================================================
171 std::string BlackBox::bbGetFullName() const
173 return this->bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
175 //=========================================================================
179 //=========================================================================
180 std::string BlackBox::bbGetNameWithParent() const
182 if (bbmParent.lock())
184 return bbmParent.lock()->bbGetNameWithParent() + ":" + bbmName;
191 //=========================================================================
193 //=========================================================================
194 void BlackBox::bbGetHelp(bool full) const
196 bbGetDescriptor()->GetHelp(full);
198 //=========================================================================
201 //=========================================================================
202 bool BlackBox::bbHasInput(const std::string& name) const
204 bbtkBlackBoxDebugMessage("kernel",8,
205 "BlackBox::bbHasInput(\""
208 bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
209 != bbGetDescriptor()->GetInputDescriptorMap().end());
210 bbtkDebugDecTab("kernel",8);
213 //=========================================================================
216 //=========================================================================
217 bool BlackBox::bbHasOutput(const std::string& name) const
219 bbtkBlackBoxDebugMessage("kernel",8,"BlackBox::bbHasOutput(\""
222 bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
223 != bbGetDescriptor()->GetOutputDescriptorMap().end());
224 bbtkDebugDecTab("kernel",8);
227 //=========================================================================
230 //=========================================================================
231 TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const
233 bbtkBlackBoxDebugMessage("kernel",8,
234 "BlackBox::bbGetOutputType(\""
237 TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
238 bbtkDebugDecTab("kernel",8);
241 //=========================================================================
243 //=========================================================================
244 TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
246 bbtkBlackBoxDebugMessage("kernel",8,
247 "BlackBox::bbGetInputType(\""
250 TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
251 bbtkDebugDecTab("kernel",8);
254 //=========================================================================
257 //=========================================================================
258 void BlackBox::bbAllocateConnectors()
260 bbtkBlackBoxDebugMessage("kernel",8,
261 "BlackBox::bbAllocateConnectors()"
264 MakeBlackBoxPointer(this,true);
266 const BlackBoxDescriptor::InputDescriptorMapType& imap
267 = bbGetDescriptor()->GetInputDescriptorMap();
268 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
269 for ( i = imap.begin(); i != imap.end(); ++i )
271 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
272 bbGetInputConnectorMap()[i->second->GetName()]
273 = new BlackBoxInputConnector(GetThisPointer<BlackBox>());
275 const BlackBoxDescriptor::OutputDescriptorMapType& omap
276 = bbGetDescriptor()->GetOutputDescriptorMap();
277 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
278 for ( o = omap.begin(); o != omap.end(); ++o )
280 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
281 bbGetOutputConnectorMap()[o->second->GetName()]
282 = new BlackBoxOutputConnector(GetThisPointer<BlackBox>());
286 //=========================================================================
289 //=========================================================================
290 void BlackBox::bbDesallocateConnectors()
292 bbtkBlackBoxDebugMessage("kernel",8,
293 "BlackBox::bbDesallocateConnectors()"
296 InputConnectorMapType::const_iterator i;
297 for ( i = bbGetInputConnectorMap().begin();
298 i != bbGetInputConnectorMap().end(); ++i )
300 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<i->first<<"\""<<std::endl);
303 OutputConnectorMapType::const_iterator o;
304 for ( o = bbGetOutputConnectorMap().begin();
305 o != bbGetOutputConnectorMap().end(); ++o )
307 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<o->first<<"\""<<std::endl);
311 bbtkDebugDecTab("kernel",8);
314 //=========================================================================
317 //=========================================================================
318 void BlackBox::bbCopyIOValues(BlackBox& from)
320 bbtkBlackBoxDebugMessage("kernel",1,
321 "BlackBox::bbCopyIOValues("
322 <<from.bbGetFullName()<<")"
324 // copies the input values
325 const BlackBoxDescriptor::InputDescriptorMapType& imap
326 = bbGetDescriptor()->GetInputDescriptorMap();
327 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
328 for ( i = imap.begin(); i != imap.end(); ++i )
330 if (! i->second->GetCopyConstruct() ) continue;
331 std::string input = i->second->GetName();
332 bbtkBlackBoxDebugMessage("kernel",2,"* Copying input "<<input<<std::endl);
333 this->bbSetInput(input, from.bbGetInput(input) );
335 // copies the output values
336 const BlackBoxDescriptor::OutputDescriptorMapType& omap
337 = bbGetDescriptor()->GetOutputDescriptorMap();
338 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
339 for ( o = omap.begin(); o != omap.end(); ++o )
341 if (! o->second->GetCopyConstruct() ) continue;
342 std::string output = o->second->GetName();
343 bbtkBlackBoxDebugMessage("kernel",2,"* Copying output "<<output<<std::endl);
344 this->bbSetOutput(output, from.bbGetOutput(output) );
347 bbtkDebugDecTab("kernel",9);
350 //=========================================================================
354 //=========================================================================
355 bool BlackBox::bbCanReact() const
357 return ( bbGlobalGetSomeBoxExecuting()
359 || Wx::IsSomeWindowAlive()
363 //=========================================================================
367 //=========================================================================
368 BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
370 const std::string& p = bbmBoxProcessMode;
372 (p == "P") || (p == "p") ||
373 (p == "Pipeline") || (p == "pipeline") ) return Pipeline;
375 (p == "A") || (p == "a") ||
376 (p == "Always") || (p == "always") ) return Always;
378 (p == "R") || (p == "r") ||
379 (p == "Reactive") || (p == "reactive") )
383 (p == "F") || (p == "f") ||
384 (p == "Flash") || (p == "flash") ) return Flash;
386 bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
387 <<"' unknown. Possible values : "
388 <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
389 <<"'1'/'A'/'a'/'Always'/'always' | "
390 <<"'2'/'R'/'r'/'Reactive'/'reactive'"
391 // <<"'3'/'F'/'f'/'Flash'/'flash'"
394 //=========================================================================
396 //=========================================================================
397 bool BlackBox::bbBoxProcessModeIsReactive() const
399 return (bbGetBoxProcessModeValue() == Reactive);
401 //=========================================================================
403 //=========================================================================
404 bool BlackBox::bbBoxProcessModeIsAlways() const
406 return (bbGetBoxProcessModeValue() == Always);
408 //=========================================================================
413 //=========================================================================
414 void BlackBox::bbAddOutputObserver(const std::string& output,
415 OutputChangeCallbackType f)
417 bbGetOutputConnector(output).AddChangeObserver(f);
419 //=========================================================================
421 //=========================================================================
422 void BlackBox::bbRemoveOutputObserver(const std::string& output_name,
423 OutputChangeCallbackType f)
425 bbtkError("BlackBox::RemoveChangeObserver NOT IMPLEMENTED");
427 //=========================================================================
430 //=========================================================================
431 void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
434 bbtkBlackBoxDebugMessage("change",5,
435 "=> BlackBox::bbSetStatusAndPropagate(input,"
436 <<GetIOStatusString(s)<<")"
439 if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
444 if (bbGetBoxProcessModeValue() == Flash)
450 OutputConnectorMapType::const_iterator o;
451 for ( o = bbGetOutputConnectorMap().begin();
452 o != bbGetOutputConnectorMap().end(); ++o )
454 if (o->second->GetStatus()==UPTODATE)
456 o->second->SetStatus(OUTOFDATE);
457 o->second->SignalChange(GetThisPointer<BlackBox>(),o->first);
461 if ( ( bbBoxProcessModeIsReactive() ||
462 (c==bbGetInputConnectorMap().find("BoxExecute")->second))
465 bbtkBlackBoxDebugMessage("change",2,
466 "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
467 bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
469 bbtkBlackBoxDebugMessage("change",5,
470 "<= BlackBox::bbSetStatusAndPropagate(input)"
473 //=========================================================================
476 //=========================================================================
477 void BlackBox::bbSignalOutputModification(bool reaction)
479 bbtkBlackBoxDebugMessage("change",5,
480 "=> BlackBox::bbSignalOutputModification("
484 OutputConnectorMapType::iterator i;
485 for ( i = bbGetOutputConnectorMap().begin();
486 i != bbGetOutputConnectorMap().end(); ++i)
488 // std::cout << "Stat = "
489 //<<GetIOStatusString(i->second->GetStatus())
491 // LG : CANNOT SIGNAL ONLY WHEN UPTODATE
492 // See bbtkSampleOutputObserver
493 // if (i->second->GetStatus()==UPTODATE)
495 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
499 if (reaction) bbGlobalProcessExecutionList();
501 bbtkBlackBoxDebugMessage("change",5,
502 "<= BlackBox::bbSignalOutputModification()"
506 //=========================================================================
507 //=========================================================================
508 void BlackBox::bbSignalOutputModification(const std::string& output,
511 bbtkBlackBoxDebugMessage("change",5,
512 "=> BlackBox::bbSignalOutputModification("
513 <<output<<","<<reaction<<")"
516 OutputConnectorMapType::iterator i =
517 bbGetOutputConnectorMap().find(output);
520 if ( i == bbGetOutputConnectorMap().end() )
522 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
525 // if (i->second->GetStatus()==UPTODATE)
527 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
528 // Has to notify the output "BoxChange" also
529 if (output != "BoxChange")
531 i = bbGetOutputConnectorMap().find("BoxChange");
532 if ( i != bbGetOutputConnectorMap().end() )
534 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
537 if (reaction) bbGlobalProcessExecutionList();
540 bbtkBlackBoxDebugMessage("change",5,
541 "<= BlackBox::bbSignalOutputModification("
546 //=========================================================================
547 //=========================================================================
548 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
551 bbtkBlackBoxDebugMessage("change",5,
552 "=> BlackBox::bbSignalOutputModification(vector of outputs)"
554 OutputConnectorMapType::iterator i;
555 std::vector<std::string>::const_iterator o;
556 bool changed = false;
557 for (o=output.begin();o!=output.end();++o)
559 // the output "BoxChange" must be signaled **AFTER** all others
560 if (*o == "BoxChange") continue;
561 // Look for the connector
562 i = bbGetOutputConnectorMap().find(*o);
563 if ( i == bbGetOutputConnectorMap().end() )
565 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
568 // if (i->second->GetStatus()==UPTODATE)
570 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
574 // Has to notify the output "BoxChange" also
575 i = bbGetOutputConnectorMap().find("BoxChange");
576 if ( changed && (i != bbGetOutputConnectorMap().end()))
578 // if (i->second->GetStatus()==UPTODATE)
580 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
581 if (reaction) bbGlobalProcessExecutionList();
585 bbtkBlackBoxDebugMessage("change",5,
586 "<= BlackBox::bbSignalOutputModification(vector of outputs)"
590 //=========================================================================
598 //=========================================================================
599 /// Main processing method of the box.
600 void BlackBox::bbExecute(bool force)
602 bbtkBlackBoxDebugMessage("process",2,
603 "=> BlackBox::bbExecute("<<(int)force<<")"
606 // If already executing : return
608 if (bbGetExecuting())
610 bbtkBlackBoxDebugMessage("process",2,
611 " -> already executing : abort"<<std::endl);
616 // If execution frozen : return
617 if (bbGlobalGetFreezeExecution())
619 bbtkBlackBoxDebugMessage("process",2,
620 " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
625 // If force is true then update is triggered even if the box is UPTODATE
626 // if (force) bbSetModifiedStatus();
628 // Calls the main recursive execution method
629 bbRecursiveExecute(Connection::Pointer());
631 bbtkBlackBoxDebugMessage("process",2,
632 "<= BlackBox::bbExecute()"
635 //=========================================================================
637 //=========================================================================
638 void BlackBox::bbInitializeProcessing()
642 bbtkBlackBoxDebugMessage("process",2,"** Initialize processing"
644 this->bbRecursiveInitializeProcessing();
645 bbmInitialized = true;
648 //=========================================================================
650 //=========================================================================
651 void BlackBox::bbFinalizeProcessing()
655 bbtkBlackBoxDebugMessage("process",2,"** Finalize processing"
657 this->bbRecursiveFinalizeProcessing();
658 bbmInitialized = false;
661 //=========================================================================
664 //=========================================================================
665 void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
667 bbtkBlackBoxDebugMessage("process",3,
668 "=> BlackBox::bbRecursiveExecute("
669 <<(caller?caller->GetFullName():"0")<<")"
672 // If already executing : return
673 if (bbGetExecuting())
675 bbtkBlackBoxDebugMessage("process",3,
676 " -> already executing : abort"<<std::endl);
680 // If not initialized do it
681 bbInitializeProcessing();
683 bbSetExecuting(true);
684 bool wasExecuting = bbGlobalGetSomeBoxExecuting();
685 bbGlobalSetSomeBoxExecuting(true);
687 // Creates the window if the black box has one
688 this->bbCreateWindow();
690 // Updates its inputs
691 IOStatus s = bbUpdateInputs();
693 if ( (s != UPTODATE) ||
694 bbBoxProcessModeIsAlways() )
696 // Displays the window (WxBlackbox)
697 // bbShowWindow(caller);
699 // Actual processing (virtual)
703 // Update the I/O statuses
704 bbComputePostProcessStatus();
708 // Test output status...
709 OutputConnectorMapType::iterator o;
710 for ( o = bbGetOutputConnectorMap().begin();
711 o!= bbGetOutputConnectorMap().end(); ++o)
713 if (o->second->GetStatus() != UPTODATE)
715 bbtkWarning("BlackBox::bbRecursiveExecute: "
716 <<"all inputs are Up-to-date but output '"
717 <<o->first<<"' is Out-of-date ???");
721 bbtkBlackBoxDebugMessage("process",3," -> Up-to-date : nothing to do"
725 // Shows the window if the black box has one
726 this->bbShowWindow();
729 bbtkBlackBoxDebugMessage("process",3,
730 "<= BlackBox::bbRecursiveExecute()"
733 bbSetExecuting(false);
734 bbGlobalSetSomeBoxExecuting(wasExecuting);
739 //=========================================================================
745 //=========================================================================
746 IOStatus BlackBox::bbUpdateInputs()
748 bbtkBlackBoxDebugMessage("process",4,
749 "=> BlackBox::bbUpdateInputs()"
752 IOStatus s = UPTODATE;
754 InputConnectorMapType::iterator i;
755 for ( i = bbGetInputConnectorMap().begin();
756 i!= bbGetInputConnectorMap().end(); ++i)
758 // if (i->first=="WinHide") continue;
759 // If input type is Void : no recurse
760 //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo()
763 bbtkBlackBoxDebugMessage("change",2,
765 <<"': status before update = '"
766 <<GetIOStatusString(i->second->GetStatus())
768 i->second->RecursiveExecute();
769 IOStatus t = i->second->GetStatus();
771 bbtkBlackBoxDebugMessage("change",2,
773 <<"': status before process = '"
774 <<GetIOStatusString(i->second->GetStatus())
778 bbtkBlackBoxDebugMessage("process",4,
779 "<= BlackBox::bbUpdateInputs()"
785 //=========================================================================
787 //==================================================================
788 void BlackBox::bbComputePostProcessStatus()
790 bbtkBlackBoxDebugMessage("process",4,
791 "=> BlackBox::bbComputePostProcessStatus()"
794 IOStatus new_output_status = UPTODATE;
795 if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
797 // Update the input statuses
798 InputConnectorMapType::iterator i;
799 for ( i = bbGetInputConnectorMap().begin();
800 i!= bbGetInputConnectorMap().end(); ++i)
802 IOStatus t = i->second->GetStatus();
803 if (t == OUTOFDATE) new_output_status = OUTOFDATE;
804 // A previously MODIFIED status turns to UPTODATE
805 if (t==MODIFIED) i->second->SetStatus(UPTODATE);
806 bbtkBlackBoxDebugMessage("change",2,
807 "Input '"<<i->first<<"' : "
808 << GetIOStatusString(t) << " -> "
809 << GetIOStatusString(i->second->GetStatus())
812 bbtkBlackBoxDebugMessage("change",2,
813 "New output status : "
814 << GetIOStatusString(new_output_status)
816 // Update the output statuses
817 OutputConnectorMapType::iterator o;
818 for ( o = bbGetOutputConnectorMap().begin();
819 o!= bbGetOutputConnectorMap().end(); ++o)
821 o->second->SetStatus(new_output_status);
824 bbtkBlackBoxDebugMessage("process",4,
825 "<= BlackBox::bbComputePostProcessStatus()"
829 //==================================================================
831 //=========================================================================
832 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
834 bbtkBlackBoxDebugMessage("connection",2,
835 "==> BlackBox::bbConnectInput(\""
836 <<name<<"\","<<c->GetFullName()<<")"
840 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
841 if (i==bbGetInputConnectorMap().end())
843 bbtkError("no input called '"<<name<<"'");
845 i->second->SetConnection(c);
846 // The input *MUST* be set OUTOFDATE to update its input on next execution
847 bbSetStatusAndPropagate(i->second,OUTOFDATE);
849 bbtkBlackBoxDebugMessage("connection",2,
850 "<== BlackBox::bbConnectInput(\""
851 <<name<<"\","<<c->GetFullName()<<")"
855 //=========================================================================
858 //=========================================================================
859 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
861 bbtkBlackBoxDebugMessage("connection",2,
862 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
863 <<c->GetFullName()<<")"
866 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
867 if (i==bbGetOutputConnectorMap().end())
869 bbtkError("no output called '"<<name<<"'");
871 i->second->SetConnection(c);
873 bbtkBlackBoxDebugMessage("connection",2,
874 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
875 <<c->GetFullName()<<")"
879 //=========================================================================
882 //=========================================================================
883 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
886 bbtkBlackBoxDebugMessage("connection",2,
887 "==> BlackBox::bbDisconnectInput(\""<<name
888 <<"\","<<c->GetFullName()<<")"
894 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
898 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
899 if (i==bbGetInputConnectorMap().end())
901 bbtkError("no input called '"<<name<<"'");
903 i->second->UnsetConnection(c);
905 bbtkBlackBoxDebugMessage("connection",2,
906 "<== BlackBox::bbDisconnectInput(\""<<name
907 <<"\","<<c->GetFullName()<<")"
911 //=========================================================================
914 //=========================================================================
915 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
917 bbtkBlackBoxDebugMessage("connection",2,
918 "==> BlackBox::bbDisconnectOutput(\""<<name
919 <<"\","<<c->GetFullName()<<")"
924 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
928 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
929 if (i==bbGetOutputConnectorMap().end())
931 bbtkError("no output called '"<<name<<"'");
933 i->second->UnsetConnection(c);
935 bbtkBlackBoxDebugMessage("connection",2,
936 "<== BlackBox::bbDisconnectOutput(\""<<name
937 <<"\","<<c->GetFullName()<<")"
940 //=========================================================================
964 //=========================================================================
965 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
967 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
969 //=========================================================================
972 //=========================================================================
973 std::string BlackBox::bbGetOutputAsString( const std::string &output )
976 // Looks for the adaptor
977 if (bbGetOutputType(output).name() != typeid(std::string).name() )
980 Package::Pointer p = bbGetDescriptor()->GetPackage();
981 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
983 Factory::Pointer f = p->GetFactorySet().begin()->lock();
988 bbGetOutputType(output),
991 } catch (bbtk::Exception e)
996 a->bbSetInput("In",bbGetOutput(output));
998 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1000 v="? (no adaptor found)";
1005 v="? (no factory found)";
1011 v = bbGetOutput(output).unsafe_get<std::string>() ;
1015 //=========================================================================
1017 //=========================================================================
1018 std::string BlackBox::bbGetInputAsString( const std::string &input )
1021 // Looks for the adaptor
1022 if (bbGetInputType(input) != typeid(std::string))
1025 Package::Pointer p = bbGetDescriptor()->GetPackage();
1026 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1028 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1029 BlackBox::Pointer a;
1033 bbGetInputType(input),
1034 typeid(std::string),
1036 }catch (bbtk::Exception e)
1042 a->bbSetInput("In",bbGetInput(input));
1044 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1048 v="? (no adaptor found)";
1053 v="? (no factory found)";
1058 v = bbGetInput(input).unsafe_get<std::string>() ;
1062 //=======================================================================
1064 //=======================================================================
1065 // Replaces substrings "<" by "["
1066 void SubsBrackets ( std::string& s )
1068 // std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1069 std::string ss("<");
1070 std::string::size_type pos = 0;
1072 std::string cr("[");
1073 while ( pos != std::string::npos )
1075 // std::cout << "*** find one "<<std::endl;
1076 s.replace(pos,1,cr.c_str(),1);
1077 pos = s.find(ss, pos);
1083 while ( pos != std::string::npos )
1085 // std::cout << "*** find one "<<std::endl;
1086 s.replace(pos,1,cr.c_str(),1);
1087 pos = s.find(ss, pos);
1093 while ( pos != std::string::npos )
1095 // std::cout << "*** find one "<<std::endl;
1096 s.replace(pos,1,cr.c_str(),1);
1097 pos = s.find(ss, pos);
1098 } // std::cout << "AFTER=["<<s<<"]"<<std::endl;
1100 //=======================================================================
1102 //=========================================================================
1103 /// Write Graphviz-dot description in file
1104 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1105 BlackBox::Pointer parentblackbox,
1106 int detail, int level,
1107 bool instanceOrtype,
1108 bool relative_link )
1111 InputConnectorMapType::iterator i;
1113 std::string labelStr;
1114 std::string valueStr("");
1117 labelStr = bbGetName() ;
1119 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1121 labelStr = bbGetName();
1122 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
1125 SubsBrackets(labelStr);
1128 labelStr = labelStr + " | {{ ";
1129 std::string tempStrTypeName;
1132 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1136 labelStr=labelStr+" | ";
1139 if (instanceOrtype==true)
1141 valueStr = this->bbGetInputAsString(i->first) + " = ";
1143 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1144 tempStrTypeName=id->GetTypeName();
1145 SubsBrackets(tempStrTypeName);
1146 std::string Name(i->first);
1148 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
1150 labelStr=labelStr+ " } | {";
1152 OutputConnectorMapType::iterator ii;
1153 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
1157 labelStr=labelStr+" | ";
1160 if (instanceOrtype==true)
1162 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1164 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
1165 tempStrTypeName=id->GetTypeName();
1166 SubsBrackets(tempStrTypeName);
1167 std::string Name(ii->first);
1169 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
1171 labelStr = labelStr+ " } }" ;
1175 bbWriteDotInputOutputName(ff,true,detail,level);
1176 std::string tmp ( bbGetTypeName() );
1180 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1182 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1184 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1185 // std::cout << labelStr << std::endl;
1188 if (GetThisPointer<BlackBox>()!=parentblackbox){
1189 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1193 Connection* con = i->second->GetConnection();
1195 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1196 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1198 a->bbWriteDotInputOutputName(ff,false,detail,level);
1201 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1204 b->bbWriteDotInputOutputName(ff,true,detail,level);
1207 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1209 fprintf(ff,"%s\n",";");
1213 } // if parentblackbox
1215 //=========================================================================
1220 //=========================================================================
1221 void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox,
1222 int detail, int level
1223 /*,Factory *factory*/ )
1226 if (this->bbGetDescriptor()->GetPackage())
1228 bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
1229 this->bbGetDescriptor()->GetPackage()->GetName()
1230 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1234 bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1239 bbtkBlackBoxMessage("help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1240 <<mMinOutputChangeTime<<"]"<<std::endl);
1244 bbtkBlackBoxMessage("help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1245 <<mMinOutputChangeTime<<"]"<<std::endl);
1248 // bbtkBlackBoxMessage("help",1," "<<GetDescription()<<std::endl);
1249 // bbtkBlackBoxMessage("help",1," By : "<<GetAuthor()<<std::endl);
1251 std::vector<std::string> iname;
1252 std::vector<std::string> ivalue;
1253 std::vector<std::string> iconn;
1254 std::vector<std::string> istatus;
1256 InputConnectorMapType::iterator i;
1257 unsigned int namelmax = 0;
1258 unsigned int valuelmax = 0;
1259 // unsigned int connlmax = 0;
1260 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1262 iname.push_back(i->first);
1263 if (iname.back().size()>namelmax) namelmax = iname.back().size();
1264 ivalue.push_back(bbGetInputAsString(i->first));
1265 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1267 Connection* con = i->second->GetConnection();
1269 s = con->GetOriginalBlackBoxFrom()->bbGetName();
1271 s += con->GetOriginalBlackBoxFromOutput();
1274 istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1276 OutputConnectorMapType::iterator o;
1277 std::vector<std::string> oname;
1278 std::vector<std::string> ovalue;
1279 std::vector<std::vector<std::string> > oconn;
1280 std::vector<std::string> ostatus;
1281 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
1283 oname.push_back(o->first);
1284 if (oname.back().size()>namelmax) namelmax = oname.back().size();
1285 ovalue.push_back(bbGetOutputAsString(o->first));
1286 if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size();
1287 std::vector<std::string> ss;
1288 const std::vector<Connection*>& con
1289 = o->second->GetConnectionVector();
1290 std::vector<Connection*>::const_iterator c;
1291 for (c=con.begin();c!=con.end();++c)
1294 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1296 s += (*c)->GetOriginalBlackBoxToInput();
1299 oconn.push_back(ss);
1300 ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1304 bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
1306 bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
1308 std::vector<std::string>::iterator i1,i2,i3,i4;
1309 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1310 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1311 ++i1,++i2,++i3,++i4)
1313 std::string name(*i1);
1315 name.append(1+namelmax-name.size(),' ');
1316 std::string value(*i2);
1318 value.append(1+valuelmax-value.size(),' ');
1320 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value<<" <-- '"
1323 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1324 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1328 bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
1330 bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
1332 std::vector<std::vector<std::string> >::iterator i5;
1334 for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1335 i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1336 ++i1,++i2,++i4,++i5)
1338 std::string name(*i1);
1340 name.append(1+namelmax-name.size(),' ');
1341 std::string value(*i2);
1343 value.append(1+valuelmax-value.size(),' ');
1345 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1348 std::string pref = " '"+name+" = '"+value;
1349 for (i3=i5->begin();i3!=i5->end();++i3)
1351 bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
1352 pref.replace(0,pref.size(),pref.size(),' ');
1355 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1359 //=========================================================================
1378 static bool bbmgGlobalProcessingExecutionList = false;
1380 //=========================================================================
1381 void BlackBox::bbGlobalProcessExecutionList()
1383 bbtkDebugMessage("process",3,
1384 "=> BlackBox::bbGlobalProcessExecutionList()"
1386 if (bbmgGlobalProcessingExecutionList)
1388 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1391 bbmgGlobalProcessingExecutionList = true;
1393 std::set<BlackBox::WeakPointer>::iterator i;
1394 while (bbmgExecutionList.size()>0)
1396 i = bbmgExecutionList.begin();
1397 BlackBox::WeakPointer p = *i;
1398 bbmgExecutionList.erase(i);
1401 bbtkDebugMessage("process",4,
1403 p.lock()->bbGetName()<<"'"<<std::endl);
1404 p.lock()->bbExecute(true);
1408 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1412 bbmgExecutionList.clear();
1413 bbtkDebugMessage("process",3,
1414 "<= BlackBox::bbGlobalProcessExecutionList()"
1417 bbmgGlobalProcessingExecutionList = false;
1420 //=========================================================================
1422 bool BlackBox::bbGlobalGetSomeBoxExecuting()
1424 return bbmgSomeBoxExecuting;
1427 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
1429 bbmgSomeBoxExecuting = b;
1432 void BlackBox::bbGlobalSetFreezeExecution(bool b)
1434 bbmgFreezeExecution = b;
1437 bool BlackBox::bbGlobalGetFreezeExecution()
1439 return bbmgFreezeExecution;
1442 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1444 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
1445 if (bbmgGlobalProcessingExecutionList)
1447 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1449 bbmgExecutionList.insert(b);
1453 //=========================================================================
1455 //=========================================================================
1456 void BlackBox::Check(bool recursive)
1458 bbtkBlackBoxMessage("debug",1,"*** Checking"
1459 <<" ... OK"<<std::endl);
1461 //=========================================================================
1466 } // EO namespace bbtk