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);
97 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor package expired (was not held by a package and the box was the last instance)"<<std::endl);
100 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);
102 bbtkDebugMessage("object",2,"<## BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
105 //=========================================================================
107 //=========================================================================
108 BlackBox::BlackBox(const std::string &name)
110 // bbmStatus(MODIFIED),
111 bbmInitialized(false),
114 bbmBoxProcessMode("Pipeline"),
115 bbLetRecursiveExecuteManualMode(false),
120 // bbmBoxProcessMode = "Pipeline";
121 //std::cout<<"JCP BlackBox::BlackBox(const std::string &name) name=" <<name
122 // <<"bbmBoxProcessMode="<<bbmBoxProcessMode<<std::endl;
123 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox(\""
124 <<name<<"\")"<<std::endl);
125 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox(\""
126 <<name<<"\")"<<std::endl);
128 //=========================================================================
130 //=========================================================================
131 BlackBox::BlackBox(const BlackBox&)
134 //=========================================================================
135 BlackBox::BlackBox(BlackBox& from, const std::string &name)
137 // bbmStatus(from.bbmStatus),
138 bbmInitialized(false),
141 bbmBoxProcessMode(from.bbmBoxProcessMode),
142 bbLetRecursiveExecuteManualMode(false),
147 //bbmBoxProcessMode = from.bbmBoxProcessMode;
148 //std::cout<<"JCP BlackBox::BlackBox(const std::string &name) name=" <<name
149 // <<"bbmBoxProcessMode="<<bbmBoxProcessMode<<std::endl;
150 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox("
151 <<from.bbGetFullName()<<",\""
152 <<name<<"\")"<<std::endl);
153 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox("
154 <<from.bbGetFullName()<<",\""
155 <<name<<"\")"<<std::endl);
157 //=========================================================================
160 //=========================================================================
161 BlackBox::~BlackBox()
163 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::~BlackBox() ["<<bbmName
165 this->bbDesallocateConnectors();
166 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::~BlackBox() ["<<bbmName
169 //=========================================================================
173 //=========================================================================
174 std::string BlackBox::bbGetFullName() const
176 return this->bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
178 //=========================================================================
182 //=========================================================================
183 std::string BlackBox::bbGetNameWithParent() const
185 if (bbmParent.lock())
187 return bbmParent.lock()->bbGetNameWithParent() + ":" + bbmName;
194 //=========================================================================
196 //=========================================================================
197 void BlackBox::bbGetHelp(bool full) const
199 bbGetDescriptor()->GetHelp(full);
201 //=========================================================================
204 //=========================================================================
205 bool BlackBox::bbHasInput(const std::string& name) const
207 bbtkBlackBoxDebugMessage("kernel",8,
208 "BlackBox::bbHasInput(\""
211 bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
212 != bbGetDescriptor()->GetInputDescriptorMap().end());
213 bbtkDebugDecTab("kernel",8);
216 //=========================================================================
219 //=========================================================================
220 bool BlackBox::bbHasOutput(const std::string& name) const
222 bbtkBlackBoxDebugMessage("kernel",8,"BlackBox::bbHasOutput(\""
225 bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
226 != bbGetDescriptor()->GetOutputDescriptorMap().end());
227 bbtkDebugDecTab("kernel",8);
230 //=========================================================================
233 //=========================================================================
234 TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const
236 bbtkBlackBoxDebugMessage("kernel",8,
237 "BlackBox::bbGetOutputType(\""
240 TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
241 bbtkDebugDecTab("kernel",8);
244 //=========================================================================
246 //=========================================================================
247 TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
249 bbtkBlackBoxDebugMessage("kernel",8,
250 "BlackBox::bbGetInputType(\""
253 TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
254 bbtkDebugDecTab("kernel",8);
257 //=========================================================================
260 //=========================================================================
261 void BlackBox::bbAllocateConnectors()
263 bbtkBlackBoxDebugMessage("kernel",8,
264 "BlackBox::bbAllocateConnectors()"
267 MakeBlackBoxPointer(this,true);
269 const BlackBoxDescriptor::InputDescriptorMapType& imap
270 = bbGetDescriptor()->GetInputDescriptorMap();
271 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
272 for ( i = imap.begin(); i != imap.end(); ++i )
274 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
275 bbGetInputConnectorMap()[i->second->GetName()]
276 = new BlackBoxInputConnector(GetThisPointer<BlackBox>());
278 const BlackBoxDescriptor::OutputDescriptorMapType& omap
279 = bbGetDescriptor()->GetOutputDescriptorMap();
280 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
281 for ( o = omap.begin(); o != omap.end(); ++o )
283 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
284 bbGetOutputConnectorMap()[o->second->GetName()]
285 = new BlackBoxOutputConnector(GetThisPointer<BlackBox>());
288 //=========================================================================
291 //=========================================================================
292 void BlackBox::bbDesallocateConnectors()
294 bbtkBlackBoxDebugMessage("kernel",8,
295 "BlackBox::bbDesallocateConnectors()"
298 InputConnectorMapType::const_iterator i;
299 for ( i = bbGetInputConnectorMap().begin();
300 i != bbGetInputConnectorMap().end(); ++i )
302 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<i->first<<"\""<<std::endl);
305 OutputConnectorMapType::const_iterator o;
306 for ( o = bbGetOutputConnectorMap().begin();
307 o != bbGetOutputConnectorMap().end(); ++o )
309 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<o->first<<"\""<<std::endl);
313 bbtkDebugDecTab("kernel",8);
315 //=========================================================================
318 //=========================================================================
319 void BlackBox::bbCopyIOValues(BlackBox& from)
321 bbtkBlackBoxDebugMessage("kernel",1,
322 "BlackBox::bbCopyIOValues("
323 <<from.bbGetFullName()<<")"
325 // copies the input values
326 const BlackBoxDescriptor::InputDescriptorMapType& imap
327 = bbGetDescriptor()->GetInputDescriptorMap();
328 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
329 for ( i = imap.begin(); i != imap.end(); ++i )
331 if (! i->second->GetCopyConstruct() ) continue;
332 std::string input = i->second->GetName();
333 bbtkBlackBoxDebugMessage("kernel",2,"* Copying input "<<input<<std::endl);
334 this->bbSetInput(input, from.bbGetInput(input) );
336 // copies the output values
337 const BlackBoxDescriptor::OutputDescriptorMapType& omap
338 = bbGetDescriptor()->GetOutputDescriptorMap();
339 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
340 for ( o = omap.begin(); o != omap.end(); ++o )
342 if (! o->second->GetCopyConstruct() ) continue;
343 std::string output = o->second->GetName();
344 bbtkBlackBoxDebugMessage("kernel",2,"* Copying output "<<output<<std::endl);
345 this->bbSetOutput(output, from.bbGetOutput(output) );
348 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 bbPipeline;
375 (p == "A") || (p == "a") ||
376 (p == "Always") || (p == "always") ) return bbAlways;
378 (p == "R") || (p == "r") ||
379 (p == "Reactive") || (p == "reactive") )
383 (p == "F") || (p == "f") ||
384 (p == "Flash") || (p == "flash") ) return Flash;
388 (p == "M") || (p == "m") ||
389 (p == "Manual") || (p == "manual") ) return bbManual;
391 bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
392 <<"' unknown. Possible values : "
393 <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
394 <<"'1'/'A'/'a'/'Always'/'always' | "
395 <<"'2'/'R'/'r'/'Reactive'/'reactive'"
396 // <<"'3'/'F'/'f'/'Flash'/'flash'"
397 <<"'3'/'M'/'m'/'Manual'/'manual'"
400 //=========================================================================
402 //=========================================================================
403 bool BlackBox::bbBoxProcessModeIsReactive() const
405 return (bbGetBoxProcessModeValue() == bbReactive);
407 //=========================================================================
409 //=========================================================================
410 bool BlackBox::bbBoxProcessModeIsAlways() const
412 return (bbGetBoxProcessModeValue() == bbAlways);
414 //=========================================================================
417 //=========================================================================
418 bool BlackBox::bbBoxProcessModeIsManual() const
420 return (bbGetBoxProcessModeValue() == bbManual);
422 //=========================================================================
425 //=========================================================================
426 void BlackBox::bbAddOutputObserver(const std::string& output,
427 OutputChangeCallbackType f)
429 bbGetOutputConnector(output).AddChangeObserver(f);
431 //=========================================================================
433 //=========================================================================
434 void BlackBox::bbRemoveOutputObserver(const std::string& output_name,
435 OutputChangeCallbackType f)
437 bbtkError("BlackBox::RemoveChangeObserver NOT IMPLEMENTED");
439 //=========================================================================
442 //=========================================================================
443 void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
446 bbtkBlackBoxDebugMessage("change",5,
447 "=> BlackBox::bbSetStatusAndPropagate(input,"
448 <<GetIOStatusString(s)<<")"
451 if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
456 if (bbGetBoxProcessModeValue() == Flash)
463 OutputConnectorMapType::const_iterator o;
464 for ( o = bbGetOutputConnectorMap().begin();
465 o != bbGetOutputConnectorMap().end(); ++o )
469 if (o->first=="BoxChange")
471 o->second->SetStatus(UPTODATE);
478 if (o->second->GetStatus()==UPTODATE)
479 // if ((o->second->GetStatus()==UPTODATE) || (o->second->GetStatus()==OUTOFDATE))
480 // if ((o->second->GetStatus()==UPTODATE) || (o->second->GetStatus()==MODIFIED))
482 o->second->SetStatus(OUTOFDATE);
483 o->second->SignalChange(GetThisPointer<BlackBox>(),o->first);
488 if ( ( bbBoxProcessModeIsReactive()
489 || (c==bbGetInputConnectorMap().find("BoxExecute")->second))
492 bbtkBlackBoxDebugMessage("change",2,
493 "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
494 bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
496 bbtkBlackBoxDebugMessage("change",5,
497 "<= BlackBox::bbSetStatusAndPropagate(input)"
500 //=========================================================================
503 //=========================================================================
504 void BlackBox::bbSignalOutputModification(bool reaction)
506 bbtkBlackBoxDebugMessage("change",5,
507 "=> BlackBox::bbSignalOutputModification("
511 OutputConnectorMapType::iterator i;
512 for ( i = bbGetOutputConnectorMap().begin();
513 i != bbGetOutputConnectorMap().end(); ++i)
515 // std::cout << "Stat = "
516 //<<GetIOStatusString(i->second->GetStatus())
518 // LG : CANNOT SIGNAL ONLY WHEN UPTODATE
519 // See bbtkSampleOutputObserver
520 // if (i->second->GetStatus()==UPTODATE)
522 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
526 if (reaction) bbGlobalProcessExecutionList();
528 bbtkBlackBoxDebugMessage("change",5,
529 "<= BlackBox::bbSignalOutputModification()"
532 //=========================================================================
535 //=========================================================================
536 void BlackBox::bbSignalOutputModification(const std::string& output,
539 bbtkBlackBoxDebugMessage("change",5,
540 "=> BlackBox::bbSignalOutputModification("
541 <<output<<","<<reaction<<")"
544 OutputConnectorMapType::iterator i =
545 bbGetOutputConnectorMap().find(output);
548 if ( i == bbGetOutputConnectorMap().end() )
550 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
553 // if (i->second->GetStatus()==UPTODATE)
555 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
556 // Has to notify the output "BoxChange" also
557 if (output != "BoxChange")
559 i = bbGetOutputConnectorMap().find("BoxChange");
560 if ( i != bbGetOutputConnectorMap().end() )
562 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
565 if (reaction) bbGlobalProcessExecutionList();
568 bbtkBlackBoxDebugMessage("change",5,
569 "<= BlackBox::bbSignalOutputModification("
573 //=========================================================================
574 //=========================================================================
575 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
578 bbtkBlackBoxDebugMessage("change",5,
579 "=> BlackBox::bbSignalOutputModification(vector of outputs)"
581 OutputConnectorMapType::iterator i;
582 std::vector<std::string>::const_iterator o;
583 bool changed = false;
584 for (o=output.begin();o!=output.end();++o)
586 // the output "BoxChange" must be signaled **AFTER** all others
587 if (*o == "BoxChange") continue;
588 // Look for the connector
589 i = bbGetOutputConnectorMap().find(*o);
590 if ( i == bbGetOutputConnectorMap().end() )
592 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
595 // if (i->second->GetStatus()==UPTODATE)
597 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
601 // Has to notify the output "BoxChange" also
602 i = bbGetOutputConnectorMap().find("BoxChange");
603 if ( changed && (i != bbGetOutputConnectorMap().end()))
605 // if (i->second->GetStatus()==UPTODATE)
607 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
608 if (reaction) bbGlobalProcessExecutionList();
612 bbtkBlackBoxDebugMessage("change",5,
613 "<= BlackBox::bbSignalOutputModification(vector of outputs)"
616 //=========================================================================
624 //=========================================================================
625 /// Main processing method of the box.
626 void BlackBox::bbExecute(bool force)
628 bbtkBlackBoxDebugMessage("process",2,
629 "=> BlackBox::bbExecute("<<(int)force<<")"
632 // If already executing : return
634 if (bbGetExecuting())
636 bbtkBlackBoxDebugMessage("process",2,
637 " -> already executing : abort"<<std::endl);
642 // If execution frozen : return
643 if (bbGlobalGetFreezeExecution())
645 bbtkBlackBoxDebugMessage("process",2,
646 " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
651 // If force is true then update is triggered even if the box is UPTODATE
652 // if (force) bbSetModifiedStatus();
654 if ( bbBoxProcessModeIsManual() )
656 bbLetRecursiveExecuteManualMode = true;
660 // Calls the main recursive execution method
661 bbRecursiveExecute(Connection::Pointer());
664 if ( bbBoxProcessModeIsManual() )
666 bbLetRecursiveExecuteManualMode = false;
670 bbtkBlackBoxDebugMessage("process",2,
671 "<= BlackBox::bbExecute()"
674 //=========================================================================
676 //=========================================================================
677 void BlackBox::bbInitializeProcessing()
681 bbtkBlackBoxDebugMessage("process",2,"** Initialize processing"
683 this->bbRecursiveInitializeProcessing();
684 bbmInitialized = true;
687 //=========================================================================
689 //=========================================================================
690 void BlackBox::bbFinalizeProcessing()
694 bbtkBlackBoxDebugMessage("process",2,"** Finalize processing"
696 this->bbRecursiveFinalizeProcessing();
697 bbmInitialized = false;
700 //=========================================================================
703 //=========================================================================
704 void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
706 bbtkBlackBoxDebugMessage("process",3,
707 "=> BlackBox::bbRecursiveExecute("
708 <<(caller?caller->GetFullName():"0")<<")"
711 // If already executing : return
712 if (bbGetExecuting())
714 bbtkBlackBoxDebugMessage("process",3,
715 " -> already executing : abort"<<std::endl);
719 // If not initialized do it
720 bbInitializeProcessing();
722 bbSetExecuting(true);
723 bool wasExecuting = bbGlobalGetSomeBoxExecuting();
724 bbGlobalSetSomeBoxExecuting(true);
726 // Creates the window if the black box has one
727 this->bbCreateWindow();
729 // Updates its inputs
733 // IOStatus s=OUTOFDATE;
734 // IOStatus s=MODIFIED;
737 if ( ( bbBoxProcessModeIsManual()==false ) ||
738 ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) ) )
740 s = bbUpdateInputs();
743 if ( (s != UPTODATE) || bbBoxProcessModeIsAlways() )
745 // Displays the window (WxBlackbox)
746 // bbShowWindow(caller);
748 // Actual processing (virtual)
749 if ( ( bbBoxProcessModeIsManual()==false ) ||
750 ( (bbBoxProcessModeIsManual()==true)&&(bbLetRecursiveExecuteManualMode==true) )
753 //printf("EED BlackBox::bbRecursiveExecute bbProcess start %s \n", bbGetFullName().c_str() );
755 //printf("EED BlackBox::bbRecursiveExecute bbProcess end %s \n", bbGetFullName().c_str() );
758 //EED ups if ((bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false))
760 //EED ups bbSignalOutputModification(true);
764 // Update the I/O statuses
765 bbComputePostProcessStatus();
767 // Test output status...
768 OutputConnectorMapType::iterator o;
769 for ( o = bbGetOutputConnectorMap().begin();
770 o!= bbGetOutputConnectorMap().end(); ++o)
772 if (o->second->GetStatus() != UPTODATE)
774 bbtkWarning("BlackBox::bbRecursiveExecute: "
775 <<"all inputs are Up-to-date but output '"
776 <<o->first<<"' is Out-of-date ???");
780 bbtkBlackBoxDebugMessage("process",3," -> Up-to-date : nothing to do"
784 // Shows the window if the black box has one
785 this->bbShowWindow();
788 bbtkBlackBoxDebugMessage("process",3,
789 "<= BlackBox::bbRecursiveExecute()"
792 bbSetExecuting(false);
793 bbGlobalSetSomeBoxExecuting(wasExecuting);
797 //=========================================================================
803 //=========================================================================
804 IOStatus BlackBox::bbUpdateInputs()
806 bbtkBlackBoxDebugMessage("process",4,
807 "=> BlackBox::bbUpdateInputs()"
810 IOStatus s = UPTODATE;
812 InputConnectorMapType::iterator i;
813 for ( i = bbGetInputConnectorMap().begin();
814 i!= bbGetInputConnectorMap().end(); ++i)
816 // if (i->first=="WinHide") continue;
817 // If input type is Void : no recurse
818 //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo()
821 bbtkBlackBoxDebugMessage("change",2,
823 <<"': status before update = '"
824 <<GetIOStatusString(i->second->GetStatus())
826 i->second->RecursiveExecute();
827 IOStatus t = i->second->GetStatus();
829 bbtkBlackBoxDebugMessage("change",2,
831 <<"': status before process = '"
832 <<GetIOStatusString(i->second->GetStatus())
836 bbtkBlackBoxDebugMessage("process",4,
837 "<= BlackBox::bbUpdateInputs()"
841 //=========================================================================
843 //==================================================================
844 void BlackBox::bbComputePostProcessStatus()
846 bbtkBlackBoxDebugMessage("process",4,
847 "=> BlackBox::bbComputePostProcessStatus()"
850 IOStatus new_output_status = UPTODATE;
851 if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
853 // Update the input statuses
854 InputConnectorMapType::iterator i;
855 for ( i = bbGetInputConnectorMap().begin();
856 i!= bbGetInputConnectorMap().end(); ++i)
858 IOStatus t = i->second->GetStatus();
859 if (t == OUTOFDATE) new_output_status = OUTOFDATE;
860 // A previously MODIFIED status turns to UPTODATE
861 if (t==MODIFIED) i->second->SetStatus(UPTODATE);
862 bbtkBlackBoxDebugMessage("change",2,
863 "Input '"<<i->first<<"' : "
864 << GetIOStatusString(t) << " -> "
865 << GetIOStatusString(i->second->GetStatus())
868 bbtkBlackBoxDebugMessage("change",2,
869 "New output status : "
870 << GetIOStatusString(new_output_status)
872 // Update the output statuses
873 OutputConnectorMapType::iterator o;
874 for ( o = bbGetOutputConnectorMap().begin();
875 o!= bbGetOutputConnectorMap().end(); ++o)
878 //EED if ( ( bbBoxProcessModeIsManual()==false ) ||
879 //EED ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) )
882 o->second->SetStatus(new_output_status);
884 //EED if (( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false) ) )
886 //EED o->second->SetStatus(UPTODATE);
888 //EED } // Manual analysis
892 bbtkBlackBoxDebugMessage("process",4,
893 "<= BlackBox::bbComputePostProcessStatus()"
896 //==================================================================
898 //=========================================================================
899 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
901 bbtkBlackBoxDebugMessage("connection",2,
902 "==> BlackBox::bbConnectInput(\""
903 <<name<<"\","<<c->GetFullName()<<")"
906 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
907 if (i==bbGetInputConnectorMap().end())
909 bbtkError("no input called '"<<name<<"'");
911 i->second->SetConnection(c);
912 // The input *MUST* be set OUTOFDATE to update its input on next execution
913 bbSetStatusAndPropagate(i->second,OUTOFDATE);
915 bbtkBlackBoxDebugMessage("connection",2,
916 "<== BlackBox::bbConnectInput(\""
917 <<name<<"\","<<c->GetFullName()<<")"
920 //=========================================================================
923 //=========================================================================
924 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
926 bbtkBlackBoxDebugMessage("connection",2,
927 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
928 <<c->GetFullName()<<")"
931 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
932 if (i==bbGetOutputConnectorMap().end())
934 bbtkError("no output called '"<<name<<"'");
936 i->second->SetConnection(c);
938 bbtkBlackBoxDebugMessage("connection",2,
939 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
940 <<c->GetFullName()<<")"
943 //=========================================================================
946 //=========================================================================
947 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
950 bbtkBlackBoxDebugMessage("connection",2,
951 "==> BlackBox::bbDisconnectInput(\""<<name
952 <<"\","<<c->GetFullName()<<")"
957 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
961 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
962 if (i==bbGetInputConnectorMap().end())
964 bbtkError("no input called '"<<name<<"'");
966 i->second->UnsetConnection(c);
968 bbtkBlackBoxDebugMessage("connection",2,
969 "<== BlackBox::bbDisconnectInput(\""<<name
970 <<"\","<<c->GetFullName()<<")"
974 //=========================================================================
977 //=========================================================================
978 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
980 bbtkBlackBoxDebugMessage("connection",2,
981 "==> BlackBox::bbDisconnectOutput(\""<<name
982 <<"\","<<c->GetFullName()<<")"
987 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
991 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
992 if (i==bbGetOutputConnectorMap().end())
994 bbtkError("no output called '"<<name<<"'");
996 i->second->UnsetConnection(c);
998 bbtkBlackBoxDebugMessage("connection",2,
999 "<== BlackBox::bbDisconnectOutput(\""<<name
1000 <<"\","<<c->GetFullName()<<")"
1003 //=========================================================================
1027 //=========================================================================
1028 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
1030 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
1032 //=========================================================================
1035 //=========================================================================
1036 std::string BlackBox::bbGetOutputAsString( const std::string &output )
1039 // Looks for the adaptor
1040 if (bbGetOutputType(output).name() != typeid(std::string).name() )
1043 Package::Pointer p = bbGetDescriptor()->GetPackage();
1044 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1046 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1047 BlackBox::Pointer a;
1051 bbGetOutputType(output),
1052 typeid(std::string),
1054 } catch (bbtk::Exception e)
1059 a->bbSetInput("In",bbGetOutput(output));
1061 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1063 v="? (no adaptor found)";
1068 v="? (no factory found)";
1074 v = bbGetOutput(output).unsafe_get<std::string>() ;
1078 //=========================================================================
1080 //=========================================================================
1081 std::string BlackBox::bbGetInputAsString( const std::string &input )
1084 // Looks for the adaptor
1085 if (bbGetInputType(input) != typeid(std::string))
1088 Package::Pointer p = bbGetDescriptor()->GetPackage();
1089 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1091 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1092 BlackBox::Pointer a;
1096 bbGetInputType(input),
1097 typeid(std::string),
1099 }catch (bbtk::Exception e)
1105 a->bbSetInput("In",bbGetInput(input));
1107 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1111 v="? (no adaptor found)";
1116 v="? (no factory found)";
1121 v = bbGetInput(input).unsafe_get<std::string>() ;
1125 //=======================================================================
1127 //=======================================================================
1128 // Replaces substrings "<" by "["
1129 void SubsBrackets ( std::string& s )
1131 // std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1132 std::string ss("<");
1133 std::string::size_type pos = 0;
1135 std::string cr("[");
1136 while ( pos != std::string::npos )
1138 // std::cout << "*** find one "<<std::endl;
1139 s.replace(pos,1,cr.c_str(),1);
1140 pos = s.find(ss, pos);
1146 while ( pos != std::string::npos )
1148 // std::cout << "*** find one "<<std::endl;
1149 s.replace(pos,1,cr.c_str(),1);
1150 pos = s.find(ss, pos);
1156 while ( pos != std::string::npos )
1158 // std::cout << "*** find one "<<std::endl;
1159 s.replace(pos,1,cr.c_str(),1);
1160 pos = s.find(ss, pos);
1161 } // std::cout << "AFTER=["<<s<<"]"<<std::endl;
1163 //=======================================================================
1165 //=========================================================================
1166 /// Write Graphviz-dot description in file
1167 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1168 BlackBox::Pointer parentblackbox,
1169 int detail, int level,
1170 bool instanceOrtype,
1171 bool relative_link )
1174 InputConnectorMapType::iterator i;
1176 std::string labelStr;
1177 std::string valueStr("");
1180 labelStr = bbGetName() ;
1182 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1184 labelStr = bbGetName();
1185 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
1188 SubsBrackets(labelStr);
1191 labelStr = labelStr + " | {{ ";
1192 std::string tempStrTypeName;
1195 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1199 labelStr=labelStr+" | ";
1202 if (instanceOrtype==true)
1204 valueStr = this->bbGetInputAsString(i->first) + " = ";
1206 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1207 tempStrTypeName=id->GetTypeName();
1208 SubsBrackets(tempStrTypeName);
1209 std::string Name(i->first);
1211 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
1213 labelStr=labelStr+ " } | {";
1215 OutputConnectorMapType::iterator ii;
1216 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
1220 labelStr=labelStr+" | ";
1223 if (instanceOrtype==true)
1225 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1227 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
1228 tempStrTypeName=id->GetTypeName();
1229 SubsBrackets(tempStrTypeName);
1230 std::string Name(ii->first);
1232 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
1234 labelStr = labelStr+ " } }" ;
1238 bbWriteDotInputOutputName(ff,true,detail,level);
1239 std::string tmp ( bbGetTypeName() );
1243 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1245 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1247 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1248 // std::cout << labelStr << std::endl;
1251 if (GetThisPointer<BlackBox>()!=parentblackbox){
1252 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1256 Connection* con = i->second->GetConnection();
1258 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1259 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1261 a->bbWriteDotInputOutputName(ff,false,detail,level);
1264 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1267 b->bbWriteDotInputOutputName(ff,true,detail,level);
1270 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1272 fprintf(ff,"%s\n",";");
1276 } // if parentblackbox
1278 //=========================================================================
1283 //=========================================================================
1284 void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox,
1285 int detail, int level
1286 /*,Factory *factory*/ )
1289 if (this->bbGetDescriptor()->GetPackage())
1291 bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
1292 this->bbGetDescriptor()->GetPackage()->GetName()
1293 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1297 bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1302 bbtkBlackBoxMessage("help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1303 <<mMinOutputChangeTime<<"]"<<std::endl);
1307 bbtkBlackBoxMessage("help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1308 <<mMinOutputChangeTime<<"]"<<std::endl);
1311 // bbtkBlackBoxMessage("help",1," "<<GetDescription()<<std::endl);
1312 // bbtkBlackBoxMessage("help",1," By : "<<GetAuthor()<<std::endl);
1314 std::vector<std::string> iname;
1315 std::vector<std::string> ivalue;
1316 std::vector<std::string> iconn;
1317 std::vector<std::string> istatus;
1319 InputConnectorMapType::iterator i;
1320 unsigned int namelmax = 0;
1321 unsigned int valuelmax = 0;
1322 // unsigned int connlmax = 0;
1323 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1325 iname.push_back(i->first);
1326 if (iname.back().size()>namelmax) namelmax = iname.back().size();
1327 ivalue.push_back(bbGetInputAsString(i->first));
1328 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1330 Connection* con = i->second->GetConnection();
1332 s = con->GetOriginalBlackBoxFrom()->bbGetName();
1334 s += con->GetOriginalBlackBoxFromOutput();
1337 istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1339 OutputConnectorMapType::iterator o;
1340 std::vector<std::string> oname;
1341 std::vector<std::string> ovalue;
1342 std::vector<std::vector<std::string> > oconn;
1343 std::vector<std::string> ostatus;
1344 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
1346 oname.push_back(o->first);
1347 if (oname.back().size()>namelmax)
1348 namelmax = oname.back().size();
1349 ovalue.push_back(bbGetOutputAsString(o->first));
1350 if (ovalue.back().size()>valuelmax)
1351 valuelmax = ovalue.back().size();
1352 std::vector<std::string> ss;
1353 const std::vector<Connection*>& con
1354 = o->second->GetConnectionVector();
1355 std::vector<Connection*>::const_iterator c;
1356 for (c=con.begin();c!=con.end();++c)
1359 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1361 s += (*c)->GetOriginalBlackBoxToInput();
1364 oconn.push_back(ss);
1365 ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1369 bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
1371 bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
1373 std::vector<std::string>::iterator i1,i2,i3,i4;
1374 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1375 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1376 ++i1,++i2,++i3,++i4)
1378 std::string name(*i1);
1380 name.append(1+namelmax-name.size(),' ');
1381 std::string value(*i2);
1383 value.append(1+valuelmax-value.size(),' ');
1385 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value<<" <-- '" <<*i3<<"'");
1387 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1388 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1392 bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
1394 bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
1396 std::vector<std::vector<std::string> >::iterator i5;
1398 for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1399 i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1400 ++i1,++i2,++i4,++i5)
1402 std::string name(*i1);
1404 name.append(1+namelmax-name.size(),' ');
1405 std::string value(*i2);
1407 value.append(1+valuelmax-value.size(),' ');
1409 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1412 std::string pref = " '"+name+" = '"+value;
1413 for (i3=i5->begin();i3!=i5->end();++i3)
1415 bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
1416 pref.replace(0,pref.size(),pref.size(),' ');
1419 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1423 //=========================================================================
1442 static bool bbmgGlobalProcessingExecutionList = false;
1444 //=========================================================================
1445 void BlackBox::bbGlobalProcessExecutionList()
1447 bbtkDebugMessage("process",3,
1448 "=> BlackBox::bbGlobalProcessExecutionList()"
1450 if (bbmgGlobalProcessingExecutionList)
1452 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1455 bbmgGlobalProcessingExecutionList = true;
1457 std::set<BlackBox::WeakPointer>::iterator i;
1458 while (bbmgExecutionList.size()>0)
1460 i = bbmgExecutionList.begin();
1461 BlackBox::WeakPointer p = *i;
1462 bbmgExecutionList.erase(i);
1465 bbtkDebugMessage("process",4,
1467 p.lock()->bbGetName()<<"'"<<std::endl);
1468 p.lock()->bbExecute(true);
1472 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1476 bbmgExecutionList.clear();
1477 bbtkDebugMessage("process",3,
1478 "<= BlackBox::bbGlobalProcessExecutionList()"
1481 bbmgGlobalProcessingExecutionList = false;
1485 //=========================================================================
1487 bool BlackBox::bbGlobalGetSomeBoxExecuting()
1489 return bbmgSomeBoxExecuting;
1492 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
1494 bbmgSomeBoxExecuting = b;
1497 void BlackBox::bbGlobalSetFreezeExecution(bool b)
1499 bbmgFreezeExecution = b;
1502 bool BlackBox::bbGlobalGetFreezeExecution()
1504 return bbmgFreezeExecution;
1507 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1509 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
1510 if (bbmgGlobalProcessingExecutionList)
1512 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1514 bbmgExecutionList.insert(b);
1518 //=========================================================================
1520 //=========================================================================
1521 void BlackBox::Check(bool recursive)
1523 bbtkBlackBoxMessage("debug",1,"*** Checking"
1524 <<" ... OK"<<std::endl);
1526 //=========================================================================
1531 } // EO namespace bbtk