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)
466 OutputConnectorMapType::const_iterator o;
467 for ( o = bbGetOutputConnectorMap().begin();
468 o != bbGetOutputConnectorMap().end(); ++o )
470 if (o->second->GetStatus()==UPTODATE)
472 o->second->SetStatus(OUTOFDATE);
473 o->second->SignalChange(GetThisPointer<BlackBox>(),o->first);
477 if ( ( bbBoxProcessModeIsReactive()
478 || (c==bbGetInputConnectorMap().find("BoxExecute")->second))
481 bbtkBlackBoxDebugMessage("change",2,
482 "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
483 bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
485 bbtkBlackBoxDebugMessage("change",5,
486 "<= BlackBox::bbSetStatusAndPropagate(input)"
489 //=========================================================================
492 //=========================================================================
493 void BlackBox::bbSignalOutputModification(bool reaction)
495 bbtkBlackBoxDebugMessage("change",5,
496 "=> BlackBox::bbSignalOutputModification("
500 OutputConnectorMapType::iterator i;
501 for ( i = bbGetOutputConnectorMap().begin();
502 i != bbGetOutputConnectorMap().end(); ++i)
504 // std::cout << "Stat = "
505 //<<GetIOStatusString(i->second->GetStatus())
507 // LG : CANNOT SIGNAL ONLY WHEN UPTODATE
508 // See bbtkSampleOutputObserver
509 // if (i->second->GetStatus()==UPTODATE)
511 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
515 if (reaction) bbGlobalProcessExecutionList();
517 bbtkBlackBoxDebugMessage("change",5,
518 "<= BlackBox::bbSignalOutputModification()"
521 //=========================================================================
524 //=========================================================================
525 void BlackBox::bbSignalOutputModification(const std::string& output,
528 bbtkBlackBoxDebugMessage("change",5,
529 "=> BlackBox::bbSignalOutputModification("
530 <<output<<","<<reaction<<")"
533 OutputConnectorMapType::iterator i =
534 bbGetOutputConnectorMap().find(output);
537 if ( i == bbGetOutputConnectorMap().end() )
539 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
542 // if (i->second->GetStatus()==UPTODATE)
544 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
545 // Has to notify the output "BoxChange" also
546 if (output != "BoxChange")
548 i = bbGetOutputConnectorMap().find("BoxChange");
549 if ( i != bbGetOutputConnectorMap().end() )
551 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
554 if (reaction) bbGlobalProcessExecutionList();
557 bbtkBlackBoxDebugMessage("change",5,
558 "<= BlackBox::bbSignalOutputModification("
562 //=========================================================================
563 //=========================================================================
564 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
567 bbtkBlackBoxDebugMessage("change",5,
568 "=> BlackBox::bbSignalOutputModification(vector of outputs)"
570 OutputConnectorMapType::iterator i;
571 std::vector<std::string>::const_iterator o;
572 bool changed = false;
573 for (o=output.begin();o!=output.end();++o)
575 // the output "BoxChange" must be signaled **AFTER** all others
576 if (*o == "BoxChange") continue;
577 // Look for the connector
578 i = bbGetOutputConnectorMap().find(*o);
579 if ( i == bbGetOutputConnectorMap().end() )
581 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
584 // if (i->second->GetStatus()==UPTODATE)
586 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
590 // Has to notify the output "BoxChange" also
591 i = bbGetOutputConnectorMap().find("BoxChange");
592 if ( changed && (i != bbGetOutputConnectorMap().end()))
594 // if (i->second->GetStatus()==UPTODATE)
596 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
597 if (reaction) bbGlobalProcessExecutionList();
601 bbtkBlackBoxDebugMessage("change",5,
602 "<= BlackBox::bbSignalOutputModification(vector of outputs)"
605 //=========================================================================
613 //=========================================================================
614 /// Main processing method of the box.
615 void BlackBox::bbExecute(bool force)
617 bbtkBlackBoxDebugMessage("process",2,
618 "=> BlackBox::bbExecute("<<(int)force<<")"
621 // If already executing : return
623 if (bbGetExecuting())
625 bbtkBlackBoxDebugMessage("process",2,
626 " -> already executing : abort"<<std::endl);
631 // If execution frozen : return
632 if (bbGlobalGetFreezeExecution())
634 bbtkBlackBoxDebugMessage("process",2,
635 " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
640 // If force is true then update is triggered even if the box is UPTODATE
641 // if (force) bbSetModifiedStatus();
643 if ( bbBoxProcessModeIsManual() )
645 bbLetRecursiveExecuteManualMode = true;
649 // Calls the main recursive execution method
650 bbRecursiveExecute(Connection::Pointer());
653 if ( bbBoxProcessModeIsManual() )
655 bbLetRecursiveExecuteManualMode = false;
659 bbtkBlackBoxDebugMessage("process",2,
660 "<= BlackBox::bbExecute()"
663 //=========================================================================
665 //=========================================================================
666 void BlackBox::bbInitializeProcessing()
670 bbtkBlackBoxDebugMessage("process",2,"** Initialize processing"
672 this->bbRecursiveInitializeProcessing();
673 bbmInitialized = true;
676 //=========================================================================
678 //=========================================================================
679 void BlackBox::bbFinalizeProcessing()
683 bbtkBlackBoxDebugMessage("process",2,"** Finalize processing"
685 this->bbRecursiveFinalizeProcessing();
686 bbmInitialized = false;
689 //=========================================================================
692 //=========================================================================
693 void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
695 bbtkBlackBoxDebugMessage("process",3,
696 "=> BlackBox::bbRecursiveExecute("
697 <<(caller?caller->GetFullName():"0")<<")"
700 // If already executing : return
701 if (bbGetExecuting())
703 bbtkBlackBoxDebugMessage("process",3,
704 " -> already executing : abort"<<std::endl);
708 // If not initialized do it
709 bbInitializeProcessing();
711 bbSetExecuting(true);
712 bool wasExecuting = bbGlobalGetSomeBoxExecuting();
713 bbGlobalSetSomeBoxExecuting(true);
715 // Creates the window if the black box has one
716 this->bbCreateWindow();
718 // Updates its inputs
722 // IOStatus s=OUTOFDATE;
723 // IOStatus s=MODIFIED;
726 if ( ( bbBoxProcessModeIsManual()==false ) ||
727 ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) ) )
729 s = bbUpdateInputs();
732 if ( (s != UPTODATE) || bbBoxProcessModeIsAlways() )
734 // Displays the window (WxBlackbox)
735 // bbShowWindow(caller);
737 // Actual processing (virtual)
738 if ( ( bbBoxProcessModeIsManual()==false ) ||
739 ( (bbBoxProcessModeIsManual()==true)&&(bbLetRecursiveExecuteManualMode==true) )
745 //EED ups if ((bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false))
747 //EED ups bbSignalOutputModification(true);
751 // Update the I/O statuses
752 bbComputePostProcessStatus();
756 // Test output status...
757 OutputConnectorMapType::iterator o;
758 for ( o = bbGetOutputConnectorMap().begin();
759 o!= bbGetOutputConnectorMap().end(); ++o)
761 if (o->second->GetStatus() != UPTODATE)
763 bbtkWarning("BlackBox::bbRecursiveExecute: "
764 <<"all inputs are Up-to-date but output '"
765 <<o->first<<"' is Out-of-date ???");
769 bbtkBlackBoxDebugMessage("process",3," -> Up-to-date : nothing to do"
773 // Shows the window if the black box has one
774 this->bbShowWindow();
777 bbtkBlackBoxDebugMessage("process",3,
778 "<= BlackBox::bbRecursiveExecute()"
781 bbSetExecuting(false);
782 bbGlobalSetSomeBoxExecuting(wasExecuting);
786 //=========================================================================
792 //=========================================================================
793 IOStatus BlackBox::bbUpdateInputs()
795 bbtkBlackBoxDebugMessage("process",4,
796 "=> BlackBox::bbUpdateInputs()"
799 IOStatus s = UPTODATE;
801 InputConnectorMapType::iterator i;
802 for ( i = bbGetInputConnectorMap().begin();
803 i!= bbGetInputConnectorMap().end(); ++i)
805 // if (i->first=="WinHide") continue;
806 // If input type is Void : no recurse
807 //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo()
810 bbtkBlackBoxDebugMessage("change",2,
812 <<"': status before update = '"
813 <<GetIOStatusString(i->second->GetStatus())
815 i->second->RecursiveExecute();
816 IOStatus t = i->second->GetStatus();
818 bbtkBlackBoxDebugMessage("change",2,
820 <<"': status before process = '"
821 <<GetIOStatusString(i->second->GetStatus())
825 bbtkBlackBoxDebugMessage("process",4,
826 "<= BlackBox::bbUpdateInputs()"
830 //=========================================================================
832 //==================================================================
833 void BlackBox::bbComputePostProcessStatus()
835 bbtkBlackBoxDebugMessage("process",4,
836 "=> BlackBox::bbComputePostProcessStatus()"
839 IOStatus new_output_status = UPTODATE;
840 if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
842 // Update the input statuses
843 InputConnectorMapType::iterator i;
844 for ( i = bbGetInputConnectorMap().begin();
845 i!= bbGetInputConnectorMap().end(); ++i)
847 IOStatus t = i->second->GetStatus();
848 if (t == OUTOFDATE) new_output_status = OUTOFDATE;
849 // A previously MODIFIED status turns to UPTODATE
850 if (t==MODIFIED) i->second->SetStatus(UPTODATE);
851 bbtkBlackBoxDebugMessage("change",2,
852 "Input '"<<i->first<<"' : "
853 << GetIOStatusString(t) << " -> "
854 << GetIOStatusString(i->second->GetStatus())
857 bbtkBlackBoxDebugMessage("change",2,
858 "New output status : "
859 << GetIOStatusString(new_output_status)
861 // Update the output statuses
862 OutputConnectorMapType::iterator o;
863 for ( o = bbGetOutputConnectorMap().begin();
864 o!= bbGetOutputConnectorMap().end(); ++o)
867 //EED if ( ( bbBoxProcessModeIsManual()==false ) ||
868 //EED ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) )
871 o->second->SetStatus(new_output_status);
873 //EED if (( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false) ) )
875 //EED o->second->SetStatus(UPTODATE);
877 //EED } // Manual analysis
881 bbtkBlackBoxDebugMessage("process",4,
882 "<= BlackBox::bbComputePostProcessStatus()"
885 //==================================================================
887 //=========================================================================
888 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
890 bbtkBlackBoxDebugMessage("connection",2,
891 "==> BlackBox::bbConnectInput(\""
892 <<name<<"\","<<c->GetFullName()<<")"
895 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
896 if (i==bbGetInputConnectorMap().end())
898 bbtkError("no input called '"<<name<<"'");
900 i->second->SetConnection(c);
901 // The input *MUST* be set OUTOFDATE to update its input on next execution
902 bbSetStatusAndPropagate(i->second,OUTOFDATE);
904 bbtkBlackBoxDebugMessage("connection",2,
905 "<== BlackBox::bbConnectInput(\""
906 <<name<<"\","<<c->GetFullName()<<")"
909 //=========================================================================
912 //=========================================================================
913 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
915 bbtkBlackBoxDebugMessage("connection",2,
916 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
917 <<c->GetFullName()<<")"
920 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
921 if (i==bbGetOutputConnectorMap().end())
923 bbtkError("no output called '"<<name<<"'");
925 i->second->SetConnection(c);
927 bbtkBlackBoxDebugMessage("connection",2,
928 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
929 <<c->GetFullName()<<")"
932 //=========================================================================
935 //=========================================================================
936 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
939 bbtkBlackBoxDebugMessage("connection",2,
940 "==> BlackBox::bbDisconnectInput(\""<<name
941 <<"\","<<c->GetFullName()<<")"
946 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
950 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
951 if (i==bbGetInputConnectorMap().end())
953 bbtkError("no input called '"<<name<<"'");
955 i->second->UnsetConnection(c);
957 bbtkBlackBoxDebugMessage("connection",2,
958 "<== BlackBox::bbDisconnectInput(\""<<name
959 <<"\","<<c->GetFullName()<<")"
963 //=========================================================================
966 //=========================================================================
967 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
969 bbtkBlackBoxDebugMessage("connection",2,
970 "==> BlackBox::bbDisconnectOutput(\""<<name
971 <<"\","<<c->GetFullName()<<")"
976 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
980 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
981 if (i==bbGetOutputConnectorMap().end())
983 bbtkError("no output called '"<<name<<"'");
985 i->second->UnsetConnection(c);
987 bbtkBlackBoxDebugMessage("connection",2,
988 "<== BlackBox::bbDisconnectOutput(\""<<name
989 <<"\","<<c->GetFullName()<<")"
992 //=========================================================================
1016 //=========================================================================
1017 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
1019 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
1021 //=========================================================================
1024 //=========================================================================
1025 std::string BlackBox::bbGetOutputAsString( const std::string &output )
1028 // Looks for the adaptor
1029 if (bbGetOutputType(output).name() != typeid(std::string).name() )
1032 Package::Pointer p = bbGetDescriptor()->GetPackage();
1033 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1035 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1036 BlackBox::Pointer a;
1040 bbGetOutputType(output),
1041 typeid(std::string),
1043 } catch (bbtk::Exception e)
1048 a->bbSetInput("In",bbGetOutput(output));
1050 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1052 v="? (no adaptor found)";
1057 v="? (no factory found)";
1063 v = bbGetOutput(output).unsafe_get<std::string>() ;
1067 //=========================================================================
1069 //=========================================================================
1070 std::string BlackBox::bbGetInputAsString( const std::string &input )
1073 // Looks for the adaptor
1074 if (bbGetInputType(input) != typeid(std::string))
1077 Package::Pointer p = bbGetDescriptor()->GetPackage();
1078 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1080 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1081 BlackBox::Pointer a;
1085 bbGetInputType(input),
1086 typeid(std::string),
1088 }catch (bbtk::Exception e)
1094 a->bbSetInput("In",bbGetInput(input));
1096 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1100 v="? (no adaptor found)";
1105 v="? (no factory found)";
1110 v = bbGetInput(input).unsafe_get<std::string>() ;
1114 //=======================================================================
1116 //=======================================================================
1117 // Replaces substrings "<" by "["
1118 void SubsBrackets ( std::string& s )
1120 // std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1121 std::string ss("<");
1122 std::string::size_type pos = 0;
1124 std::string cr("[");
1125 while ( pos != std::string::npos )
1127 // std::cout << "*** find one "<<std::endl;
1128 s.replace(pos,1,cr.c_str(),1);
1129 pos = s.find(ss, pos);
1135 while ( pos != std::string::npos )
1137 // std::cout << "*** find one "<<std::endl;
1138 s.replace(pos,1,cr.c_str(),1);
1139 pos = s.find(ss, pos);
1145 while ( pos != std::string::npos )
1147 // std::cout << "*** find one "<<std::endl;
1148 s.replace(pos,1,cr.c_str(),1);
1149 pos = s.find(ss, pos);
1150 } // std::cout << "AFTER=["<<s<<"]"<<std::endl;
1152 //=======================================================================
1154 //=========================================================================
1155 /// Write Graphviz-dot description in file
1156 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1157 BlackBox::Pointer parentblackbox,
1158 int detail, int level,
1159 bool instanceOrtype,
1160 bool relative_link )
1163 InputConnectorMapType::iterator i;
1165 std::string labelStr;
1166 std::string valueStr("");
1169 labelStr = bbGetName() ;
1171 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1173 labelStr = bbGetName();
1174 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
1177 SubsBrackets(labelStr);
1180 labelStr = labelStr + " | {{ ";
1181 std::string tempStrTypeName;
1184 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1188 labelStr=labelStr+" | ";
1191 if (instanceOrtype==true)
1193 valueStr = this->bbGetInputAsString(i->first) + " = ";
1195 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1196 tempStrTypeName=id->GetTypeName();
1197 SubsBrackets(tempStrTypeName);
1198 std::string Name(i->first);
1200 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
1202 labelStr=labelStr+ " } | {";
1204 OutputConnectorMapType::iterator ii;
1205 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
1209 labelStr=labelStr+" | ";
1212 if (instanceOrtype==true)
1214 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1216 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
1217 tempStrTypeName=id->GetTypeName();
1218 SubsBrackets(tempStrTypeName);
1219 std::string Name(ii->first);
1221 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
1223 labelStr = labelStr+ " } }" ;
1227 bbWriteDotInputOutputName(ff,true,detail,level);
1228 std::string tmp ( bbGetTypeName() );
1232 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1234 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1236 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1237 // std::cout << labelStr << std::endl;
1240 if (GetThisPointer<BlackBox>()!=parentblackbox){
1241 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1245 Connection* con = i->second->GetConnection();
1247 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1248 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1250 a->bbWriteDotInputOutputName(ff,false,detail,level);
1253 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1256 b->bbWriteDotInputOutputName(ff,true,detail,level);
1259 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1261 fprintf(ff,"%s\n",";");
1265 } // if parentblackbox
1267 //=========================================================================
1272 //=========================================================================
1273 void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox,
1274 int detail, int level
1275 /*,Factory *factory*/ )
1278 if (this->bbGetDescriptor()->GetPackage())
1280 bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
1281 this->bbGetDescriptor()->GetPackage()->GetName()
1282 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1286 bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1291 bbtkBlackBoxMessage("help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1292 <<mMinOutputChangeTime<<"]"<<std::endl);
1296 bbtkBlackBoxMessage("help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1297 <<mMinOutputChangeTime<<"]"<<std::endl);
1300 // bbtkBlackBoxMessage("help",1," "<<GetDescription()<<std::endl);
1301 // bbtkBlackBoxMessage("help",1," By : "<<GetAuthor()<<std::endl);
1303 std::vector<std::string> iname;
1304 std::vector<std::string> ivalue;
1305 std::vector<std::string> iconn;
1306 std::vector<std::string> istatus;
1308 InputConnectorMapType::iterator i;
1309 unsigned int namelmax = 0;
1310 unsigned int valuelmax = 0;
1311 // unsigned int connlmax = 0;
1312 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1314 iname.push_back(i->first);
1315 if (iname.back().size()>namelmax) namelmax = iname.back().size();
1316 ivalue.push_back(bbGetInputAsString(i->first));
1317 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1319 Connection* con = i->second->GetConnection();
1321 s = con->GetOriginalBlackBoxFrom()->bbGetName();
1323 s += con->GetOriginalBlackBoxFromOutput();
1326 istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1328 OutputConnectorMapType::iterator o;
1329 std::vector<std::string> oname;
1330 std::vector<std::string> ovalue;
1331 std::vector<std::vector<std::string> > oconn;
1332 std::vector<std::string> ostatus;
1333 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
1335 oname.push_back(o->first);
1336 if (oname.back().size()>namelmax)
1337 namelmax = oname.back().size();
1338 ovalue.push_back(bbGetOutputAsString(o->first));
1339 if (ovalue.back().size()>valuelmax)
1340 valuelmax = ovalue.back().size();
1341 std::vector<std::string> ss;
1342 const std::vector<Connection*>& con
1343 = o->second->GetConnectionVector();
1344 std::vector<Connection*>::const_iterator c;
1345 for (c=con.begin();c!=con.end();++c)
1348 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1350 s += (*c)->GetOriginalBlackBoxToInput();
1353 oconn.push_back(ss);
1354 ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1358 bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
1360 bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
1362 std::vector<std::string>::iterator i1,i2,i3,i4;
1363 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1364 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1365 ++i1,++i2,++i3,++i4)
1367 std::string name(*i1);
1369 name.append(1+namelmax-name.size(),' ');
1370 std::string value(*i2);
1372 value.append(1+valuelmax-value.size(),' ');
1374 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value<<" <-- '" <<*i3<<"'");
1376 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1377 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1381 bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
1383 bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
1385 std::vector<std::vector<std::string> >::iterator i5;
1387 for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1388 i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1389 ++i1,++i2,++i4,++i5)
1391 std::string name(*i1);
1393 name.append(1+namelmax-name.size(),' ');
1394 std::string value(*i2);
1396 value.append(1+valuelmax-value.size(),' ');
1398 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1401 std::string pref = " '"+name+" = '"+value;
1402 for (i3=i5->begin();i3!=i5->end();++i3)
1404 bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
1405 pref.replace(0,pref.size(),pref.size(),' ');
1408 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1412 //=========================================================================
1431 static bool bbmgGlobalProcessingExecutionList = false;
1433 //=========================================================================
1434 void BlackBox::bbGlobalProcessExecutionList()
1436 bbtkDebugMessage("process",3,
1437 "=> BlackBox::bbGlobalProcessExecutionList()"
1439 if (bbmgGlobalProcessingExecutionList)
1441 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1444 bbmgGlobalProcessingExecutionList = true;
1446 std::set<BlackBox::WeakPointer>::iterator i;
1447 while (bbmgExecutionList.size()>0)
1449 i = bbmgExecutionList.begin();
1450 BlackBox::WeakPointer p = *i;
1451 bbmgExecutionList.erase(i);
1454 bbtkDebugMessage("process",4,
1456 p.lock()->bbGetName()<<"'"<<std::endl);
1457 p.lock()->bbExecute(true);
1461 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1465 bbmgExecutionList.clear();
1466 bbtkDebugMessage("process",3,
1467 "<= BlackBox::bbGlobalProcessExecutionList()"
1470 bbmgGlobalProcessingExecutionList = false;
1473 //=========================================================================
1475 bool BlackBox::bbGlobalGetSomeBoxExecuting()
1477 return bbmgSomeBoxExecuting;
1480 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
1482 bbmgSomeBoxExecuting = b;
1485 void BlackBox::bbGlobalSetFreezeExecution(bool b)
1487 bbmgFreezeExecution = b;
1490 bool BlackBox::bbGlobalGetFreezeExecution()
1492 return bbmgFreezeExecution;
1495 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1497 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
1498 if (bbmgGlobalProcessingExecutionList)
1500 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1502 bbmgExecutionList.insert(b);
1506 //=========================================================================
1508 //=========================================================================
1509 void BlackBox::Check(bool recursive)
1511 bbtkBlackBoxMessage("debug",1,"*** Checking"
1512 <<" ... OK"<<std::endl);
1514 //=========================================================================
1519 } // EO namespace bbtk