1 /*=========================================================================
3 Module: $RCSfile: bbtkBlackBox.cxx,v $
5 Date: $Date: 2012/07/26 08:28:31 $
6 Version: $Revision: 1.55 $
7 =========================================================================*/
9 /* ---------------------------------------------------------------------
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 * This software is governed by the CeCILL-B license under French law and
15 * abiding by the rules of distribution of free software. You can use,
16 * modify and/ or redistribute the software under the terms of the CeCILL-B
17 * license as circulated by CEA, CNRS and INRIA at the following URL
18 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
19 * or in the file LICENSE.txt.
21 * As a counterpart to the access to the source code and rights to copy,
22 * modify and redistribute granted by the license, users are provided only
23 * with a limited warranty and the software's author, the holder of the
24 * economic rights, and the successive licensors have only limited
27 * The fact that you are presently reading this means that you have had
28 * knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */
33 * \brief Class bbtk::BlackBox : abstract black-box interface.
35 #include "bbtkBlackBox.h"
36 #include "bbtkPackage.h"
37 #include "bbtkMessageManager.h"
38 #include "bbtkFactory.h"
39 #include "bbtkBlackBoxOutputConnector.h"
41 #include "bbtkConfigurationFile.h"
42 #include "bbtkWxBlackBox.h"
51 static bool bbmgSomeBoxExecuting = false;
52 static bool bbmgFreezeExecution = false;
53 static std::set<BlackBox::WeakPointer> bbmgExecutionList;
55 //=========================================================================
57 BlackBox::Deleter::Deleter()
60 //=========================================================================
62 //=========================================================================
63 int BlackBox::Deleter::Delete(Object* p)
65 BlackBox* b = dynamic_cast<BlackBox*>(p);
68 bbtkInternalError("BlackBox::Deleter::Delete("<<p->GetObjectName()
70 <<"dynamic cast to BlackBox* failed !");
72 std::string name = p->GetObjectName();//b->bbGetNameWithParent();
73 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
76 BlackBoxDescriptor::WeakPointer desc = b->bbGetDescriptor();
77 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : deleting black box"<<std::endl);
79 int refs = b->bbDelete();
81 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : releasing descriptor"<<std::endl);
85 Package::WeakPointer pack = desc.lock()->GetPackage();
88 Package::ReleaseBlackBoxDescriptor(pack,desc);
92 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor package expired (was not held by a package and the box was the last instance)"<<std::endl);
97 bbtkDebugMessage("object",2,"##> BlackBox::Deleter(\""<<name<<"\") : descriptor expired : nothing to do (was not held by a package or the box is a complex black box prototype)"<<std::endl);
99 bbtkDebugMessage("object",2,"<## BlackBox::Deleter(\""<<name<<"\")"<<std::endl);
102 //=========================================================================
104 //=========================================================================
105 BlackBox::BlackBox(const std::string &name)
107 // bbmStatus(MODIFIED),
108 bbmInitialized(false),
111 bbmBoxProcessMode("Pipeline"),
112 bbLetRecursiveExecuteManualMode(false),
117 // bbmBoxProcessMode = "Pipeline";
118 //std::cout<<"JCP BlackBox::BlackBox(const std::string &name) name=" <<name
119 // <<"bbmBoxProcessMode="<<bbmBoxProcessMode<<std::endl;
120 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox(\""
121 <<name<<"\")"<<std::endl);
122 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox(\""
123 <<name<<"\")"<<std::endl);
125 //=========================================================================
127 //=========================================================================
128 BlackBox::BlackBox(const BlackBox&)
131 //=========================================================================
132 BlackBox::BlackBox(BlackBox& from, const std::string &name)
134 // bbmStatus(from.bbmStatus),
135 bbmInitialized(false),
138 bbmBoxProcessMode(from.bbmBoxProcessMode),
139 bbLetRecursiveExecuteManualMode(false),
144 //bbmBoxProcessMode = from.bbmBoxProcessMode;
145 //std::cout<<"JCP BlackBox::BlackBox(const std::string &name) name=" <<name
146 // <<"bbmBoxProcessMode="<<bbmBoxProcessMode<<std::endl;
147 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::BlackBox("
148 <<from.bbGetFullName()<<",\""
149 <<name<<"\")"<<std::endl);
150 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::BlackBox("
151 <<from.bbGetFullName()<<",\""
152 <<name<<"\")"<<std::endl);
154 //=========================================================================
157 //=========================================================================
158 BlackBox::~BlackBox()
160 bbtkBlackBoxDebugMessage("object",4,"==> BlackBox::~BlackBox() ["<<bbmName
162 this->bbDesallocateConnectors();
163 bbtkBlackBoxDebugMessage("object",4,"<== BlackBox::~BlackBox() ["<<bbmName
166 //=========================================================================
170 //=========================================================================
171 std::string BlackBox::bbGetFullName() const
173 return this->bbGetNameWithParent()+"<"+this->bbGetDescriptor()->GetTypeName()+">";
175 //=========================================================================
179 //=========================================================================
180 std::string BlackBox::bbGetNameWithParent() const
182 if (bbmParent.lock())
184 return bbmParent.lock()->bbGetNameWithParent() + ":" + bbmName;
191 //=========================================================================
193 //=========================================================================
194 void BlackBox::bbGetHelp(bool full) const
196 bbGetDescriptor()->GetHelp(full);
198 //=========================================================================
201 //=========================================================================
202 bool BlackBox::bbHasInput(const std::string& name) const
204 bbtkBlackBoxDebugMessage("kernel",8,
205 "BlackBox::bbHasInput(\""
208 bool r = ( bbGetDescriptor()->GetInputDescriptorMap().find(name)
209 != bbGetDescriptor()->GetInputDescriptorMap().end());
210 bbtkDebugDecTab("kernel",8);
213 //=========================================================================
216 //=========================================================================
217 bool BlackBox::bbHasOutput(const std::string& name) const
219 bbtkBlackBoxDebugMessage("kernel",8,"BlackBox::bbHasOutput(\""
222 bool r = ( bbGetDescriptor()->GetOutputDescriptorMap().find(name)
223 != bbGetDescriptor()->GetOutputDescriptorMap().end());
224 bbtkDebugDecTab("kernel",8);
227 //=========================================================================
230 //=========================================================================
231 TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const
233 bbtkBlackBoxDebugMessage("kernel",8,
234 "BlackBox::bbGetOutputType(\""
237 TypeInfo r = bbGetDescriptor()->GetOutputDescriptor(name)->GetTypeInfo();
238 bbtkDebugDecTab("kernel",8);
241 //=========================================================================
243 //=========================================================================
244 TypeInfo BlackBox::bbGetInputType( const std::string &name ) const
246 bbtkBlackBoxDebugMessage("kernel",8,
247 "BlackBox::bbGetInputType(\""
250 TypeInfo r = bbGetDescriptor()->GetInputDescriptor(name)->GetTypeInfo();
251 bbtkDebugDecTab("kernel",8);
254 //=========================================================================
257 //=========================================================================
258 void BlackBox::bbAllocateConnectors()
260 bbtkBlackBoxDebugMessage("kernel",8,
261 "BlackBox::bbAllocateConnectors()"
264 MakeBlackBoxPointer(this,true);
266 const BlackBoxDescriptor::InputDescriptorMapType& imap
267 = bbGetDescriptor()->GetInputDescriptorMap();
268 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
269 for ( i = imap.begin(); i != imap.end(); ++i )
271 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
272 bbGetInputConnectorMap()[i->second->GetName()]
273 = new BlackBoxInputConnector(GetThisPointer<BlackBox>());
275 const BlackBoxDescriptor::OutputDescriptorMapType& omap
276 = bbGetDescriptor()->GetOutputDescriptorMap();
277 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
278 for ( o = omap.begin(); o != omap.end(); ++o )
280 bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
281 bbGetOutputConnectorMap()[o->second->GetName()]
282 = new BlackBoxOutputConnector(GetThisPointer<BlackBox>());
285 //=========================================================================
288 //=========================================================================
289 void BlackBox::bbDesallocateConnectors()
291 bbtkBlackBoxDebugMessage("kernel",8,
292 "BlackBox::bbDesallocateConnectors()"
295 InputConnectorMapType::const_iterator i;
296 for ( i = bbGetInputConnectorMap().begin();
297 i != bbGetInputConnectorMap().end(); ++i )
299 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<i->first<<"\""<<std::endl);
302 OutputConnectorMapType::const_iterator o;
303 for ( o = bbGetOutputConnectorMap().begin();
304 o != bbGetOutputConnectorMap().end(); ++o )
306 bbtkBlackBoxDebugMessage("kernel",8,"* Delete \""<<o->first<<"\""<<std::endl);
310 bbtkDebugDecTab("kernel",8);
312 //=========================================================================
315 //=========================================================================
316 void BlackBox::bbCopyIOValues(BlackBox& from)
318 bbtkBlackBoxDebugMessage("kernel",1,
319 "BlackBox::bbCopyIOValues("
320 <<from.bbGetFullName()<<")"
322 // copies the input values
323 const BlackBoxDescriptor::InputDescriptorMapType& imap
324 = bbGetDescriptor()->GetInputDescriptorMap();
325 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
326 for ( i = imap.begin(); i != imap.end(); ++i )
328 if (! i->second->GetCopyConstruct() ) continue;
329 std::string input = i->second->GetName();
330 bbtkBlackBoxDebugMessage("kernel",2,"* Copying input "<<input<<std::endl);
331 this->bbSetInput(input, from.bbGetInput(input) );
333 // copies the output values
334 const BlackBoxDescriptor::OutputDescriptorMapType& omap
335 = bbGetDescriptor()->GetOutputDescriptorMap();
336 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
337 for ( o = omap.begin(); o != omap.end(); ++o )
339 if (! o->second->GetCopyConstruct() ) continue;
340 std::string output = o->second->GetName();
341 bbtkBlackBoxDebugMessage("kernel",2,"* Copying output "<<output<<std::endl);
342 this->bbSetOutput(output, from.bbGetOutput(output) );
345 bbtkDebugDecTab("kernel",9);
347 //=========================================================================
351 //=========================================================================
352 bool BlackBox::bbCanReact() const
354 return ( bbGlobalGetSomeBoxExecuting()
356 || Wx::IsSomeWindowAlive()
360 //=========================================================================
364 //=========================================================================
365 BlackBox::BoxProcessModeValue BlackBox::bbGetBoxProcessModeValue() const
367 const std::string& p = bbmBoxProcessMode;
369 (p == "P") || (p == "p") ||
370 (p == "Pipeline") || (p == "pipeline") ) return bbPipeline;
372 (p == "A") || (p == "a") ||
373 (p == "Always") || (p == "always") ) return bbAlways;
375 (p == "R") || (p == "r") ||
376 (p == "Reactive") || (p == "reactive") )
380 (p == "F") || (p == "f") ||
381 (p == "Flash") || (p == "flash") ) return Flash;
385 (p == "M") || (p == "m") ||
386 (p == "Manual") || (p == "manual") ) return bbManual;
388 bbtkError(bbGetFullName()<<" : BoxProcessMode value '"<<p
389 <<"' unknown. Possible values : "
390 <<"'0'/'P'/'p'/'Pipeline'/'pipeline' | "
391 <<"'1'/'A'/'a'/'Always'/'always' | "
392 <<"'2'/'R'/'r'/'Reactive'/'reactive'"
393 // <<"'3'/'F'/'f'/'Flash'/'flash'"
394 <<"'3'/'M'/'m'/'Manual'/'manual'"
397 //=========================================================================
399 //=========================================================================
400 bool BlackBox::bbBoxProcessModeIsReactive() const
402 return (bbGetBoxProcessModeValue() == bbReactive);
404 //=========================================================================
406 //=========================================================================
407 bool BlackBox::bbBoxProcessModeIsAlways() const
409 return (bbGetBoxProcessModeValue() == bbAlways);
411 //=========================================================================
414 //=========================================================================
415 bool BlackBox::bbBoxProcessModeIsManual() const
417 return (bbGetBoxProcessModeValue() == bbManual);
419 //=========================================================================
422 //=========================================================================
423 void BlackBox::bbAddOutputObserver(const std::string& output,
424 OutputChangeCallbackType f)
426 bbGetOutputConnector(output).AddChangeObserver(f);
428 //=========================================================================
430 //=========================================================================
431 void BlackBox::bbRemoveOutputObserver(const std::string& output_name,
432 OutputChangeCallbackType f)
434 bbtkError("BlackBox::RemoveChangeObserver NOT IMPLEMENTED");
436 //=========================================================================
439 //=========================================================================
440 void BlackBox::bbSetStatusAndPropagate(BlackBoxInputConnector* c,
443 bbtkBlackBoxDebugMessage("change",5,
444 "=> BlackBox::bbSetStatusAndPropagate(input,"
445 <<GetIOStatusString(s)<<")"
448 if (s==UPTODATE) bbtkError("bbSetStatusAndPropagate with status UPTODATE!");
453 if (bbGetBoxProcessModeValue() == Flash)
459 OutputConnectorMapType::const_iterator o;
460 for ( o = bbGetOutputConnectorMap().begin();
461 o != bbGetOutputConnectorMap().end(); ++o )
463 if (o->second->GetStatus()==UPTODATE)
465 o->second->SetStatus(OUTOFDATE);
466 o->second->SignalChange(GetThisPointer<BlackBox>(),o->first);
470 if ( ( bbBoxProcessModeIsReactive()
471 || (c==bbGetInputConnectorMap().find("BoxExecute")->second))
474 bbtkBlackBoxDebugMessage("change",2,
475 "-> Execution triggered by Reactive mode or BoxExecute input change"<<std::endl);
476 bbGlobalAddToExecutionList( GetThisPointer<BlackBox>() );
478 bbtkBlackBoxDebugMessage("change",5,
479 "<= BlackBox::bbSetStatusAndPropagate(input)"
482 //=========================================================================
485 //=========================================================================
486 void BlackBox::bbSignalOutputModification(bool reaction)
488 bbtkBlackBoxDebugMessage("change",5,
489 "=> BlackBox::bbSignalOutputModification("
493 OutputConnectorMapType::iterator i;
494 for ( i = bbGetOutputConnectorMap().begin();
495 i != bbGetOutputConnectorMap().end(); ++i)
497 // std::cout << "Stat = "
498 //<<GetIOStatusString(i->second->GetStatus())
500 // LG : CANNOT SIGNAL ONLY WHEN UPTODATE
501 // See bbtkSampleOutputObserver
502 // if (i->second->GetStatus()==UPTODATE)
504 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
508 if (reaction) bbGlobalProcessExecutionList();
510 bbtkBlackBoxDebugMessage("change",5,
511 "<= BlackBox::bbSignalOutputModification()"
514 //=========================================================================
517 //=========================================================================
518 void BlackBox::bbSignalOutputModification(const std::string& output,
521 bbtkBlackBoxDebugMessage("change",5,
522 "=> BlackBox::bbSignalOutputModification("
523 <<output<<","<<reaction<<")"
526 OutputConnectorMapType::iterator i =
527 bbGetOutputConnectorMap().find(output);
530 if ( i == bbGetOutputConnectorMap().end() )
532 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<output<<") : unknown output");
535 // if (i->second->GetStatus()==UPTODATE)
537 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
538 // Has to notify the output "BoxChange" also
539 if (output != "BoxChange")
541 i = bbGetOutputConnectorMap().find("BoxChange");
542 if ( i != bbGetOutputConnectorMap().end() )
544 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
547 if (reaction) bbGlobalProcessExecutionList();
550 bbtkBlackBoxDebugMessage("change",5,
551 "<= BlackBox::bbSignalOutputModification("
555 //=========================================================================
556 //=========================================================================
557 void BlackBox::bbSignalOutputModification(const std::vector<std::string>& output,
560 bbtkBlackBoxDebugMessage("change",5,
561 "=> BlackBox::bbSignalOutputModification(vector of outputs)"
563 OutputConnectorMapType::iterator i;
564 std::vector<std::string>::const_iterator o;
565 bool changed = false;
566 for (o=output.begin();o!=output.end();++o)
568 // the output "BoxChange" must be signaled **AFTER** all others
569 if (*o == "BoxChange") continue;
570 // Look for the connector
571 i = bbGetOutputConnectorMap().find(*o);
572 if ( i == bbGetOutputConnectorMap().end() )
574 bbtkError("BlackBox["<<bbGetFullName()<<"]::bbSignalOutputModification("<<*o<<") : unknown output");
577 // if (i->second->GetStatus()==UPTODATE)
579 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
583 // Has to notify the output "BoxChange" also
584 i = bbGetOutputConnectorMap().find("BoxChange");
585 if ( changed && (i != bbGetOutputConnectorMap().end()))
587 // if (i->second->GetStatus()==UPTODATE)
589 i->second->SignalChange(GetThisPointer<BlackBox>(),i->first);
590 if (reaction) bbGlobalProcessExecutionList();
594 bbtkBlackBoxDebugMessage("change",5,
595 "<= BlackBox::bbSignalOutputModification(vector of outputs)"
598 //=========================================================================
606 //=========================================================================
607 /// Main processing method of the box.
608 void BlackBox::bbExecute(bool force)
610 bbtkBlackBoxDebugMessage("process",2,
611 "=> BlackBox::bbExecute("<<(int)force<<")"
614 // If already executing : return
616 if (bbGetExecuting())
618 bbtkBlackBoxDebugMessage("process",2,
619 " -> already executing : abort"<<std::endl);
624 // If execution frozen : return
625 if (bbGlobalGetFreezeExecution())
627 bbtkBlackBoxDebugMessage("process",2,
628 " -> FreezeExecution global flag is 'true' : abort execution"<<std::endl);
633 // If force is true then update is triggered even if the box is UPTODATE
634 // if (force) bbSetModifiedStatus();
636 if ( bbBoxProcessModeIsManual() )
638 bbLetRecursiveExecuteManualMode = true;
642 // Calls the main recursive execution method
643 bbRecursiveExecute(Connection::Pointer());
646 if ( bbBoxProcessModeIsManual() )
648 bbLetRecursiveExecuteManualMode = false;
652 bbtkBlackBoxDebugMessage("process",2,
653 "<= BlackBox::bbExecute()"
656 //=========================================================================
658 //=========================================================================
659 void BlackBox::bbInitializeProcessing()
663 bbtkBlackBoxDebugMessage("process",2,"** Initialize processing"
665 this->bbRecursiveInitializeProcessing();
666 bbmInitialized = true;
669 //=========================================================================
671 //=========================================================================
672 void BlackBox::bbFinalizeProcessing()
676 bbtkBlackBoxDebugMessage("process",2,"** Finalize processing"
678 this->bbRecursiveFinalizeProcessing();
679 bbmInitialized = false;
682 //=========================================================================
685 //=========================================================================
686 void BlackBox::bbRecursiveExecute( Connection::Pointer caller )
688 bbtkBlackBoxDebugMessage("process",3,
689 "=> BlackBox::bbRecursiveExecute("
690 <<(caller?caller->GetFullName():"0")<<")"
693 // If already executing : return
694 if (bbGetExecuting())
696 bbtkBlackBoxDebugMessage("process",3,
697 " -> already executing : abort"<<std::endl);
701 // If not initialized do it
702 bbInitializeProcessing();
704 bbSetExecuting(true);
705 bool wasExecuting = bbGlobalGetSomeBoxExecuting();
706 bbGlobalSetSomeBoxExecuting(true);
708 // Creates the window if the black box has one
709 this->bbCreateWindow();
711 // Updates its inputs
715 // IOStatus s=OUTOFDATE;
716 // IOStatus s=MODIFIED;
719 if ( ( bbBoxProcessModeIsManual()==false ) ||
720 ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) ) )
722 s = bbUpdateInputs();
725 if ( (s != UPTODATE) || bbBoxProcessModeIsAlways() )
727 // Displays the window (WxBlackbox)
728 // bbShowWindow(caller);
730 // Actual processing (virtual)
731 if ( ( bbBoxProcessModeIsManual()==false ) ||
732 ( (bbBoxProcessModeIsManual()==true)&&(bbLetRecursiveExecuteManualMode==true) )
738 //EED ups if ((bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false))
740 //EED ups bbSignalOutputModification(true);
744 // Update the I/O statuses
745 bbComputePostProcessStatus();
749 // Test output status...
750 OutputConnectorMapType::iterator o;
751 for ( o = bbGetOutputConnectorMap().begin();
752 o!= bbGetOutputConnectorMap().end(); ++o)
754 if (o->second->GetStatus() != UPTODATE)
756 bbtkWarning("BlackBox::bbRecursiveExecute: "
757 <<"all inputs are Up-to-date but output '"
758 <<o->first<<"' is Out-of-date ???");
762 bbtkBlackBoxDebugMessage("process",3," -> Up-to-date : nothing to do"
766 // Shows the window if the black box has one
767 this->bbShowWindow();
770 bbtkBlackBoxDebugMessage("process",3,
771 "<= BlackBox::bbRecursiveExecute()"
774 bbSetExecuting(false);
775 bbGlobalSetSomeBoxExecuting(wasExecuting);
779 //=========================================================================
785 //=========================================================================
786 IOStatus BlackBox::bbUpdateInputs()
788 bbtkBlackBoxDebugMessage("process",4,
789 "=> BlackBox::bbUpdateInputs()"
792 IOStatus s = UPTODATE;
794 InputConnectorMapType::iterator i;
795 for ( i = bbGetInputConnectorMap().begin();
796 i!= bbGetInputConnectorMap().end(); ++i)
798 // if (i->first=="WinHide") continue;
799 // If input type is Void : no recurse
800 //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo()
803 bbtkBlackBoxDebugMessage("change",2,
805 <<"': status before update = '"
806 <<GetIOStatusString(i->second->GetStatus())
808 i->second->RecursiveExecute();
809 IOStatus t = i->second->GetStatus();
811 bbtkBlackBoxDebugMessage("change",2,
813 <<"': status before process = '"
814 <<GetIOStatusString(i->second->GetStatus())
818 bbtkBlackBoxDebugMessage("process",4,
819 "<= BlackBox::bbUpdateInputs()"
823 //=========================================================================
825 //==================================================================
826 void BlackBox::bbComputePostProcessStatus()
828 bbtkBlackBoxDebugMessage("process",4,
829 "=> BlackBox::bbComputePostProcessStatus()"
832 IOStatus new_output_status = UPTODATE;
833 if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
835 // Update the input statuses
836 InputConnectorMapType::iterator i;
837 for ( i = bbGetInputConnectorMap().begin();
838 i!= bbGetInputConnectorMap().end(); ++i)
840 IOStatus t = i->second->GetStatus();
841 if (t == OUTOFDATE) new_output_status = OUTOFDATE;
842 // A previously MODIFIED status turns to UPTODATE
843 if (t==MODIFIED) i->second->SetStatus(UPTODATE);
844 bbtkBlackBoxDebugMessage("change",2,
845 "Input '"<<i->first<<"' : "
846 << GetIOStatusString(t) << " -> "
847 << GetIOStatusString(i->second->GetStatus())
850 bbtkBlackBoxDebugMessage("change",2,
851 "New output status : "
852 << GetIOStatusString(new_output_status)
854 // Update the output statuses
855 OutputConnectorMapType::iterator o;
856 for ( o = bbGetOutputConnectorMap().begin();
857 o!= bbGetOutputConnectorMap().end(); ++o)
860 //EED if ( ( bbBoxProcessModeIsManual()==false ) ||
861 //EED ( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==true) )
864 o->second->SetStatus(new_output_status);
866 //EED if (( (bbBoxProcessModeIsManual()==true) && (bbLetRecursiveExecuteManualMode==false) ) )
868 //EED o->second->SetStatus(UPTODATE);
870 //EED } // Manual analysis
874 bbtkBlackBoxDebugMessage("process",4,
875 "<= BlackBox::bbComputePostProcessStatus()"
878 //==================================================================
880 //=========================================================================
881 void BlackBox::bbConnectInput( const std::string& name, Connection* c)
883 bbtkBlackBoxDebugMessage("connection",2,
884 "==> BlackBox::bbConnectInput(\""
885 <<name<<"\","<<c->GetFullName()<<")"
888 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
889 if (i==bbGetInputConnectorMap().end())
891 bbtkError("no input called '"<<name<<"'");
893 i->second->SetConnection(c);
894 // The input *MUST* be set OUTOFDATE to update its input on next execution
895 bbSetStatusAndPropagate(i->second,OUTOFDATE);
897 bbtkBlackBoxDebugMessage("connection",2,
898 "<== BlackBox::bbConnectInput(\""
899 <<name<<"\","<<c->GetFullName()<<")"
902 //=========================================================================
905 //=========================================================================
906 void BlackBox::bbConnectOutput( const std::string& name, Connection* c)
908 bbtkBlackBoxDebugMessage("connection",2,
909 "==> BlackBox::bbConnectOutput(\""<<name<<"\","
910 <<c->GetFullName()<<")"
913 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
914 if (i==bbGetOutputConnectorMap().end())
916 bbtkError("no output called '"<<name<<"'");
918 i->second->SetConnection(c);
920 bbtkBlackBoxDebugMessage("connection",2,
921 "<== BlackBox::bbConnectOutput(\""<<name<<"\","
922 <<c->GetFullName()<<")"
925 //=========================================================================
928 //=========================================================================
929 void BlackBox::bbDisconnectInput( const std::string& name, Connection* c)
932 bbtkBlackBoxDebugMessage("connection",2,
933 "==> BlackBox::bbDisconnectInput(\""<<name
934 <<"\","<<c->GetFullName()<<")"
939 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
943 InputConnectorMapType::iterator i = bbGetInputConnectorMap().find(name);
944 if (i==bbGetInputConnectorMap().end())
946 bbtkError("no input called '"<<name<<"'");
948 i->second->UnsetConnection(c);
950 bbtkBlackBoxDebugMessage("connection",2,
951 "<== BlackBox::bbDisconnectInput(\""<<name
952 <<"\","<<c->GetFullName()<<")"
956 //=========================================================================
959 //=========================================================================
960 void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c)
962 bbtkBlackBoxDebugMessage("connection",2,
963 "==> BlackBox::bbDisconnectOutput(\""<<name
964 <<"\","<<c->GetFullName()<<")"
969 bbtkBlackBoxDebugMessage("connection",2,"c==0"<<std::endl);
973 OutputConnectorMapType::iterator i = bbGetOutputConnectorMap().find(name);
974 if (i==bbGetOutputConnectorMap().end())
976 bbtkError("no output called '"<<name<<"'");
978 i->second->UnsetConnection(c);
980 bbtkBlackBoxDebugMessage("connection",2,
981 "<== BlackBox::bbDisconnectOutput(\""<<name
982 <<"\","<<c->GetFullName()<<")"
985 //=========================================================================
1009 //=========================================================================
1010 void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
1012 fprintf(ff,"%s%p",bbGetTypeName().c_str(),this);
1014 //=========================================================================
1017 //=========================================================================
1018 std::string BlackBox::bbGetOutputAsString( const std::string &output )
1021 // Looks for the adaptor
1022 if (bbGetOutputType(output).name() != typeid(std::string).name() )
1025 Package::Pointer p = bbGetDescriptor()->GetPackage();
1026 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1028 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1029 BlackBox::Pointer a;
1033 bbGetOutputType(output),
1034 typeid(std::string),
1036 } catch (bbtk::Exception e)
1041 a->bbSetInput("In",bbGetOutput(output));
1043 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1045 v="? (no adaptor found)";
1050 v="? (no factory found)";
1056 v = bbGetOutput(output).unsafe_get<std::string>() ;
1060 //=========================================================================
1062 //=========================================================================
1063 std::string BlackBox::bbGetInputAsString( const std::string &input )
1066 // Looks for the adaptor
1067 if (bbGetInputType(input) != typeid(std::string))
1070 Package::Pointer p = bbGetDescriptor()->GetPackage();
1071 if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
1073 Factory::Pointer f = p->GetFactorySet().begin()->lock();
1074 BlackBox::Pointer a;
1078 bbGetInputType(input),
1079 typeid(std::string),
1081 }catch (bbtk::Exception e)
1087 a->bbSetInput("In",bbGetInput(input));
1089 v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
1093 v="? (no adaptor found)";
1098 v="? (no factory found)";
1103 v = bbGetInput(input).unsafe_get<std::string>() ;
1107 //=======================================================================
1109 //=======================================================================
1110 // Replaces substrings "<" by "["
1111 void SubsBrackets ( std::string& s )
1113 // std::cout << "BEFORE=["<<s<<"]"<<std::endl;
1114 std::string ss("<");
1115 std::string::size_type pos = 0;
1117 std::string cr("[");
1118 while ( pos != std::string::npos )
1120 // std::cout << "*** find one "<<std::endl;
1121 s.replace(pos,1,cr.c_str(),1);
1122 pos = s.find(ss, pos);
1128 while ( pos != std::string::npos )
1130 // std::cout << "*** find one "<<std::endl;
1131 s.replace(pos,1,cr.c_str(),1);
1132 pos = s.find(ss, pos);
1138 while ( pos != std::string::npos )
1140 // std::cout << "*** find one "<<std::endl;
1141 s.replace(pos,1,cr.c_str(),1);
1142 pos = s.find(ss, pos);
1143 } // std::cout << "AFTER=["<<s<<"]"<<std::endl;
1145 //=======================================================================
1147 //=========================================================================
1148 /// Write Graphviz-dot description in file
1149 void BlackBox::bbWriteDotFileBlackBox(FILE *ff,
1150 BlackBox::Pointer parentblackbox,
1151 int detail, int level,
1152 bool instanceOrtype,
1153 bool relative_link )
1156 InputConnectorMapType::iterator i;
1158 std::string labelStr;
1159 std::string valueStr("");
1162 labelStr = bbGetName() ;
1164 labelStr = labelStr + "\\n[" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
1166 labelStr = bbGetName();
1167 labelStr = labelStr + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] ";
1170 SubsBrackets(labelStr);
1173 labelStr = labelStr + " | {{ ";
1174 std::string tempStrTypeName;
1177 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1181 labelStr=labelStr+" | ";
1184 if (instanceOrtype==true)
1186 valueStr = this->bbGetInputAsString(i->first) + " = ";
1188 const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first);
1189 tempStrTypeName=id->GetTypeName();
1190 SubsBrackets(tempStrTypeName);
1191 std::string Name(i->first);
1193 labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]";
1195 labelStr=labelStr+ " } | {";
1197 OutputConnectorMapType::iterator ii;
1198 for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii )
1202 labelStr=labelStr+" | ";
1205 if (instanceOrtype==true)
1207 valueStr = this->bbGetOutputAsString(ii->first) + " = ";
1209 const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first);
1210 tempStrTypeName=id->GetTypeName();
1211 SubsBrackets(tempStrTypeName);
1212 std::string Name(ii->first);
1214 labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]";
1216 labelStr = labelStr+ " } }" ;
1220 bbWriteDotInputOutputName(ff,true,detail,level);
1221 std::string tmp ( bbGetTypeName() );
1225 url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp;
1227 url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp;
1229 fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" );
1230 // std::cout << labelStr << std::endl;
1233 if (GetThisPointer<BlackBox>()!=parentblackbox){
1234 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1238 Connection* con = i->second->GetConnection();
1240 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1241 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1243 a->bbWriteDotInputOutputName(ff,false,detail,level);
1246 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1249 b->bbWriteDotInputOutputName(ff,true,detail,level);
1252 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1254 fprintf(ff,"%s\n",";");
1258 } // if parentblackbox
1260 //=========================================================================
1265 //=========================================================================
1266 void BlackBox::bbPrintHelp(BlackBox::Pointer parentblackbox,
1267 int detail, int level
1268 /*,Factory *factory*/ )
1271 if (this->bbGetDescriptor()->GetPackage())
1273 bbtkBlackBoxMessage("help",1,"Black Box '"<<bbGetName()<<"' <"<<
1274 this->bbGetDescriptor()->GetPackage()->GetName()
1275 <<"::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1279 bbtkBlackBoxMessage("help",1,"Black Box <::"<<this->bbGetDescriptor()->GetTypeName()<<">"<<std::endl);
1284 bbtkBlackBoxMessage("help",1,"Up-to-date ["<<mMaxInputChangeTime<<","
1285 <<mMinOutputChangeTime<<"]"<<std::endl);
1289 bbtkBlackBoxMessage("help",1,"Out-of-date ["<<mMaxInputChangeTime<<","
1290 <<mMinOutputChangeTime<<"]"<<std::endl);
1293 // bbtkBlackBoxMessage("help",1," "<<GetDescription()<<std::endl);
1294 // bbtkBlackBoxMessage("help",1," By : "<<GetAuthor()<<std::endl);
1296 std::vector<std::string> iname;
1297 std::vector<std::string> ivalue;
1298 std::vector<std::string> iconn;
1299 std::vector<std::string> istatus;
1301 InputConnectorMapType::iterator i;
1302 unsigned int namelmax = 0;
1303 unsigned int valuelmax = 0;
1304 // unsigned int connlmax = 0;
1305 for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i )
1307 iname.push_back(i->first);
1308 if (iname.back().size()>namelmax) namelmax = iname.back().size();
1309 ivalue.push_back(bbGetInputAsString(i->first));
1310 if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size();
1312 Connection* con = i->second->GetConnection();
1314 s = con->GetOriginalBlackBoxFrom()->bbGetName();
1316 s += con->GetOriginalBlackBoxFromOutput();
1319 istatus.push_back(GetIOStatusString(i->second->GetStatus()));
1321 OutputConnectorMapType::iterator o;
1322 std::vector<std::string> oname;
1323 std::vector<std::string> ovalue;
1324 std::vector<std::vector<std::string> > oconn;
1325 std::vector<std::string> ostatus;
1326 for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o )
1328 oname.push_back(o->first);
1329 if (oname.back().size()>namelmax)
1330 namelmax = oname.back().size();
1331 ovalue.push_back(bbGetOutputAsString(o->first));
1332 if (ovalue.back().size()>valuelmax)
1333 valuelmax = ovalue.back().size();
1334 std::vector<std::string> ss;
1335 const std::vector<Connection*>& con
1336 = o->second->GetConnectionVector();
1337 std::vector<Connection*>::const_iterator c;
1338 for (c=con.begin();c!=con.end();++c)
1341 s = (*c)->GetOriginalBlackBoxTo()->bbGetName();
1343 s += (*c)->GetOriginalBlackBoxToInput();
1346 oconn.push_back(ss);
1347 ostatus.push_back(GetIOStatusString(o->second->GetStatus()));
1351 bbtkBlackBoxMessage("help",1," * Inputs : "<<std::endl);
1353 bbtkBlackBoxMessage("help",1," * No inputs"<<std::endl);
1355 std::vector<std::string>::iterator i1,i2,i3,i4;
1356 for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(),i4=istatus.begin();
1357 i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(),i4!=istatus.end();
1358 ++i1,++i2,++i3,++i4)
1360 std::string name(*i1);
1362 name.append(1+namelmax-name.size(),' ');
1363 std::string value(*i2);
1365 value.append(1+valuelmax-value.size(),' ');
1367 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value<<" <-- '" <<*i3<<"'");
1369 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1370 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1374 bbtkBlackBoxMessage("help",1," * Outputs : "<<std::endl);
1376 bbtkBlackBoxMessage("help",1," * No outputs"<<std::endl);
1378 std::vector<std::vector<std::string> >::iterator i5;
1380 for (i1=oname.begin(),i2=ovalue.begin(),i5=oconn.begin(),i4=ostatus.begin();
1381 i1!=oname.end(),i2!=ovalue.end(),i5!=oconn.end(),i4!=ostatus.end();
1382 ++i1,++i2,++i4,++i5)
1384 std::string name(*i1);
1386 name.append(1+namelmax-name.size(),' ');
1387 std::string value(*i2);
1389 value.append(1+valuelmax-value.size(),' ');
1391 bbtkBlackBoxMessage("help",1," '"<<name<<" = '"<<value);
1394 std::string pref = " '"+name+" = '"+value;
1395 for (i3=i5->begin();i3!=i5->end();++i3)
1397 bbtkBlackBoxMessage("help",1,pref<<" --> '"<<*i3<<"'");
1398 pref.replace(0,pref.size(),pref.size(),' ');
1401 bbtkBlackBoxMessage("help",1," ["<<*i4<<"]"<<std::endl);
1405 //=========================================================================
1424 static bool bbmgGlobalProcessingExecutionList = false;
1426 //=========================================================================
1427 void BlackBox::bbGlobalProcessExecutionList()
1429 bbtkDebugMessage("process",3,
1430 "=> BlackBox::bbGlobalProcessExecutionList()"
1432 if (bbmgGlobalProcessingExecutionList)
1434 bbtkDebugMessage("process",3,"BlackBox::bbGlobalProcessExecutionList() reentered !");
1437 bbmgGlobalProcessingExecutionList = true;
1439 std::set<BlackBox::WeakPointer>::iterator i;
1440 while (bbmgExecutionList.size()>0)
1442 i = bbmgExecutionList.begin();
1443 BlackBox::WeakPointer p = *i;
1444 bbmgExecutionList.erase(i);
1447 bbtkDebugMessage("process",4,
1449 p.lock()->bbGetName()<<"'"<<std::endl);
1450 p.lock()->bbExecute(true);
1454 bbtkGlobalError("Strange error in BlackBox::bbGlobalProcessExecutionList() : Weak bb pointer in bbmgExecutionList is no more valid...");
1458 bbmgExecutionList.clear();
1459 bbtkDebugMessage("process",3,
1460 "<= BlackBox::bbGlobalProcessExecutionList()"
1463 bbmgGlobalProcessingExecutionList = false;
1466 //=========================================================================
1468 bool BlackBox::bbGlobalGetSomeBoxExecuting()
1470 return bbmgSomeBoxExecuting;
1473 void BlackBox::bbGlobalSetSomeBoxExecuting(bool b)
1475 bbmgSomeBoxExecuting = b;
1478 void BlackBox::bbGlobalSetFreezeExecution(bool b)
1480 bbmgFreezeExecution = b;
1483 bool BlackBox::bbGlobalGetFreezeExecution()
1485 return bbmgFreezeExecution;
1488 void BlackBox::bbGlobalAddToExecutionList( BlackBox::Pointer b )
1490 bbtkDebugMessage("process",3,"* bbGlobalAddToExecutionList("<<b->bbGetName()<<")"<<std::endl);
1491 if (bbmgGlobalProcessingExecutionList)
1493 bbtkDebugMessage("process",3,"bbGlobalAddToExecutionList called inside bbGlobalProcessExecutionList !");
1495 bbmgExecutionList.insert(b);
1499 //=========================================================================
1501 //=========================================================================
1502 void BlackBox::Check(bool recursive)
1504 bbtkBlackBoxMessage("debug",1,"*** Checking"
1505 <<" ... OK"<<std::endl);
1507 //=========================================================================
1512 } // EO namespace bbtk