2 # ---------------------------------------------------------------------
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
10 # This software is governed by the CeCILL-B license under French law and
11 # abiding by the rules of distribution of free software. You can use,
12 # modify and/ or redistribute the software under the terms of the CeCILL-B
13 # license as circulated by CEA, CNRS and INRIA at the following URL
14 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 # or in the file LICENSE.txt.
17 # As a counterpart to the access to the source code and rights to copy,
18 # modify and redistribute granted by the license, users are provided only
19 # with a limited warranty and the software's author, the holder of the
20 # economic rights, and the successive licensors have only limited
23 # The fact that you are presently reading this means that you have had
24 # knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------ */
28 /*=========================================================================
30 Module: $RCSfile: bbtkBlackBox.cxx,v $
32 Date: $Date: 2012/11/16 08:49:01 $
33 Version: $Revision: 1.56 $
34 =========================================================================*/
40 * \brief Class bbtk::BlackBox : abstract black-box interface.
42 #include "bbtkBlackBox.h"
43 #include "bbtkPackage.h"
44 #include "bbtkMessageManager.h"
45 #include "bbtkFactory.h"
46 #include "bbtkBlackBoxOutputConnector.h"
48 #include "bbtkConfigurationFile.h"
49 #include "bbtkWxBlackBox.h"
58 static bool bbmgSomeBoxExecuting = false;
59 static bool bbmgFreezeExecution = false;
60 static std::set<BlackBox::WeakPointer> bbmgExecutionList;
62 //=========================================================================
64 BlackBox::Deleter::Deleter()
67 //=========================================================================
69 //=========================================================================
70 int BlackBox::Deleter::Delete(Object* p)
72 BlackBox* b = dynamic_cast<BlackBox*>(p);
75 bbtkInternalError("BlackBox::Deleter::Delete("<<p->GetObjectName()
77 <<"dynamic cast to BlackBox* failed !");
79 std::string name = p->GetObjectName();//b->bbGetNameWithParent();
80 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
83 BlackBoxDescriptor::WeakPointer desc = b->bbGetDescriptor();
84 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : deleting black box"<<std::endl);
86 int refs = b->bbDelete();
88 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : releasing descriptor"<<std::endl);
92 Package::WeakPointer pack = desc.lock()->GetPackage();
95 Package::ReleaseBlackBoxDescriptor(pack,desc);
99 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor package expired (was not held by a package and the box was the last instance)"<<std::endl);
104 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);
106 bbtkDebugMessage("object",2,"<## BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
109 //=========================================================================
111 //=========================================================================
112 BlackBox::BlackBox(const std::string &name)
114 // bbmStatus(MODIFIED),
115 bbmInitialized(false),
118 bbmBoxProcessMode("Pipeline"),
119 bbLetRecursiveExecuteManualMode(false),
124 // bbmBoxProcessMode = "Pipeline";
125 //std::cout<<"JCP BlackBox::BlackBox(const std::string &name) name=" <<name
126 // <<"bbmBoxProcessMode="<<bbmBoxProcessMode<<std::endl;
127 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox(\""
128 <<name<<"\")"<<std::endl);
129 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox(\""
130 <<name<<"\")"<<std::endl);
132 //=========================================================================
134 //=========================================================================
135 BlackBox::BlackBox(const BlackBox&)
138 //=========================================================================
139 BlackBox::BlackBox(BlackBox& from, const std::string &name)
141 // bbmStatus(from.bbmStatus),
142 bbmInitialized(false),
145 bbmBoxProcessMode(from.bbmBoxProcessMode),
146 bbLetRecursiveExecuteManualMode(false),
151 //bbmBoxProcessMode = from.bbmBoxProcessMode;
152 //std::cout<<"JCP BlackBox::BlackBox(const std::string &name) name=" <<name
153 // <<"bbmBoxProcessMode="<<bbmBoxProcessMode<<std::endl;
154 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox("
155 <<from.bbGetFullName()<<",\""
156 <<name<<"\")"<<std::endl);
157 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox("
158 <<from.bbGetFullName()<<",\""
159 <<name<<"\")"<<std::endl);
161 //=========================================================================
164 //=========================================================================
165 BlackBox::~BlackBox()
167 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::~BlackBox() ["<<bbmName
169 this->bbDesallocateConnectors();
170 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::~BlackBox() ["<<bbmName
173 //=========================================================================
177 //=========================================================================
178 std::string BlackBox::bbGetFullName() const
180 return this->bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
182 //=========================================================================
186 //=========================================================================
187 std::string BlackBox::bbGetNameWithParent() const
189 if (bbmParent.lock())
191 return bbmParent.lock()->bbGetNameWithParent() + ":" + bbmName;
198 //=========================================================================
200 //=========================================================================
201 void BlackBox::bbGetHelp(bool full) const
203 bbGetDescriptor()->GetHelp(full);
205 //=========================================================================
208 //=========================================================================
209 bool BlackBox::bbHasInput(const std::string& name) const
211 bbtkBlackBoxDebugMessage("kernel",8,
212 "BlackBox::bbHasInput(\""
215 bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
216 != bbGetDescriptor()->GetInputDescriptorMap().end());
217 bbtkDebugDecTab("kernel",8);
220 //=========================================================================
223 //=========================================================================
224 bool BlackBox::bbHasOutput(const std::string& name) const
226 bbtkBlackBoxDebugMessage("kernel",8,"BlackBox::bbHasOutput(\""
229 bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
230 != bbGetDescriptor()->GetOutputDescriptorMap().end());
231 bbtkDebugDecTab("kernel",8);
234 //=========================================================================
237 //=========================================================================
238 TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const
240 bbtkBlackBoxDebugMessage("kernel",8,
241 "BlackBox::bbGetOutputType(\""
244 TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
245 bbtkDebugDecTab("kernel",8);
248 //=========================================================================
250 //=========================================================================
251 TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
253 bbtkBlackBoxDebugMessage("kernel",8,
254 "BlackBox::bbGetInputType(\""
257 TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
258 bbtkDebugDecTab("kernel",8);
261 //=========================================================================
264 //=========================================================================
265 void BlackBox::bbAllocateConnectors()
267 bbtkBlackBoxDebugMessage("kernel",8,
268 "BlackBox::bbAllocateConnectors()"
271 MakeBlackBoxPointer(this,true);
273 const BlackBoxDescriptor::InputDescriptorMapType& imap
274 = bbGetDescriptor()->GetInputDescriptorMap();
275 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
276 for ( i = imap.begin(); i != imap.end(); ++i )
278 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
279 bbGetInputConnectorMap()[i->second->GetName()]
280 = new BlackBoxInputConnector(GetThisPointer<BlackBox>());
282 const BlackBoxDescriptor::OutputDescriptorMapType& omap
283 = bbGetDescriptor()->GetOutputDescriptorMap();
284 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
285 for ( o = omap.begin(); o != omap.end(); ++o )
287 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
288 bbGetOutputConnectorMap()[o->second->GetName()]
289 = new BlackBoxOutputConnector(GetThisPointer<BlackBox>());
292 //=========================================================================
295 //=========================================================================
296 void BlackBox::bbDesallocateConnectors()
298 bbtkBlackBoxDebugMessage("kernel",8,
299 "BlackBox::bbDesallocateConnectors()"
302 InputConnectorMapType::const_iterator i;
303 for ( i = bbGetInputConnectorMap().begin();
304 i != bbGetInputConnectorMap().end(); ++i )
306 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<i->first<<"\""<<std::endl);
309 OutputConnectorMapType::const_iterator o;
310 for ( o = bbGetOutputConnectorMap().begin();
311 o != bbGetOutputConnectorMap().end(); ++o )
313 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<o->first<<"\""<<std::endl);
317 bbtkDebugDecTab("kernel",8);
319 //=========================================================================
322 //=========================================================================
323 void BlackBox::bbCopyIOValues(BlackBox& from)
325 bbtkBlackBoxDebugMessage("kernel",1,
326 "BlackBox::bbCopyIOValues("
327 <<from.bbGetFullName()<<")"
329 // copies the input values
330 const BlackBoxDescriptor::InputDescriptorMapType& imap
331 = bbGetDescriptor()->GetInputDescriptorMap();
332 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
333 for ( i = imap.begin(); i != imap.end(); ++i )
335 if (! i->second->GetCopyConstruct() ) continue;
336 std::string input = i->second->GetName();
337 bbtkBlackBoxDebugMessage("kernel",2,"* Copying input "<<input<<std::endl);
338 this->bbSetInput(input, from.bbGetInput(input) );
340 // copies the output values
341 const BlackBoxDescriptor::OutputDescriptorMapType& omap
342 = bbGetDescriptor()->GetOutputDescriptorMap();
343 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
344 for ( o = omap.begin(); o != omap.end(); ++o )
346 if (! o->second->GetCopyConstruct() ) continue;
347 std::string output = o->second->GetName();
348 bbtkBlackBoxDebugMessage("kernel",2,"* Copying output "<<output<<std::endl);
349 this->bbSetOutput(output, from.bbGetOutput(output) );
352 bbtkDebugDecTab("kernel",9);
354 //=========================================================================
358 //=========================================================================
359 bool BlackBox::bbCanReact() const
361 return ( bbGlobalGetSomeBoxExecuting()
363 || Wx::IsSomeWindowAlive()
367 //=========================================================================
371 //=========================================================================
372 BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
374 const std::string& p = bbmBoxProcessMode;
376 (p == "P") || (p == "p") ||
377 (p == "Pipeline") || (p == "pipeline") ) return bbPipeline;
379 (p == "A") || (p == "a") ||
380 (p == "Always") || (p == "always") ) return bbAlways;
382 (p == "R") || (p == "r") ||
383 (p == "Reactive") || (p == "reactive") )
387 (p == "F") || (p == "f") ||
388 (p == "Flash") || (p == "flash") ) return Flash;
392 (p == "M") || (p == "m") ||
393 (p == "Manual") || (p == "manual") ) return bbManual;
395 bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
396 <<"' unknown. Possible values : "
397 <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
398 <<"'1'/'A'/'a'/'Always'/'always' | "
399 <<"'2'/'R'/'r'/'Reactive'/'reactive'"
400 // <<"'3'/'F'/'f'/'Flash'/'flash'"
401 <<"'3'/'M'/'m'/'Manual'/'manual'"
404 //=========================================================================
406 //=========================================================================
407 bool BlackBox::bbBoxProcessModeIsReactive() const
409 return (bbGetBoxProcessModeValue() == bbReactive);
411 //=========================================================================
413 //=========================================================================
414 bool BlackBox::bbBoxProcessModeIsAlways() const
416 return (bbGetBoxProcessModeValue() == bbAlways);
418 //=========================================================================
421 //=========================================================================
422 bool BlackBox::bbBoxProcessModeIsManual() const
424 return (bbGetBoxProcessModeValue() == bbManual);
426 //=========================================================================
429 //=========================================================================
430 void BlackBox::bbAddOutputObserver(const std::string& output,
431 OutputChangeCallbackType f)
433 bbGetOutputConnector(output).AddChangeObserver(f);
435 //=========================================================================
437 //=========================================================================
438 void BlackBox::bbRemoveOutputObserver(const std::string& output_name,
439 OutputChangeCallbackType f)
441 bbtkError("BlackBox::RemoveChangeObserver NOT IMPLEMENTED");
443 //=========================================================================
446 //=========================================================================
447 void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
450 bbtkBlackBoxDebugMessage("change",5,
451 "=> BlackBox::bbSetStatusAndPropagate(input,"
452 <<GetIOStatusString(s)<<")"
455 if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
460 if (bbGetBoxProcessModeValue() == Flash)
467 OutputConnectorMapType::const_iterator o;
468 for ( o = bbGetOutputConnectorMap().begin();
469 o != bbGetOutputConnectorMap().end(); ++o )
473 if (o->first=="BoxChange")
475 o->second->SetStatus(UPTODATE);
482 if (o->second->GetStatus()==UPTODATE)
483 // if ((o->second->GetStatus()==UPTODATE) || (o->second->GetStatus()==OUTOFDATE))
484 // if ((o->second->GetStatus()==UPTODATE) || (o->second->GetStatus()==MODIFIED))
486 o->second->SetStatus(OUTOFDATE);
487 o->second->SignalChange(GetThisPointer<BlackBox>(),o->first);
492 if ( ( bbBoxProcessModeIsReactive()
493 || (c==bbGetInputConnectorMap().find("BoxExecute")->second))
496 bbtkBlackBoxDebugMessage("change",2,
497 "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
498 bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
500 bbtkBlackBoxDebugMessage("change",5,
501 "<= BlackBox::bbSetStatusAndPropagate(input)"
504 //=========================================================================
507 //=========================================================================
508 void BlackBox::bbSignalOutputModification(bool reaction)
510 bbtkBlackBoxDebugMessage("change",5,
511 "=> BlackBox::bbSignalOutputModification("
515 OutputConnectorMapType::iterator i;
516 for ( i = bbGetOutputConnectorMap().begin();
517 i != bbGetOutputConnectorMap().end(); ++i)
519 // std::cout << "Stat = "
520 //<<GetIOStatusString(i->second->GetStatus())
522 // LG : CANNOT SIGNAL ONLY WHEN UPTODATE
523 // See bbtkSampleOutputObserver
524 // if (i->second->GetStatus()==UPTODATE)
526 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
530 if (reaction) bbGlobalProcessExecutionList();
532 bbtkBlackBoxDebugMessage("change",5,
533 "<= BlackBox::bbSignalOutputModification()"
536 //=========================================================================
539 //=========================================================================
540 void BlackBox::bbSignalOutputModification(const std::string& output,
543 bbtkBlackBoxDebugMessage("change",5,
544 "=> BlackBox::bbSignalOutputModification("
545 <<output<<","<<reaction<<")"
548 OutputConnectorMapType::iterator i =
549 bbGetOutputConnectorMap().find(output);
552 if ( i == bbGetOutputConnectorMap().end() )
554 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
557 // if (i->second->GetStatus()==UPTODATE)
559 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
560 // Has to notify the output "BoxChange" also
561 if (output != "BoxChange")
563 i = bbGetOutputConnectorMap().find("BoxChange");
564 if ( i != bbGetOutputConnectorMap().end() )
566 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
569 if (reaction) bbGlobalProcessExecutionList();
572 bbtkBlackBoxDebugMessage("change",5,
573 "<= BlackBox::bbSignalOutputModification("
577 //=========================================================================
578 //=========================================================================
579 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
582 bbtkBlackBoxDebugMessage("change",5,
583 "=> BlackBox::bbSignalOutputModification(vector of outputs)"
585 OutputConnectorMapType::iterator i;
586 std::vector<std::string>::const_iterator o;
587 bool changed = false;
588 for (o=output.begin();o!=output.end();++o)
590 // the output "BoxChange" must be signaled **AFTER** all others
591 if (*o == "BoxChange") continue;
592 // Look for the connector
593 i = bbGetOutputConnectorMap().find(*o);
594 if ( i == bbGetOutputConnectorMap().end() )
596 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
599 // if (i->second->GetStatus()==UPTODATE)
601 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
605 // Has to notify the output "BoxChange" also
606 i = bbGetOutputConnectorMap().find("BoxChange");
607 if ( changed && (i != bbGetOutputConnectorMap().end()))
609 // if (i->second->GetStatus()==UPTODATE)
611 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
612 if (reaction) bbGlobalProcessExecutionList();
616 bbtkBlackBoxDebugMessage("change",5,
617 "<= BlackBox::bbSignalOutputModification(vector of outputs)"
620 //=========================================================================
628 //=========================================================================
629 /// Main processing method of the box.
630 void BlackBox::bbExecute(bool force)
632 bbtkBlackBoxDebugMessage("process",2,
633 "=> BlackBox::bbExecute("<<(int)force<<")"
636 // If already executing : return
638 if (bbGetExecuting())
640 bbtkBlackBoxDebugMessage("process",2,
641 " -> already executing : abort"<<std::endl);
646 // If execution frozen : return
647 if (bbGlobalGetFreezeExecution())
649 bbtkBlackBoxDebugMessage("process",2,
650 " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
655 // If force is true then update is triggered even if the box is UPTODATE
656 // if (force) bbSetModifiedStatus();
658 if ( bbBoxProcessModeIsManual() )
660 bbLetRecursiveExecuteManualMode = true;
664 // Calls the main recursive execution method
665 bbRecursiveExecute(Connection::Pointer());
668 if ( bbBoxProcessModeIsManual() )
670 bbLetRecursiveExecuteManualMode = false;
674 bbtkBlackBoxDebugMessage("process",2,
675 "<= BlackBox::bbExecute()"
678 //=========================================================================
680 //=========================================================================
681 void BlackBox::bbInitializeProcessing()
685 bbtkBlackBoxDebugMessage("process",2,"** Initialize processing"
687 this->bbRecursiveInitializeProcessing();
688 bbmInitialized = true;
691 //=========================================================================
693 //=========================================================================
694 void BlackBox::bbFinalizeProcessing()
698 bbtkBlackBoxDebugMessage("process",2,"** Finalize processing"
700 this->bbRecursiveFinalizeProcessing();
701 bbmInitialized = false;
704 //=========================================================================
707 //=========================================================================
708 void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
711 bbtkBlackBoxDebugMessage("process",3,
712 "=> BlackBox::bbRecursiveExecute("
713 <<(caller?caller->GetFullName():"0")<<")"
716 // If already executing : return
717 if (bbGetExecuting())
719 bbtkBlackBoxDebugMessage("process",3,
720 " -> already executing : abort"<<std::endl);
724 // If not initialized do it
725 bbInitializeProcessing();
727 bbSetExecuting(true);
728 bool wasExecuting = bbGlobalGetSomeBoxExecuting();
729 bbGlobalSetSomeBoxExecuting(true);
731 // Creates the window if the black box has one
732 this->bbCreateWindow();
734 // Updates its inputs
738 // IOStatus s=OUTOFDATE;
739 // IOStatus s=MODIFIED;
742 if ( ( bbBoxProcessModeIsManual()==false ) ||
743 ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) ) )
745 s = bbUpdateInputs();
748 if ( (s != UPTODATE) || bbBoxProcessModeIsAlways() )
750 // Displays the window (WxBlackbox)
751 // bbShowWindow(caller);
753 // Actual processing (virtual)
754 if ( ( bbBoxProcessModeIsManual()==false ) ||
755 ( (bbBoxProcessModeIsManual()==true)&&(bbLetRecursiveExecuteManualMode==true) )
761 //EED ups if ((bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false))
763 //EED ups bbSignalOutputModification(true);
767 // Update the I/O statuses
768 bbComputePostProcessStatus();
772 // Test output status...
773 OutputConnectorMapType::iterator o;
774 for ( o = bbGetOutputConnectorMap().begin();
775 o!= bbGetOutputConnectorMap().end(); ++o)
777 if (o->second->GetStatus() != UPTODATE)
779 bbtkWarning("BlackBox::bbRecursiveExecute: "
780 <<"all inputs are Up-to-date but output '"
781 <<o->first<<"' is Out-of-date ???");
785 bbtkBlackBoxDebugMessage("process",3," -> Up-to-date : nothing to do"
789 // Shows the window if the black box has one
790 this->bbShowWindow();
793 bbtkBlackBoxDebugMessage("process",3,
794 "<= BlackBox::bbRecursiveExecute()"
797 bbSetExecuting(false);
798 bbGlobalSetSomeBoxExecuting(wasExecuting);
803 //=========================================================================
809 //=========================================================================
810 IOStatus BlackBox::bbUpdateInputs()
812 bbtkBlackBoxDebugMessage("process",4,
813 "=> BlackBox::bbUpdateInputs()"
816 IOStatus s = UPTODATE;
818 InputConnectorMapType::iterator i;
819 for ( i = bbGetInputConnectorMap().begin();
820 i!= bbGetInputConnectorMap().end(); ++i)
822 // if (i->first=="WinHide") continue;
823 // If input type is Void : no recurse
824 //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo()
827 bbtkBlackBoxDebugMessage("change",2,
829 <<"': status before update = '"
830 <<GetIOStatusString(i->second->GetStatus())
832 i->second->RecursiveExecute();
833 IOStatus t = i->second->GetStatus();
835 bbtkBlackBoxDebugMessage("change",2,
837 <<"': status before process = '"
838 <<GetIOStatusString(i->second->GetStatus())
842 bbtkBlackBoxDebugMessage("process",4,
843 "<= BlackBox::bbUpdateInputs()"
847 //=========================================================================
849 //==================================================================
850 void BlackBox::bbComputePostProcessStatus()
852 bbtkBlackBoxDebugMessage("process",4,
853 "=> BlackBox::bbComputePostProcessStatus()"
856 IOStatus new_output_status = UPTODATE;
857 if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
859 // Update the input statuses
860 InputConnectorMapType::iterator i;
861 for ( i = bbGetInputConnectorMap().begin();
862 i!= bbGetInputConnectorMap().end(); ++i)
864 IOStatus t = i->second->GetStatus();
865 if (t == OUTOFDATE) new_output_status = OUTOFDATE;
866 // A previously MODIFIED status turns to UPTODATE
867 if (t==MODIFIED) i->second->SetStatus(UPTODATE);
868 bbtkBlackBoxDebugMessage("change",2,
869 "Input '"<<i->first<<"' : "
870 << GetIOStatusString(t) << " -> "
871 << GetIOStatusString(i->second->GetStatus())
874 bbtkBlackBoxDebugMessage("change",2,
875 "New output status : "
876 << GetIOStatusString(new_output_status)
878 // Update the output statuses
879 OutputConnectorMapType::iterator o;
880 for ( o = bbGetOutputConnectorMap().begin();
881 o!= bbGetOutputConnectorMap().end(); ++o)
884 //EED if ( ( bbBoxProcessModeIsManual()==false ) ||
885 //EED ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) )
888 o->second->SetStatus(new_output_status);
890 //EED if (( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false) ) )
892 //EED o->second->SetStatus(UPTODATE);
894 //EED } // Manual analysis
898 bbtkBlackBoxDebugMessage("process",4,
899 "<= BlackBox::bbComputePostProcessStatus()"
902 //==================================================================
904 //=========================================================================
905 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
907 bbtkBlackBoxDebugMessage("connection",2,
908 "==> BlackBox::bbConnectInput(\""
909 <<name<<"\","<<c->GetFullName()<<")"
912 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
913 if (i==bbGetInputConnectorMap().end())
915 bbtkError("no input called '"<<name<<"'");
917 i->second->SetConnection(c);
918 // The input *MUST* be set OUTOFDATE to update its input on next execution
919 bbSetStatusAndPropagate(i->second,OUTOFDATE);
921 bbtkBlackBoxDebugMessage("connection",2,
922 "<== BlackBox::bbConnectInput(\""
923 <<name<<"\","<<c->GetFullName()<<")"
926 //=========================================================================
929 //=========================================================================
930 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
932 bbtkBlackBoxDebugMessage("connection",2,
933 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
934 <<c->GetFullName()<<")"
937 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
938 if (i==bbGetOutputConnectorMap().end())
940 bbtkError("no output called '"<<name<<"'");
942 i->second->SetConnection(c);
944 bbtkBlackBoxDebugMessage("connection",2,
945 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
946 <<c->GetFullName()<<")"
949 //=========================================================================
952 //=========================================================================
953 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
956 bbtkBlackBoxDebugMessage("connection",2,
957 "==> BlackBox::bbDisconnectInput(\""<<name
958 <<"\","<<c->GetFullName()<<")"
963 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
967 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
968 if (i==bbGetInputConnectorMap().end())
970 bbtkError("no input called '"<<name<<"'");
972 i->second->UnsetConnection(c);
974 bbtkBlackBoxDebugMessage("connection",2,
975 "<== BlackBox::bbDisconnectInput(\""<<name
976 <<"\","<<c->GetFullName()<<")"
980 //=========================================================================
983 //=========================================================================
984 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
986 bbtkBlackBoxDebugMessage("connection",2,
987 "==> BlackBox::bbDisconnectOutput(\""<<name
988 <<"\","<<c->GetFullName()<<")"
993 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
997 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
998 if (i==bbGetOutputConnectorMap().end())
1000 bbtkError("no output called '"<<name<<"'");
1002 i->second->UnsetConnection(c);
1004 bbtkBlackBoxDebugMessage("connection",2,
1005 "<== BlackBox::bbDisconnectOutput(\""<<name
1006 <<"\","<<c->GetFullName()<<")"
1009 //=========================================================================
1033 //=========================================================================
1034 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
1036 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
1038 //=========================================================================
1041 //=========================================================================
1042 std::string BlackBox::bbGetOutputAsString( const std::string &output )
1045 // Looks for the adaptor
1046 if (bbGetOutputType(output).name() != typeid(std::string).name() )
1049 Package::Pointer p = bbGetDescriptor()->GetPackage();
1050 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1052 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1053 BlackBox::Pointer a;
1057 bbGetOutputType(output),
1058 typeid(std::string),
1060 } catch (bbtk::Exception e)
1065 a->bbSetInput("In",bbGetOutput(output));
1067 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1069 v="? (no adaptor found)";
1074 v="? (no factory found)";
1080 v = bbGetOutput(output).unsafe_get<std::string>() ;
1084 //=========================================================================
1086 //=========================================================================
1087 std::string BlackBox::bbGetInputAsString( const std::string &input )
1090 // Looks for the adaptor
1091 if (bbGetInputType(input) != typeid(std::string))
1094 Package::Pointer p = bbGetDescriptor()->GetPackage();
1095 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1097 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1098 BlackBox::Pointer a;
1102 bbGetInputType(input),
1103 typeid(std::string),
1105 }catch (bbtk::Exception e)
1111 a->bbSetInput("In",bbGetInput(input));
1113 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1117 v="? (no adaptor found)";
1122 v="? (no factory found)";
1127 v = bbGetInput(input).unsafe_get<std::string>() ;
1131 //=======================================================================
1133 //=======================================================================
1134 // Replaces substrings "<" by "["
1135 void SubsBrackets ( std::string& s )
1137 // std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1138 std::string ss("<");
1139 std::string::size_type pos = 0;
1141 std::string cr("[");
1142 while ( pos != std::string::npos )
1144 // std::cout << "*** find one "<<std::endl;
1145 s.replace(pos,1,cr.c_str(),1);
1146 pos = s.find(ss, pos);
1152 while ( pos != std::string::npos )
1154 // std::cout << "*** find one "<<std::endl;
1155 s.replace(pos,1,cr.c_str(),1);
1156 pos = s.find(ss, pos);
1162 while ( pos != std::string::npos )
1164 // std::cout << "*** find one "<<std::endl;
1165 s.replace(pos,1,cr.c_str(),1);
1166 pos = s.find(ss, pos);
1167 } // std::cout << "AFTER=["<<s<<"]"<<std::endl;
1169 //=======================================================================
1171 //=========================================================================
1172 /// Write Graphviz-dot description in file
1173 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1174 BlackBox::Pointer parentblackbox,
1175 int detail, int level,
1176 bool instanceOrtype,
1177 bool relative_link )
1180 InputConnectorMapType::iterator i;
1182 std::string labelStr;
1183 std::string valueStr("");
1186 labelStr = bbGetName() ;
1188 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1190 labelStr = bbGetName();
1191 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
1194 SubsBrackets(labelStr);
1197 labelStr = labelStr + " | {{ ";
1198 std::string tempStrTypeName;
1201 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1205 labelStr=labelStr+" | ";
1208 if (instanceOrtype==true)
1210 valueStr = this->bbGetInputAsString(i->first) + " = ";
1212 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1213 tempStrTypeName=id->GetTypeName();
1214 SubsBrackets(tempStrTypeName);
1215 std::string Name(i->first);
1217 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
1219 labelStr=labelStr+ " } | {";
1221 OutputConnectorMapType::iterator ii;
1222 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
1226 labelStr=labelStr+" | ";
1229 if (instanceOrtype==true)
1231 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1233 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
1234 tempStrTypeName=id->GetTypeName();
1235 SubsBrackets(tempStrTypeName);
1236 std::string Name(ii->first);
1238 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
1240 labelStr = labelStr+ " } }" ;
1244 bbWriteDotInputOutputName(ff,true,detail,level);
1245 std::string tmp ( bbGetTypeName() );
1249 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1251 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1253 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1254 // std::cout << labelStr << std::endl;
1257 if (GetThisPointer<BlackBox>()!=parentblackbox){
1258 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1262 Connection* con = i->second->GetConnection();
1264 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1265 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1267 a->bbWriteDotInputOutputName(ff,false,detail,level);
1270 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1273 b->bbWriteDotInputOutputName(ff,true,detail,level);
1276 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1278 fprintf(ff,"%s\n",";");
1282 } // if parentblackbox
1284 //=========================================================================
1289 //=========================================================================
1290 void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox,
1291 int detail, int level
1292 /*,Factory *factory*/ )
1295 if (this->bbGetDescriptor()->GetPackage())
1297 bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
1298 this->bbGetDescriptor()->GetPackage()->GetName()
1299 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1303 bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1308 bbtkBlackBoxMessage("help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1309 <<mMinOutputChangeTime<<"]"<<std::endl);
1313 bbtkBlackBoxMessage("help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1314 <<mMinOutputChangeTime<<"]"<<std::endl);
1317 // bbtkBlackBoxMessage("help",1," "<<GetDescription()<<std::endl);
1318 // bbtkBlackBoxMessage("help",1," By : "<<GetAuthor()<<std::endl);
1320 std::vector<std::string> iname;
1321 std::vector<std::string> ivalue;
1322 std::vector<std::string> iconn;
1323 std::vector<std::string> istatus;
1325 InputConnectorMapType::iterator i;
1326 unsigned int namelmax = 0;
1327 unsigned int valuelmax = 0;
1328 // unsigned int connlmax = 0;
1329 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1331 iname.push_back(i->first);
1332 if (iname.back().size()>namelmax) namelmax = iname.back().size();
1333 ivalue.push_back(bbGetInputAsString(i->first));
1334 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1336 Connection* con = i->second->GetConnection();
1338 s = con->GetOriginalBlackBoxFrom()->bbGetName();
1340 s += con->GetOriginalBlackBoxFromOutput();
1343 istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1345 OutputConnectorMapType::iterator o;
1346 std::vector<std::string> oname;
1347 std::vector<std::string> ovalue;
1348 std::vector<std::vector<std::string> > oconn;
1349 std::vector<std::string> ostatus;
1350 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
1352 oname.push_back(o->first);
1353 if (oname.back().size()>namelmax)
1354 namelmax = oname.back().size();
1355 ovalue.push_back(bbGetOutputAsString(o->first));
1356 if (ovalue.back().size()>valuelmax)
1357 valuelmax = ovalue.back().size();
1358 std::vector<std::string> ss;
1359 const std::vector<Connection*>& con
1360 = o->second->GetConnectionVector();
1361 std::vector<Connection*>::const_iterator c;
1362 for (c=con.begin();c!=con.end();++c)
1365 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1367 s += (*c)->GetOriginalBlackBoxToInput();
1370 oconn.push_back(ss);
1371 ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1375 bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
1377 bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
1379 std::vector<std::string>::iterator i1,i2,i3,i4;
1380 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1381 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1382 ++i1,++i2,++i3,++i4)
1384 std::string name(*i1);
1386 name.append(1+namelmax-name.size(),' ');
1387 std::string value(*i2);
1389 value.append(1+valuelmax-value.size(),' ');
1391 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value<<" <-- '" <<*i3<<"'");
1393 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1394 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1398 bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
1400 bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
1402 std::vector<std::vector<std::string> >::iterator i5;
1404 for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1405 i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1406 ++i1,++i2,++i4,++i5)
1408 std::string name(*i1);
1410 name.append(1+namelmax-name.size(),' ');
1411 std::string value(*i2);
1413 value.append(1+valuelmax-value.size(),' ');
1415 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1418 std::string pref = " '"+name+" = '"+value;
1419 for (i3=i5->begin();i3!=i5->end();++i3)
1421 bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
1422 pref.replace(0,pref.size(),pref.size(),' ');
1425 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1429 //=========================================================================
1448 static bool bbmgGlobalProcessingExecutionList = false;
1450 //=========================================================================
1451 void BlackBox::bbGlobalProcessExecutionList()
1453 bbtkDebugMessage("process",3,
1454 "=> BlackBox::bbGlobalProcessExecutionList()"
1456 if (bbmgGlobalProcessingExecutionList)
1458 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1461 bbmgGlobalProcessingExecutionList = true;
1463 std::set<BlackBox::WeakPointer>::iterator i;
1464 while (bbmgExecutionList.size()>0)
1466 i = bbmgExecutionList.begin();
1467 BlackBox::WeakPointer p = *i;
1468 bbmgExecutionList.erase(i);
1471 bbtkDebugMessage("process",4,
1473 p.lock()->bbGetName()<<"'"<<std::endl);
1474 p.lock()->bbExecute(true);
1478 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1482 bbmgExecutionList.clear();
1483 bbtkDebugMessage("process",3,
1484 "<= BlackBox::bbGlobalProcessExecutionList()"
1487 bbmgGlobalProcessingExecutionList = false;
1491 //=========================================================================
1493 bool BlackBox::bbGlobalGetSomeBoxExecuting()
1495 return bbmgSomeBoxExecuting;
1498 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
1500 bbmgSomeBoxExecuting = b;
1503 void BlackBox::bbGlobalSetFreezeExecution(bool b)
1505 bbmgFreezeExecution = b;
1508 bool BlackBox::bbGlobalGetFreezeExecution()
1510 return bbmgFreezeExecution;
1513 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1515 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
1516 if (bbmgGlobalProcessingExecutionList)
1518 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1520 bbmgExecutionList.insert(b);
1524 //=========================================================================
1526 //=========================================================================
1527 void BlackBox::Check(bool recursive)
1529 bbtkBlackBoxMessage("debug",1,"*** Checking"
1530 <<" ... OK"<<std::endl);
1532 //=========================================================================
1537 } // EO namespace bbtk