1 /*=========================================================================
3 Module: $RCSfile: bbtkBlackBox.cxx,v $
5 Date: $Date: 2011/07/02 08:00:34 $
6 Version: $Revision: 1.53 $
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
353 return ( bbGlobalGetSomeBoxExecuting()
355 || Wx::IsSomeWindowAlive()
359 //=========================================================================
363 //=========================================================================
364 BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
366 const std::string& p = bbmBoxProcessMode;
368 (p == "P") || (p == "p") ||
369 (p == "Pipeline") || (p == "pipeline") ) return bbPipeline;
371 (p == "A") || (p == "a") ||
372 (p == "Always") || (p == "always") ) return bbAlways;
374 (p == "R") || (p == "r") ||
375 (p == "Reactive") || (p == "reactive") )
379 (p == "F") || (p == "f") ||
380 (p == "Flash") || (p == "flash") ) return Flash;
382 bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
383 <<"' unknown. Possible values : "
384 <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
385 <<"'1'/'A'/'a'/'Always'/'always' | "
386 <<"'2'/'R'/'r'/'Reactive'/'reactive'"
387 // <<"'3'/'F'/'f'/'Flash'/'flash'"
390 //=========================================================================
392 //=========================================================================
393 bool BlackBox::bbBoxProcessModeIsReactive() const
395 return (bbGetBoxProcessModeValue() == bbReactive);
397 //=========================================================================
399 //=========================================================================
400 bool BlackBox::bbBoxProcessModeIsAlways() const
402 return (bbGetBoxProcessModeValue() == bbAlways);
404 //=========================================================================
409 //=========================================================================
410 void BlackBox::bbAddOutputObserver(const std::string& output,
411 OutputChangeCallbackType f)
413 bbGetOutputConnector(output).AddChangeObserver(f);
415 //=========================================================================
417 //=========================================================================
418 void BlackBox::bbRemoveOutputObserver(const std::string& output_name,
419 OutputChangeCallbackType f)
421 bbtkError("BlackBox::RemoveChangeObserver NOT IMPLEMENTED");
423 //=========================================================================
426 //=========================================================================
427 void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
430 bbtkBlackBoxDebugMessage("change",5,
431 "=> BlackBox::bbSetStatusAndPropagate(input,"
432 <<GetIOStatusString(s)<<")"
435 if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
440 if (bbGetBoxProcessModeValue() == Flash)
446 OutputConnectorMapType::const_iterator o;
447 for ( o = bbGetOutputConnectorMap().begin();
448 o != bbGetOutputConnectorMap().end(); ++o )
450 if (o->second->GetStatus()==UPTODATE)
452 o->second->SetStatus(OUTOFDATE);
453 o->second->SignalChange(GetThisPointer<BlackBox>(),o->first);
458 if ( ( bbBoxProcessModeIsReactive() || (c==bbGetInputConnectorMap().find("BoxExecute")->second))
461 bbtkBlackBoxDebugMessage("change",2,
462 "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
463 bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
465 bbtkBlackBoxDebugMessage("change",5,
466 "<= BlackBox::bbSetStatusAndPropagate(input)"
469 //=========================================================================
472 //=========================================================================
473 void BlackBox::bbSignalOutputModification(bool reaction)
475 bbtkBlackBoxDebugMessage("change",5,
476 "=> BlackBox::bbSignalOutputModification("
481 OutputConnectorMapType::iterator i;
482 for ( i = bbGetOutputConnectorMap().begin();
483 i != bbGetOutputConnectorMap().end(); ++i)
485 // std::cout << "Stat = "
486 //<<GetIOStatusString(i->second->GetStatus())
488 // LG : CANNOT SIGNAL ONLY WHEN UPTODATE
489 // See bbtkSampleOutputObserver
490 // if (i->second->GetStatus()==UPTODATE)
492 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
498 bbGlobalProcessExecutionList();
501 bbtkBlackBoxDebugMessage("change",5,
502 "<= BlackBox::bbSignalOutputModification()"
505 //=========================================================================
509 //=========================================================================
510 void BlackBox::bbSignalOutputModification(const std::string& output,
513 bbtkBlackBoxDebugMessage("change",5,
514 "=> BlackBox::bbSignalOutputModification("
515 <<output<<","<<reaction<<")"
518 OutputConnectorMapType::iterator i =
519 bbGetOutputConnectorMap().find(output);
522 if ( i == bbGetOutputConnectorMap().end() )
524 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
527 // if (i->second->GetStatus()==UPTODATE)
529 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
530 // Has to notify the output "BoxChange" also
531 if (output != "BoxChange")
533 i = bbGetOutputConnectorMap().find("BoxChange");
534 if ( i != bbGetOutputConnectorMap().end() )
536 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
539 if (reaction) bbGlobalProcessExecutionList();
542 bbtkBlackBoxDebugMessage("change",5,
543 "<= BlackBox::bbSignalOutputModification("
547 //=========================================================================
548 //=========================================================================
549 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
552 bbtkBlackBoxDebugMessage("change",5,
553 "=> BlackBox::bbSignalOutputModification(vector of outputs)"
555 OutputConnectorMapType::iterator i;
556 std::vector<std::string>::const_iterator o;
557 bool changed = false;
558 for (o=output.begin();o!=output.end();++o)
560 // the output "BoxChange" must be signaled **AFTER** all others
561 if (*o == "BoxChange") continue;
562 // Look for the connector
563 i = bbGetOutputConnectorMap().find(*o);
564 if ( i == bbGetOutputConnectorMap().end() )
566 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
569 // if (i->second->GetStatus()==UPTODATE)
571 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
575 // Has to notify the output "BoxChange" also
576 i = bbGetOutputConnectorMap().find("BoxChange");
577 if ( changed && (i != bbGetOutputConnectorMap().end()))
579 // if (i->second->GetStatus()==UPTODATE)
581 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
582 if (reaction) bbGlobalProcessExecutionList();
586 bbtkBlackBoxDebugMessage("change",5,
587 "<= 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);
738 //=========================================================================
744 //=========================================================================
745 IOStatus BlackBox::bbUpdateInputs()
747 bbtkBlackBoxDebugMessage("process",4,
748 "=> BlackBox::bbUpdateInputs()"
751 IOStatus s = UPTODATE;
753 InputConnectorMapType::iterator i;
754 for ( i = bbGetInputConnectorMap().begin();
755 i!= bbGetInputConnectorMap().end(); ++i)
757 // if (i->first=="WinHide") continue;
758 // If input type is Void : no recurse
759 //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo()
762 bbtkBlackBoxDebugMessage("change",2,
764 <<"': status before update = '"
765 <<GetIOStatusString(i->second->GetStatus())
767 i->second->RecursiveExecute();
768 IOStatus t = i->second->GetStatus();
770 bbtkBlackBoxDebugMessage("change",2,
772 <<"': status before process = '"
773 <<GetIOStatusString(i->second->GetStatus())
777 bbtkBlackBoxDebugMessage("process",4,
778 "<= BlackBox::bbUpdateInputs()"
782 //=========================================================================
784 //==================================================================
785 void BlackBox::bbComputePostProcessStatus()
787 bbtkBlackBoxDebugMessage("process",4,
788 "=> BlackBox::bbComputePostProcessStatus()"
791 IOStatus new_output_status = UPTODATE;
792 if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
794 // Update the input statuses
795 InputConnectorMapType::iterator i;
796 for ( i = bbGetInputConnectorMap().begin();
797 i!= bbGetInputConnectorMap().end(); ++i)
799 IOStatus t = i->second->GetStatus();
800 if (t == OUTOFDATE) new_output_status = OUTOFDATE;
801 // A previously MODIFIED status turns to UPTODATE
802 if (t==MODIFIED) i->second->SetStatus(UPTODATE);
803 bbtkBlackBoxDebugMessage("change",2,
804 "Input '"<<i->first<<"' : "
805 << GetIOStatusString(t) << " -> "
806 << GetIOStatusString(i->second->GetStatus())
809 bbtkBlackBoxDebugMessage("change",2,
810 "New output status : "
811 << GetIOStatusString(new_output_status)
813 // Update the output statuses
814 OutputConnectorMapType::iterator o;
815 for ( o = bbGetOutputConnectorMap().begin();
816 o!= bbGetOutputConnectorMap().end(); ++o)
818 o->second->SetStatus(new_output_status);
821 bbtkBlackBoxDebugMessage("process",4,
822 "<= BlackBox::bbComputePostProcessStatus()"
825 //==================================================================
827 //=========================================================================
828 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
830 bbtkBlackBoxDebugMessage("connection",2,
831 "==> BlackBox::bbConnectInput(\""
832 <<name<<"\","<<c->GetFullName()<<")"
835 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
836 if (i==bbGetInputConnectorMap().end())
838 bbtkError("no input called '"<<name<<"'");
840 i->second->SetConnection(c);
841 // The input *MUST* be set OUTOFDATE to update its input on next execution
842 bbSetStatusAndPropagate(i->second,OUTOFDATE);
844 bbtkBlackBoxDebugMessage("connection",2,
845 "<== BlackBox::bbConnectInput(\""
846 <<name<<"\","<<c->GetFullName()<<")"
849 //=========================================================================
852 //=========================================================================
853 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
855 bbtkBlackBoxDebugMessage("connection",2,
856 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
857 <<c->GetFullName()<<")"
860 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
861 if (i==bbGetOutputConnectorMap().end())
863 bbtkError("no output called '"<<name<<"'");
865 i->second->SetConnection(c);
867 bbtkBlackBoxDebugMessage("connection",2,
868 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
869 <<c->GetFullName()<<")"
872 //=========================================================================
875 //=========================================================================
876 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
879 bbtkBlackBoxDebugMessage("connection",2,
880 "==> BlackBox::bbDisconnectInput(\""<<name
881 <<"\","<<c->GetFullName()<<")"
886 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
890 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
891 if (i==bbGetInputConnectorMap().end())
893 bbtkError("no input called '"<<name<<"'");
895 i->second->UnsetConnection(c);
897 bbtkBlackBoxDebugMessage("connection",2,
898 "<== BlackBox::bbDisconnectInput(\""<<name
899 <<"\","<<c->GetFullName()<<")"
903 //=========================================================================
906 //=========================================================================
907 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
909 bbtkBlackBoxDebugMessage("connection",2,
910 "==> BlackBox::bbDisconnectOutput(\""<<name
911 <<"\","<<c->GetFullName()<<")"
916 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
920 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
921 if (i==bbGetOutputConnectorMap().end())
923 bbtkError("no output called '"<<name<<"'");
925 i->second->UnsetConnection(c);
927 bbtkBlackBoxDebugMessage("connection",2,
928 "<== BlackBox::bbDisconnectOutput(\""<<name
929 <<"\","<<c->GetFullName()<<")"
932 //=========================================================================
956 //=========================================================================
957 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
959 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
961 //=========================================================================
964 //=========================================================================
965 std::string BlackBox::bbGetOutputAsString( const std::string &output )
968 // Looks for the adaptor
969 if (bbGetOutputType(output).name() != typeid(std::string).name() )
972 Package::Pointer p = bbGetDescriptor()->GetPackage();
973 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
975 Factory::Pointer f = p->GetFactorySet().begin()->lock();
980 bbGetOutputType(output),
983 } catch (bbtk::Exception e)
988 a->bbSetInput("In",bbGetOutput(output));
990 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
992 v="? (no adaptor found)";
997 v="? (no factory found)";
1003 v = bbGetOutput(output).unsafe_get<std::string>() ;
1007 //=========================================================================
1009 //=========================================================================
1010 std::string BlackBox::bbGetInputAsString( const std::string &input )
1013 // Looks for the adaptor
1014 if (bbGetInputType(input) != typeid(std::string))
1017 Package::Pointer p = bbGetDescriptor()->GetPackage();
1018 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1020 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1021 BlackBox::Pointer a;
1025 bbGetInputType(input),
1026 typeid(std::string),
1028 }catch (bbtk::Exception e)
1034 a->bbSetInput("In",bbGetInput(input));
1036 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1040 v="? (no adaptor found)";
1045 v="? (no factory found)";
1050 v = bbGetInput(input).unsafe_get<std::string>() ;
1054 //=======================================================================
1056 //=======================================================================
1057 // Replaces substrings "<" by "["
1058 void SubsBrackets ( std::string& s )
1060 // std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1061 std::string ss("<");
1062 std::string::size_type pos = 0;
1064 std::string cr("[");
1065 while ( pos != std::string::npos )
1067 // std::cout << "*** find one "<<std::endl;
1068 s.replace(pos,1,cr.c_str(),1);
1069 pos = s.find(ss, pos);
1075 while ( pos != std::string::npos )
1077 // std::cout << "*** find one "<<std::endl;
1078 s.replace(pos,1,cr.c_str(),1);
1079 pos = s.find(ss, pos);
1085 while ( pos != std::string::npos )
1087 // std::cout << "*** find one "<<std::endl;
1088 s.replace(pos,1,cr.c_str(),1);
1089 pos = s.find(ss, pos);
1090 } // std::cout << "AFTER=["<<s<<"]"<<std::endl;
1092 //=======================================================================
1094 //=========================================================================
1095 /// Write Graphviz-dot description in file
1096 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1097 BlackBox::Pointer parentblackbox,
1098 int detail, int level,
1099 bool instanceOrtype,
1100 bool relative_link )
1103 InputConnectorMapType::iterator i;
1105 std::string labelStr;
1106 std::string valueStr("");
1109 labelStr = bbGetName() ;
1111 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1113 labelStr = bbGetName();
1114 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
1117 SubsBrackets(labelStr);
1120 labelStr = labelStr + " | {{ ";
1121 std::string tempStrTypeName;
1124 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1128 labelStr=labelStr+" | ";
1131 if (instanceOrtype==true)
1133 valueStr = this->bbGetInputAsString(i->first) + " = ";
1135 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1136 tempStrTypeName=id->GetTypeName();
1137 SubsBrackets(tempStrTypeName);
1138 std::string Name(i->first);
1140 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
1142 labelStr=labelStr+ " } | {";
1144 OutputConnectorMapType::iterator ii;
1145 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
1149 labelStr=labelStr+" | ";
1152 if (instanceOrtype==true)
1154 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1156 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
1157 tempStrTypeName=id->GetTypeName();
1158 SubsBrackets(tempStrTypeName);
1159 std::string Name(ii->first);
1161 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
1163 labelStr = labelStr+ " } }" ;
1167 bbWriteDotInputOutputName(ff,true,detail,level);
1168 std::string tmp ( bbGetTypeName() );
1172 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1174 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1176 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1177 // std::cout << labelStr << std::endl;
1180 if (GetThisPointer<BlackBox>()!=parentblackbox){
1181 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1185 Connection* con = i->second->GetConnection();
1187 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1188 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1190 a->bbWriteDotInputOutputName(ff,false,detail,level);
1193 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1196 b->bbWriteDotInputOutputName(ff,true,detail,level);
1199 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1201 fprintf(ff,"%s\n",";");
1205 } // if parentblackbox
1207 //=========================================================================
1212 //=========================================================================
1213 void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox,
1214 int detail, int level
1215 /*,Factory *factory*/ )
1218 if (this->bbGetDescriptor()->GetPackage())
1220 bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
1221 this->bbGetDescriptor()->GetPackage()->GetName()
1222 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1226 bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1231 bbtkBlackBoxMessage("help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1232 <<mMinOutputChangeTime<<"]"<<std::endl);
1236 bbtkBlackBoxMessage("help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1237 <<mMinOutputChangeTime<<"]"<<std::endl);
1240 // bbtkBlackBoxMessage("help",1," "<<GetDescription()<<std::endl);
1241 // bbtkBlackBoxMessage("help",1," By : "<<GetAuthor()<<std::endl);
1243 std::vector<std::string> iname;
1244 std::vector<std::string> ivalue;
1245 std::vector<std::string> iconn;
1246 std::vector<std::string> istatus;
1248 InputConnectorMapType::iterator i;
1249 unsigned int namelmax = 0;
1250 unsigned int valuelmax = 0;
1251 // unsigned int connlmax = 0;
1252 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1254 iname.push_back(i->first);
1255 if (iname.back().size()>namelmax) namelmax = iname.back().size();
1256 ivalue.push_back(bbGetInputAsString(i->first));
1257 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1259 Connection* con = i->second->GetConnection();
1261 s = con->GetOriginalBlackBoxFrom()->bbGetName();
1263 s += con->GetOriginalBlackBoxFromOutput();
1266 istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1268 OutputConnectorMapType::iterator o;
1269 std::vector<std::string> oname;
1270 std::vector<std::string> ovalue;
1271 std::vector<std::vector<std::string> > oconn;
1272 std::vector<std::string> ostatus;
1273 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
1275 oname.push_back(o->first);
1276 if (oname.back().size()>namelmax) namelmax = oname.back().size();
1277 ovalue.push_back(bbGetOutputAsString(o->first));
1278 if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size();
1279 std::vector<std::string> ss;
1280 const std::vector<Connection*>& con
1281 = o->second->GetConnectionVector();
1282 std::vector<Connection*>::const_iterator c;
1283 for (c=con.begin();c!=con.end();++c)
1286 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1288 s += (*c)->GetOriginalBlackBoxToInput();
1291 oconn.push_back(ss);
1292 ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1296 bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
1298 bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
1300 std::vector<std::string>::iterator i1,i2,i3,i4;
1301 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1302 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1303 ++i1,++i2,++i3,++i4)
1305 std::string name(*i1);
1307 name.append(1+namelmax-name.size(),' ');
1308 std::string value(*i2);
1310 value.append(1+valuelmax-value.size(),' ');
1312 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value<<" <-- '"
1315 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1316 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1320 bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
1322 bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
1324 std::vector<std::vector<std::string> >::iterator i5;
1326 for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1327 i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1328 ++i1,++i2,++i4,++i5)
1330 std::string name(*i1);
1332 name.append(1+namelmax-name.size(),' ');
1333 std::string value(*i2);
1335 value.append(1+valuelmax-value.size(),' ');
1337 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1340 std::string pref = " '"+name+" = '"+value;
1341 for (i3=i5->begin();i3!=i5->end();++i3)
1343 bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
1344 pref.replace(0,pref.size(),pref.size(),' ');
1347 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1351 //=========================================================================
1370 static bool bbmgGlobalProcessingExecutionList = false;
1372 //=========================================================================
1373 void BlackBox::bbGlobalProcessExecutionList()
1375 bbtkDebugMessage("process",3,
1376 "=> BlackBox::bbGlobalProcessExecutionList()"
1378 if (bbmgGlobalProcessingExecutionList)
1380 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1383 bbmgGlobalProcessingExecutionList = true;
1385 std::set<BlackBox::WeakPointer>::iterator i;
1386 while (bbmgExecutionList.size()>0)
1388 i = bbmgExecutionList.begin();
1389 BlackBox::WeakPointer p = *i;
1390 bbmgExecutionList.erase(i);
1393 bbtkDebugMessage("process",4,
1395 p.lock()->bbGetName()<<"'"<<std::endl);
1396 p.lock()->bbExecute(true);
1400 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1404 bbmgExecutionList.clear();
1405 bbtkDebugMessage("process",3,
1406 "<= BlackBox::bbGlobalProcessExecutionList()"
1409 bbmgGlobalProcessingExecutionList = false;
1412 //=========================================================================
1414 bool BlackBox::bbGlobalGetSomeBoxExecuting()
1416 return bbmgSomeBoxExecuting;
1419 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
1421 bbmgSomeBoxExecuting = b;
1424 void BlackBox::bbGlobalSetFreezeExecution(bool b)
1426 bbmgFreezeExecution = b;
1429 bool BlackBox::bbGlobalGetFreezeExecution()
1431 return bbmgFreezeExecution;
1434 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1436 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
1437 if (bbmgGlobalProcessingExecutionList)
1439 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1441 bbmgExecutionList.insert(b);
1445 //=========================================================================
1447 //=========================================================================
1448 void BlackBox::Check(bool recursive)
1450 bbtkBlackBoxMessage("debug",1,"*** Checking"
1451 <<" ... OK"<<std::endl);
1453 //=========================================================================
1458 } // EO namespace bbtk