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;
192 //=========================================================================
194 //=========================================================================
195 void BlackBox::bbGetHelp(bool full) const
197 bbGetDescriptor()->GetHelp(full);
199 //=========================================================================
202 //=========================================================================
203 bool BlackBox::bbHasInput(const std::string& name) const
205 bbtkBlackBoxDebugMessage("kernel",8,
206 "BlackBox::bbHasInput(\""
209 bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
210 != bbGetDescriptor()->GetInputDescriptorMap().end());
211 bbtkDebugDecTab("kernel",8);
214 //=========================================================================
217 //=========================================================================
218 bool BlackBox::bbHasOutput(const std::string& name) const
220 bbtkBlackBoxDebugMessage("kernel",8,"BlackBox::bbHasOutput(\""
223 bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
224 != bbGetDescriptor()->GetOutputDescriptorMap().end());
225 bbtkDebugDecTab("kernel",8);
228 //=========================================================================
231 //=========================================================================
232 TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const
234 bbtkBlackBoxDebugMessage("kernel",8,
235 "BlackBox::bbGetOutputType(\""
238 TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
239 bbtkDebugDecTab("kernel",8);
242 //=========================================================================
244 //=========================================================================
245 TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
247 bbtkBlackBoxDebugMessage("kernel",8,
248 "BlackBox::bbGetInputType(\""
251 TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
252 bbtkDebugDecTab("kernel",8);
255 //=========================================================================
258 //=========================================================================
259 void BlackBox::bbAllocateConnectors()
261 bbtkBlackBoxDebugMessage("kernel",8,
262 "BlackBox::bbAllocateConnectors()"
265 MakeBlackBoxPointer(this,true);
267 const BlackBoxDescriptor::InputDescriptorMapType& imap
268 = bbGetDescriptor()->GetInputDescriptorMap();
269 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
270 for ( i = imap.begin(); i != imap.end(); ++i )
272 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
273 bbGetInputConnectorMap()[i->second->GetName()]
274 = new BlackBoxInputConnector(GetThisPointer<BlackBox>());
276 const BlackBoxDescriptor::OutputDescriptorMapType& omap
277 = bbGetDescriptor()->GetOutputDescriptorMap();
278 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
279 for ( o = omap.begin(); o != omap.end(); ++o )
281 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
282 bbGetOutputConnectorMap()[o->second->GetName()]
283 = new BlackBoxOutputConnector(GetThisPointer<BlackBox>());
286 //=========================================================================
289 //=========================================================================
290 void BlackBox::bbDesallocateConnectors()
292 bbtkBlackBoxDebugMessage("kernel",8,
293 "BlackBox::bbDesallocateConnectors()"
296 InputConnectorMapType::const_iterator i;
297 for ( i = bbGetInputConnectorMap().begin();
298 i != bbGetInputConnectorMap().end(); ++i )
300 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<i->first<<"\""<<std::endl);
303 OutputConnectorMapType::const_iterator o;
304 for ( o = bbGetOutputConnectorMap().begin();
305 o != bbGetOutputConnectorMap().end(); ++o )
307 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<o->first<<"\""<<std::endl);
311 bbtkDebugDecTab("kernel",8);
313 //=========================================================================
316 //=========================================================================
317 void BlackBox::bbCopyIOValues(BlackBox& from)
319 bbtkBlackBoxDebugMessage("kernel",1,
320 "BlackBox::bbCopyIOValues("
321 <<from.bbGetFullName()<<")"
323 // copies the input values
324 const BlackBoxDescriptor::InputDescriptorMapType& imap
325 = bbGetDescriptor()->GetInputDescriptorMap();
326 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
327 for ( i = imap.begin(); i != imap.end(); ++i )
329 if (! i->second->GetCopyConstruct() ) continue;
330 std::string input = i->second->GetName();
331 bbtkBlackBoxDebugMessage("kernel",2,"* Copying input "<<input<<std::endl);
332 this->bbSetInput(input, from.bbGetInput(input) );
334 // copies the output values
335 const BlackBoxDescriptor::OutputDescriptorMapType& omap
336 = bbGetDescriptor()->GetOutputDescriptorMap();
337 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
338 for ( o = omap.begin(); o != omap.end(); ++o )
340 if (! o->second->GetCopyConstruct() ) continue;
341 std::string output = o->second->GetName();
342 bbtkBlackBoxDebugMessage("kernel",2,"* Copying output "<<output<<std::endl);
343 this->bbSetOutput(output, from.bbGetOutput(output) );
346 bbtkDebugDecTab("kernel",9);
348 //=========================================================================
352 //=========================================================================
353 bool BlackBox::bbCanReact() const
355 return ( bbGlobalGetSomeBoxExecuting()
357 || Wx::IsSomeWindowAlive()
361 //=========================================================================
365 //=========================================================================
366 BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
368 const std::string& p = bbmBoxProcessMode;
370 (p == "P") || (p == "p") ||
371 (p == "Pipeline") || (p == "pipeline") ) return bbPipeline;
373 (p == "A") || (p == "a") ||
374 (p == "Always") || (p == "always") ) return bbAlways;
376 (p == "R") || (p == "r") ||
377 (p == "Reactive") || (p == "reactive") )
381 (p == "F") || (p == "f") ||
382 (p == "Flash") || (p == "flash") ) return Flash;
386 (p == "M") || (p == "m") ||
387 (p == "Manual") || (p == "manual") ) return bbManual;
389 bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
390 <<"' unknown. Possible values : "
391 <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
392 <<"'1'/'A'/'a'/'Always'/'always' | "
393 <<"'2'/'R'/'r'/'Reactive'/'reactive'"
394 // <<"'3'/'F'/'f'/'Flash'/'flash'"
395 <<"'3'/'M'/'m'/'Manual'/'manual'"
398 //=========================================================================
400 //=========================================================================
401 bool BlackBox::bbBoxProcessModeIsReactive() const
403 return (bbGetBoxProcessModeValue() == bbReactive);
405 //=========================================================================
407 //=========================================================================
408 bool BlackBox::bbBoxProcessModeIsAlways() const
410 return (bbGetBoxProcessModeValue() == bbAlways);
412 //=========================================================================
415 //=========================================================================
416 bool BlackBox::bbBoxProcessModeIsManual() const
418 return (bbGetBoxProcessModeValue() == bbManual);
420 //=========================================================================
423 //=========================================================================
424 void BlackBox::bbAddOutputObserver(const std::string& output,
425 OutputChangeCallbackType f)
427 bbGetOutputConnector(output).AddChangeObserver(f);
429 //=========================================================================
431 //=========================================================================
432 void BlackBox::bbRemoveOutputObserver(const std::string& output_name,
433 OutputChangeCallbackType f)
435 bbtkError("BlackBox::RemoveChangeObserver NOT IMPLEMENTED");
437 //=========================================================================
440 //=========================================================================
441 void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
444 bbtkBlackBoxDebugMessage("change",5,
445 "=> BlackBox::bbSetStatusAndPropagate(input,"
446 <<GetIOStatusString(s)<<")"
449 if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
454 if (bbGetBoxProcessModeValue() == Flash)
461 OutputConnectorMapType::const_iterator o;
462 for ( o = bbGetOutputConnectorMap().begin();
463 o != bbGetOutputConnectorMap().end(); ++o )
467 if (o->first=="BoxChange")
469 o->second->SetStatus(UPTODATE);
476 if (o->second->GetStatus()==UPTODATE)
477 // if ((o->second->GetStatus()==UPTODATE) || (o->second->GetStatus()==OUTOFDATE))
478 // if ((o->second->GetStatus()==UPTODATE) || (o->second->GetStatus()==MODIFIED))
480 o->second->SetStatus(OUTOFDATE);
481 o->second->SignalChange(GetThisPointer<BlackBox>(),o->first);
486 if ( ( bbBoxProcessModeIsReactive()
487 || (c==bbGetInputConnectorMap().find("BoxExecute")->second))
490 bbtkBlackBoxDebugMessage("change",2,
491 "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
492 bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
494 bbtkBlackBoxDebugMessage("change",5,
495 "<= BlackBox::bbSetStatusAndPropagate(input)"
498 //=========================================================================
501 //=========================================================================
502 void BlackBox::bbSignalOutputModification(bool reaction)
504 bbtkBlackBoxDebugMessage("change",5,
505 "=> BlackBox::bbSignalOutputModification("
509 OutputConnectorMapType::iterator i;
510 for ( i = bbGetOutputConnectorMap().begin();
511 i != bbGetOutputConnectorMap().end(); ++i)
513 // std::cout << "Stat = "
514 //<<GetIOStatusString(i->second->GetStatus())
516 // LG : CANNOT SIGNAL ONLY WHEN UPTODATE
517 // See bbtkSampleOutputObserver
518 // if (i->second->GetStatus()==UPTODATE)
520 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
524 if (reaction) bbGlobalProcessExecutionList();
526 bbtkBlackBoxDebugMessage("change",5,
527 "<= BlackBox::bbSignalOutputModification()"
530 //=========================================================================
533 //=========================================================================
534 void BlackBox::bbSignalOutputModification(const std::string& output,
537 bbtkBlackBoxDebugMessage("change",5,
538 "=> BlackBox::bbSignalOutputModification("
539 <<output<<","<<reaction<<")"
542 OutputConnectorMapType::iterator i =
543 bbGetOutputConnectorMap().find(output);
546 if ( i == bbGetOutputConnectorMap().end() )
548 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
551 // if (i->second->GetStatus()==UPTODATE)
553 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
554 // Has to notify the output "BoxChange" also
555 if (output != "BoxChange")
557 i = bbGetOutputConnectorMap().find("BoxChange");
558 if ( i != bbGetOutputConnectorMap().end() )
560 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
563 if (reaction) bbGlobalProcessExecutionList();
566 bbtkBlackBoxDebugMessage("change",5,
567 "<= BlackBox::bbSignalOutputModification("
571 //=========================================================================
572 //=========================================================================
573 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
576 bbtkBlackBoxDebugMessage("change",5,
577 "=> BlackBox::bbSignalOutputModification(vector of outputs)"
579 OutputConnectorMapType::iterator i;
580 std::vector<std::string>::const_iterator o;
581 bool changed = false;
582 for (o=output.begin();o!=output.end();++o)
584 // the output "BoxChange" must be signaled **AFTER** all others
585 if (*o == "BoxChange") continue;
586 // Look for the connector
587 i = bbGetOutputConnectorMap().find(*o);
588 if ( i == bbGetOutputConnectorMap().end() )
590 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
593 // if (i->second->GetStatus()==UPTODATE)
595 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
599 // Has to notify the output "BoxChange" also
600 i = bbGetOutputConnectorMap().find("BoxChange");
601 if ( changed && (i != bbGetOutputConnectorMap().end()))
603 // if (i->second->GetStatus()==UPTODATE)
605 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
606 if (reaction) bbGlobalProcessExecutionList();
610 bbtkBlackBoxDebugMessage("change",5,
611 "<= BlackBox::bbSignalOutputModification(vector of outputs)"
614 //=========================================================================
622 //=========================================================================
623 /// Main processing method of the box.
624 void BlackBox::bbExecute(bool force)
626 bbtkBlackBoxDebugMessage("process",2,
627 "=> BlackBox::bbExecute("<<(int)force<<")"
630 // If already executing : return
632 if (bbGetExecuting())
634 bbtkBlackBoxDebugMessage("process",2,
635 " -> already executing : abort"<<std::endl);
640 // If execution frozen : return
641 if (bbGlobalGetFreezeExecution())
643 bbtkBlackBoxDebugMessage("process",2,
644 " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
649 // If force is true then update is triggered even if the box is UPTODATE
650 // if (force) bbSetModifiedStatus();
652 if ( bbBoxProcessModeIsManual() )
654 bbLetRecursiveExecuteManualMode = true;
658 // Calls the main recursive execution method
659 bbRecursiveExecute(Connection::Pointer());
662 if ( bbBoxProcessModeIsManual() )
664 bbLetRecursiveExecuteManualMode = false;
668 bbtkBlackBoxDebugMessage("process",2,
669 "<= BlackBox::bbExecute()"
672 //=========================================================================
674 //=========================================================================
675 void BlackBox::bbInitializeProcessing()
679 bbtkBlackBoxDebugMessage("process",2,"** Initialize processing"
681 this->bbRecursiveInitializeProcessing();
682 bbmInitialized = true;
685 //=========================================================================
687 //=========================================================================
688 void BlackBox::bbFinalizeProcessing()
692 bbtkBlackBoxDebugMessage("process",2,"** Finalize processing"
694 this->bbRecursiveFinalizeProcessing();
695 bbmInitialized = false;
698 //=========================================================================
701 //=========================================================================
702 void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
704 bbtkBlackBoxDebugMessage("process",3,
705 "=> BlackBox::bbRecursiveExecute("
706 <<(caller?caller->GetFullName():"0")<<")"
709 // If already executing : return
710 if (bbGetExecuting())
712 bbtkBlackBoxDebugMessage("process",3,
713 " -> already executing : abort"<<std::endl);
717 // If not initialized do it
718 bbInitializeProcessing();
720 bbSetExecuting(true);
721 bool wasExecuting = bbGlobalGetSomeBoxExecuting();
722 bbGlobalSetSomeBoxExecuting(true);
724 // Creates the window if the black box has one
725 this->bbCreateWindow();
727 // Updates its inputs
731 // IOStatus s=OUTOFDATE;
732 // IOStatus s=MODIFIED;
734 if ( ( bbBoxProcessModeIsManual()==false ) ||
735 ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) ) )
737 s = bbUpdateInputs();
740 if ( (s != UPTODATE) || bbBoxProcessModeIsAlways() )
742 // Displays the window (WxBlackbox)
743 // bbShowWindow(caller);
745 // Actual processing (virtual)
746 if ( ( bbBoxProcessModeIsManual()==false ) ||
747 ( (bbBoxProcessModeIsManual()==true)&&(bbLetRecursiveExecuteManualMode==true) )
751 //printf("EED BlackBox::bbRecursiveExecute bbProcess start %s \n", bbGetFullName().c_str() );
753 //auto start = std::chrono::high_resolution_clock::now();
755 //auto stop = std::chrono::high_resolution_clock::now();
756 //auto duration = duration_cast<std::chrono::microseconds>(stop - start);
757 //printf("EED BlackBox::bbRecursiveExecute bbProcess time= %ld %s \n", duration.count() , bbGetFullName().c_str() );
759 //printf("EED BlackBox::bbRecursiveExecute bbProcess end %s \n", bbGetFullName().c_str() );
763 //EED ups if ((bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false))
765 //EED ups bbSignalOutputModification(true);
768 // Update the I/O statuses
769 bbComputePostProcessStatus();
771 // Test output status...
772 OutputConnectorMapType::iterator o;
773 for ( o = bbGetOutputConnectorMap().begin();
774 o!= bbGetOutputConnectorMap().end(); ++o)
776 if (o->second->GetStatus() != UPTODATE)
778 bbtkWarning("BlackBox::bbRecursiveExecute: "
779 <<"all inputs are Up-to-date but output '"
780 <<o->first<<"' is Out-of-date ???");
784 bbtkBlackBoxDebugMessage("process",3," -> Up-to-date : nothing to do"
788 // Shows the window if the black box has one
789 this->bbShowWindow();
792 bbtkBlackBoxDebugMessage("process",3,
793 "<= BlackBox::bbRecursiveExecute()"
796 bbSetExecuting(false);
797 bbGlobalSetSomeBoxExecuting(wasExecuting);
801 //=========================================================================
804 //=========================================================================
805 IOStatus BlackBox::bbUpdateInputs()
807 bbtkBlackBoxDebugMessage("process",4,
808 "=> BlackBox::bbUpdateInputs()"
811 IOStatus s = UPTODATE;
813 InputConnectorMapType::iterator i;
814 for ( i = bbGetInputConnectorMap().begin();
815 i!= bbGetInputConnectorMap().end(); ++i)
817 // if (i->first=="WinHide") continue;
818 // If input type is Void : no recurse
819 //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo()
822 bbtkBlackBoxDebugMessage("change",2,
824 <<"': status before update = '"
825 <<GetIOStatusString(i->second->GetStatus())
827 i->second->RecursiveExecute();
828 IOStatus t = i->second->GetStatus();
830 bbtkBlackBoxDebugMessage("change",2,
832 <<"': status before process = '"
833 <<GetIOStatusString(i->second->GetStatus())
837 bbtkBlackBoxDebugMessage("process",4,
838 "<= BlackBox::bbUpdateInputs()"
842 //=========================================================================
844 //==================================================================
845 void BlackBox::bbComputePostProcessStatus()
847 bbtkBlackBoxDebugMessage("process",4,
848 "=> BlackBox::bbComputePostProcessStatus()"
851 IOStatus new_output_status = UPTODATE;
852 if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
854 // Update the input statuses
855 InputConnectorMapType::iterator i;
856 for ( i = bbGetInputConnectorMap().begin();
857 i!= bbGetInputConnectorMap().end(); ++i)
859 IOStatus t = i->second->GetStatus();
860 if (t == OUTOFDATE) new_output_status = OUTOFDATE;
861 // A previously MODIFIED status turns to UPTODATE
862 if (t==MODIFIED) i->second->SetStatus(UPTODATE);
863 bbtkBlackBoxDebugMessage("change",2,
864 "Input '"<<i->first<<"' : "
865 << GetIOStatusString(t) << " -> "
866 << GetIOStatusString(i->second->GetStatus())
869 bbtkBlackBoxDebugMessage("change",2,
870 "New output status : "
871 << GetIOStatusString(new_output_status)
873 // Update the output statuses
874 OutputConnectorMapType::iterator o;
875 for ( o = bbGetOutputConnectorMap().begin();
876 o!= bbGetOutputConnectorMap().end(); ++o)
879 //EED if ( ( bbBoxProcessModeIsManual()==false ) ||
880 //EED ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) )
883 o->second->SetStatus(new_output_status);
885 //EED if (( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false) ) )
887 //EED o->second->SetStatus(UPTODATE);
889 //EED } // Manual analysis
893 bbtkBlackBoxDebugMessage("process",4,
894 "<= BlackBox::bbComputePostProcessStatus()"
897 //==================================================================
899 //=========================================================================
900 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
902 bbtkBlackBoxDebugMessage("connection",2,
903 "==> BlackBox::bbConnectInput(\""
904 <<name<<"\","<<c->GetFullName()<<")"
907 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
908 if (i==bbGetInputConnectorMap().end())
910 bbtkError("no input called '"<<name<<"'");
912 i->second->SetConnection(c);
913 // The input *MUST* be set OUTOFDATE to update its input on next execution
914 bbSetStatusAndPropagate(i->second,OUTOFDATE);
916 bbtkBlackBoxDebugMessage("connection",2,
917 "<== BlackBox::bbConnectInput(\""
918 <<name<<"\","<<c->GetFullName()<<")"
921 //=========================================================================
924 //=========================================================================
925 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
927 bbtkBlackBoxDebugMessage("connection",2,
928 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
929 <<c->GetFullName()<<")"
932 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
933 if (i==bbGetOutputConnectorMap().end())
935 bbtkError("no output called '"<<name<<"'");
937 i->second->SetConnection(c);
939 bbtkBlackBoxDebugMessage("connection",2,
940 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
941 <<c->GetFullName()<<")"
944 //=========================================================================
947 //=========================================================================
948 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
951 bbtkBlackBoxDebugMessage("connection",2,
952 "==> BlackBox::bbDisconnectInput(\""<<name
953 <<"\","<<c->GetFullName()<<")"
958 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
962 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
963 if (i==bbGetInputConnectorMap().end())
965 bbtkError("no input called '"<<name<<"'");
967 i->second->UnsetConnection(c);
969 bbtkBlackBoxDebugMessage("connection",2,
970 "<== BlackBox::bbDisconnectInput(\""<<name
971 <<"\","<<c->GetFullName()<<")"
975 //=========================================================================
978 //=========================================================================
979 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
981 bbtkBlackBoxDebugMessage("connection",2,
982 "==> BlackBox::bbDisconnectOutput(\""<<name
983 <<"\","<<c->GetFullName()<<")"
988 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
992 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
993 if (i==bbGetOutputConnectorMap().end())
995 bbtkError("no output called '"<<name<<"'");
997 i->second->UnsetConnection(c);
999 bbtkBlackBoxDebugMessage("connection",2,
1000 "<== BlackBox::bbDisconnectOutput(\""<<name
1001 <<"\","<<c->GetFullName()<<")"
1004 //=========================================================================
1028 //=========================================================================
1029 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
1031 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
1033 //=========================================================================
1036 //=========================================================================
1037 std::string BlackBox::bbGetOutputAsString( const std::string &output )
1040 // Looks for the adaptor
1041 if (bbGetOutputType(output).name() != typeid(std::string).name() )
1044 Package::Pointer p = bbGetDescriptor()->GetPackage();
1045 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1047 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1048 BlackBox::Pointer a;
1052 bbGetOutputType(output),
1053 typeid(std::string),
1055 } catch (bbtk::Exception e)
1060 a->bbSetInput("In",bbGetOutput(output));
1062 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1064 v="? (no adaptor found)";
1069 v="? (no factory found)";
1075 v = bbGetOutput(output).unsafe_get<std::string>() ;
1079 //=========================================================================
1081 //=========================================================================
1082 std::string BlackBox::bbGetInputAsString( const std::string &input )
1085 // Looks for the adaptor
1086 if (bbGetInputType(input) != typeid(std::string))
1089 Package::Pointer p = bbGetDescriptor()->GetPackage();
1090 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1092 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1093 BlackBox::Pointer a;
1097 bbGetInputType(input),
1098 typeid(std::string),
1100 }catch (bbtk::Exception e)
1106 a->bbSetInput("In",bbGetInput(input));
1108 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1112 v="? (no adaptor found)";
1117 v="? (no factory found)";
1122 v = bbGetInput(input).unsafe_get<std::string>() ;
1126 //=======================================================================
1128 //=======================================================================
1129 // Replaces substrings "<" by "["
1130 void SubsBrackets ( std::string& s )
1132 // std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1133 std::string ss("<");
1134 std::string::size_type pos = 0;
1136 std::string cr("[");
1137 while ( pos != std::string::npos )
1139 // std::cout << "*** find one "<<std::endl;
1140 s.replace(pos,1,cr.c_str(),1);
1141 pos = s.find(ss, pos);
1147 while ( pos != std::string::npos )
1149 // std::cout << "*** find one "<<std::endl;
1150 s.replace(pos,1,cr.c_str(),1);
1151 pos = s.find(ss, pos);
1157 while ( pos != std::string::npos )
1159 // std::cout << "*** find one "<<std::endl;
1160 s.replace(pos,1,cr.c_str(),1);
1161 pos = s.find(ss, pos);
1162 } // std::cout << "AFTER=["<<s<<"]"<<std::endl;
1164 //=======================================================================
1166 //=========================================================================
1167 /// Write Graphviz-dot description in file
1168 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1169 BlackBox::Pointer parentblackbox,
1170 int detail, int level,
1171 bool instanceOrtype,
1172 bool relative_link )
1175 InputConnectorMapType::iterator i;
1177 std::string labelStr;
1178 std::string valueStr("");
1181 labelStr = bbGetName() ;
1183 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1185 labelStr = bbGetName();
1186 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
1189 SubsBrackets(labelStr);
1192 labelStr = labelStr + " | {{ ";
1193 std::string tempStrTypeName;
1196 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1200 labelStr=labelStr+" | ";
1203 if (instanceOrtype==true)
1205 valueStr = this->bbGetInputAsString(i->first) + " = ";
1207 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1208 tempStrTypeName=id->GetTypeName();
1209 SubsBrackets(tempStrTypeName);
1210 std::string Name(i->first);
1212 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
1214 labelStr=labelStr+ " } | {";
1216 OutputConnectorMapType::iterator ii;
1217 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
1221 labelStr=labelStr+" | ";
1224 if (instanceOrtype==true)
1226 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1228 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
1229 tempStrTypeName=id->GetTypeName();
1230 SubsBrackets(tempStrTypeName);
1231 std::string Name(ii->first);
1233 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
1235 labelStr = labelStr+ " } }" ;
1239 bbWriteDotInputOutputName(ff,true,detail,level);
1240 std::string tmp ( bbGetTypeName() );
1244 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1246 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1248 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1249 // std::cout << labelStr << std::endl;
1252 if (GetThisPointer<BlackBox>()!=parentblackbox){
1253 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1257 Connection* con = i->second->GetConnection();
1259 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1260 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1262 a->bbWriteDotInputOutputName(ff,false,detail,level);
1265 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1268 b->bbWriteDotInputOutputName(ff,true,detail,level);
1271 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1273 fprintf(ff,"%s\n",";");
1277 } // if parentblackbox
1279 //=========================================================================
1284 //=========================================================================
1285 void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox,
1286 int detail, int level
1287 /*,Factory *factory*/ )
1290 if (this->bbGetDescriptor()->GetPackage())
1292 bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
1293 this->bbGetDescriptor()->GetPackage()->GetName()
1294 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1298 bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1303 bbtkBlackBoxMessage("help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1304 <<mMinOutputChangeTime<<"]"<<std::endl);
1308 bbtkBlackBoxMessage("help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1309 <<mMinOutputChangeTime<<"]"<<std::endl);
1312 // bbtkBlackBoxMessage("help",1," "<<GetDescription()<<std::endl);
1313 // bbtkBlackBoxMessage("help",1," By : "<<GetAuthor()<<std::endl);
1315 std::vector<std::string> iname;
1316 std::vector<std::string> ivalue;
1317 std::vector<std::string> iconn;
1318 std::vector<std::string> istatus;
1320 InputConnectorMapType::iterator i;
1321 unsigned int namelmax = 0;
1322 unsigned int valuelmax = 0;
1323 // unsigned int connlmax = 0;
1324 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1326 iname.push_back(i->first);
1327 if (iname.back().size()>namelmax) namelmax = iname.back().size();
1328 ivalue.push_back(bbGetInputAsString(i->first));
1329 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1331 Connection* con = i->second->GetConnection();
1333 s = con->GetOriginalBlackBoxFrom()->bbGetName();
1335 s += con->GetOriginalBlackBoxFromOutput();
1338 istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1340 OutputConnectorMapType::iterator o;
1341 std::vector<std::string> oname;
1342 std::vector<std::string> ovalue;
1343 std::vector<std::vector<std::string> > oconn;
1344 std::vector<std::string> ostatus;
1345 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
1347 oname.push_back(o->first);
1348 if (oname.back().size()>namelmax)
1349 namelmax = oname.back().size();
1350 ovalue.push_back(bbGetOutputAsString(o->first));
1351 if (ovalue.back().size()>valuelmax)
1352 valuelmax = ovalue.back().size();
1353 std::vector<std::string> ss;
1354 const std::vector<Connection*>& con
1355 = o->second->GetConnectionVector();
1356 std::vector<Connection*>::const_iterator c;
1357 for (c=con.begin();c!=con.end();++c)
1360 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1362 s += (*c)->GetOriginalBlackBoxToInput();
1365 oconn.push_back(ss);
1366 ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1370 bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
1372 bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
1374 std::vector<std::string>::iterator i1,i2,i3,i4;
1375 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1376 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1377 ++i1,++i2,++i3,++i4)
1379 std::string name(*i1);
1381 name.append(1+namelmax-name.size(),' ');
1382 std::string value(*i2);
1384 value.append(1+valuelmax-value.size(),' ');
1386 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value<<" <-- '" <<*i3<<"'");
1388 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1389 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1393 bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
1395 bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
1397 std::vector<std::vector<std::string> >::iterator i5;
1399 for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1400 i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1401 ++i1,++i2,++i4,++i5)
1403 std::string name(*i1);
1405 name.append(1+namelmax-name.size(),' ');
1406 std::string value(*i2);
1408 value.append(1+valuelmax-value.size(),' ');
1410 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1413 std::string pref = " '"+name+" = '"+value;
1414 for (i3=i5->begin();i3!=i5->end();++i3)
1416 bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
1417 pref.replace(0,pref.size(),pref.size(),' ');
1420 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1424 //=========================================================================
1443 static bool bbmgGlobalProcessingExecutionList = false;
1445 //=========================================================================
1446 void BlackBox::bbGlobalProcessExecutionList()
1448 bbtkDebugMessage("process",3,
1449 "=> BlackBox::bbGlobalProcessExecutionList()"
1451 if (bbmgGlobalProcessingExecutionList)
1453 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1456 bbmgGlobalProcessingExecutionList = true;
1458 std::set<BlackBox::WeakPointer>::iterator i;
1459 while (bbmgExecutionList.size()>0)
1461 i = bbmgExecutionList.begin();
1462 BlackBox::WeakPointer p = *i;
1463 bbmgExecutionList.erase(i);
1466 bbtkDebugMessage("process",4,
1468 p.lock()->bbGetName()<<"'"<<std::endl);
1469 p.lock()->bbExecute(true);
1473 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1477 bbmgExecutionList.clear();
1478 bbtkDebugMessage("process",3,
1479 "<= BlackBox::bbGlobalProcessExecutionList()"
1482 bbmgGlobalProcessingExecutionList = false;
1486 //=========================================================================
1488 bool BlackBox::bbGlobalGetSomeBoxExecuting()
1490 return bbmgSomeBoxExecuting;
1493 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
1495 bbmgSomeBoxExecuting = b;
1498 void BlackBox::bbGlobalSetFreezeExecution(bool b)
1500 bbmgFreezeExecution = b;
1503 bool BlackBox::bbGlobalGetFreezeExecution()
1505 return bbmgFreezeExecution;
1508 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1510 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
1511 if (bbmgGlobalProcessingExecutionList)
1513 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1515 bbmgExecutionList.insert(b);
1519 //=========================================================================
1521 //=========================================================================
1522 void BlackBox::Check(bool recursive)
1524 bbtkBlackBoxMessage("debug",1,"*** Checking"
1525 <<" ... OK"<<std::endl);
1527 //=========================================================================
1532 } // EO namespace bbtk