1 /*=========================================================================
3 Module: $RCSfile: bbtkComplexBlackBox.cxx,v $
5 Date: $Date: 2008/12/08 12:54:09 $
6 Version: $Revision: 1.22 $
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 * ------------------------------------------------------------------------ */
34 * \brief class bbtk::ComplexBlackBox : user defined complex black boxes
36 #include "bbtkComplexBlackBox.h"
38 #include "bbtkBlackBoxDescriptor.h"
39 #include "bbtkFactory.h"
40 #include "bbtkConfigurationFile.h"
45 //==========================================================================
46 /// Creates a new complex black box
47 ComplexBlackBox::Pointer ComplexBlackBox::New(const std::string& name,
48 ComplexBlackBoxDescriptor::Pointer desc)
50 bbtkDebugMessage("object",1,"##> ComplexBlackBox::New('"<<name<<"','"<<
51 desc->GetTypeName()<<"')" <<bbtkendl);
52 ComplexBlackBox::Pointer p =
53 MakeBlackBoxPointer(new ComplexBlackBox(name,desc));
54 bbtkDebugMessage("object",2,"<## ComplexBlackBox::New('"<<name<<"','"<<
55 desc->GetTypeName()<<"')" <<bbtkendl);
58 //==========================================================================
60 //=======================================================================
61 /// Usefull constructor
62 ComplexBlackBox::ComplexBlackBox(const std::string &name,
63 ComplexBlackBoxDescriptor::Pointer desc)
66 mLockedDescriptor(desc),
69 bbtkDebugMessage("object",3,
70 "##> ComplexBlackBox::ComplexBlackBox(\""
71 <<name<<"\")"<<std::endl);
72 bbAllocateConnectors();
73 bbtkDebugMessage("object",3,
74 "<## ComplexBlackBox::ComplexBlackBox(\""
75 <<name<<"\")"<<std::endl);
77 //=======================================================================
79 //=======================================================================
80 /// Constructor from an existing box (copy) with a new name
81 ComplexBlackBox::ComplexBlackBox(ComplexBlackBox& from,
82 const std::string &name)
83 : BlackBox(from,name),
84 // The locked descriptor is copied from the unlocked one
85 // to make the box a non-prototype !!
86 mLockedDescriptor(from.mDescriptor),
87 mDescriptor(from.mDescriptor),
88 mExecutionList(from.mExecutionList)
90 bbtkDebugMessage("object",3,
91 "##> ComplexBlackBox::ComplexBlackBox(\""
92 <<from.bbGetName()<<"\",\""
93 <<name<<"\")"<<std::endl);
94 bbtkDebugMessage("object",4," * Cloning Black Boxes"<<std::endl);
96 // We have to make the shared_ptr on this because it is used
97 // in bbUnsafeAddBlackBox !
98 MakeBlackBoxPointer(this,true);
100 BlackBoxMapType::const_iterator i;
101 for ( i = from.mBlackBoxMap.begin(); i != from.mBlackBoxMap.end(); ++i )
103 bbtkDebugMessageInc("object",5," * Cloning \""<<i->first<<"\""<<std::endl);
104 BlackBox::Pointer B = i->second->bbClone(i->second->bbGetName());
105 bbUnsafeAddBlackBox(B);
108 bbtkDebugMessage("object",4," * Cloning Connections"<<std::endl);
109 ConnectionListType::const_iterator j;
110 for ( j = from.mConnectionList.begin(); j != from.mConnectionList.end(); ++j )
112 bbtkDebugMessage("object",5," * Cloning \""<<
113 (*j)->GetFullName()<<"\""<<std::endl);
115 BlackBox::Pointer bbfrom = bbGetBlackBox( (*j)->GetOriginalBlackBoxFrom()->bbGetName() );
116 BlackBox::Pointer bbto = bbGetBlackBox( (*j)->GetOriginalBlackBoxTo()->bbGetName() );
118 Connection::Pointer c = mDescriptor.lock()->GetFactory()->
119 NewConnection( bbfrom,
120 (*j)->GetOriginalBlackBoxFromOutput(),
122 (*j)->GetOriginalBlackBoxToInput() );
129 bbAllocateConnectors();
130 bbtkDebugMessage("object",3,
131 "<## ComplexBlackBox::ComplexBlackBox(\""
132 <<from.bbGetName()<<"\",\""
133 <<name<<"\")"<<std::endl);
135 //=======================================================================
137 //=======================================================================
139 ComplexBlackBox::~ComplexBlackBox()
141 bbtkDebugMessage("object",3,
142 "==> ComplexBlackBox::~ComplexBlackBox() ["
143 <<bbGetName()<<"]"<<std::endl);
145 bbtkDebugMessage("object",4,
146 " -> Releasing connections"<<std::endl);
147 mConnectionList.clear();
148 bbtkDebugMessage("object",4,
149 " -> Releasing boxes"<<std::endl);
150 mBlackBoxMap.clear();
153 this->bbDesallocateConnectors();
155 bbtkDebugMessage("object",3,
156 "<== ComplexBlackBox::~ComplexBlackBox() ["
157 <<bbGetName()<<"]"<<std::endl);
159 //=======================================================================
162 //=========================================================================
163 /// Allocates the i/o connectors of the black box
164 void ComplexBlackBox::bbAllocateConnectors()
166 bbtkDebugMessageInc("Kernel",8,
167 "ComplexBlackBox::bbAllocateConnectors() ["
168 <<bbGetFullName()<<"]"
172 const BlackBoxDescriptor::InputDescriptorMapType& imap
173 = bbGetDescriptor()->GetInputDescriptorMap();
174 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
175 for ( i = imap.begin(); i != imap.end(); ++i )
177 bbtkDebugMessage("Kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
178 // Redirect the connector to the internal box connector
179 // Cast the BBInputDescriptor into a ComplexBBInputDescriptor
180 ComplexBlackBoxInputDescriptor* d =
181 (ComplexBlackBoxInputDescriptor*)i->second;
182 // Get the internal box connector
183 BlackBoxInputConnector* c =
184 bbUnsafeGetBlackBox ( d->GetTarget() )
185 ->bbGetInputConnectorMap()[ d->GetInput() ];
187 bbGetInputConnectorMap()[i->second->GetName()] = c;
191 const BlackBoxDescriptor::OutputDescriptorMapType& omap
192 = bbGetDescriptor()->GetOutputDescriptorMap();
193 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
194 for ( o = omap.begin(); o != omap.end(); ++o )
196 bbtkDebugMessage("Kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
197 // Redirect the connector to the internal box connector
198 // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
199 ComplexBlackBoxOutputDescriptor* d =
200 (ComplexBlackBoxOutputDescriptor*)o->second;
201 // Get the internal box connector
202 BlackBoxOutputConnector* c =
203 bbUnsafeGetBlackBox ( d->GetTarget() )
204 ->bbGetOutputConnectorMap()[ d->GetOutput() ];
206 bbGetOutputConnectorMap()[o->second->GetName()] = c;
209 bbtkDebugDecTab("Kernel",8);
211 //=========================================================================
214 //=========================================================================
215 /// Desallocates the i/o connectors of the black box
216 void ComplexBlackBox::bbDesallocateConnectors()
218 bbtkDebugMessageInc("Kernel",8,
219 "ComplexBlackBox::DesallocateConnectors()"
222 // The connectors have not been allocated by the complex box
223 // but by the internal boxes. Hence **DO NOT** desallocate !
224 // just clear the maps to avoid that
225 // BlackBox::bbDesallocateConnectors delete the connectors
226 bbGetInputConnectorMap().clear();
227 bbGetOutputConnectorMap().clear();
229 bbtkDebugDecTab("Kernel",8);
232 //=========================================================================
234 //=======================================================================
235 BlackBox::Pointer ComplexBlackBox::bbClone(const std::string& name)
237 bbtkDebugMessageInc("Kernel",9,
238 "ComplexBlackBox::bbClone(\""<<name<<"\") ["
239 <<bbGetFullName()<<"]"<<std::endl);
241 ComplexBlackBox* CBB = new ComplexBlackBox(*this,name);
242 return MakeBlackBoxPointer(CBB);
244 //=======================================================================
246 //=======================================================================
247 /// Main processing method of the box.
248 /// Executes the box so that its outputs are up-to-date on exit
249 void ComplexBlackBox::bbExecute(bool force)
251 bbtkDebugMessageInc("process",2,
252 "=> ComplexBlackBox::bbExecute() ["
253 <<bbGetFullName()<<"]"<<std::endl);
258 if (mExecutionList.size() != 0)
261 std::vector<std::string>::const_iterator i;
262 for (i=mExecutionList.begin();
263 i!=mExecutionList.end();
266 bbtkDebugMessage("process",3," -> Executing '"<<*i<<"'"<<std::endl);
267 mBlackBoxMap[*i]->bbExecute(force);
272 std::map<std::string, BlackBox::Pointer>::iterator i;
273 for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i)
275 i->second->bbExecute(force);
280 //==================================================================
283 //==================================================================
284 void ComplexBlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
286 bbtkDebugMessage("modified",1,
287 "==> ComplexBlackBox::bbSetModifiedStatus("
288 <<c<<") ["<<bbGetFullName()<<"]"<<std::endl);
290 c->GetBlackBox()->bbSetModifiedStatus(c);
293 //==================================================================
296 //==================================================================
297 void ComplexBlackBox::bbAddToExecutionList( const std::string& name )
299 bbtkDebugMessageInc("Kernel",9,
300 "ComplexBlackBox::bbAddToExecutionList(\""
302 <<bbGetFullName()<<"]"<<std::endl);
304 mExecutionList.push_back( name );
306 bbtkDebugDecTab("Kernel",9);
309 //==================================================================
311 //==================================================================
312 void ComplexBlackBox::bbBackwardUpdate(Connection::Pointer caller)
314 bbtkDebugMessageInc("process",3,
315 "==> ComplexBlackBox::bbBackwardUpdate("
316 <<(caller?caller->GetFullName():"0")<<") ["
317 <<bbGetFullName()<<"]"<<std::endl);
318 // bbtkInternalError("ComplexBlackBox::bbBackwardUpdate should never be called !");
322 bbtkInternalError("ComplexBlackBox::bbBackwardUpdate called with caller=0");
326 std::cout << "CBB BUP : "<<caller->GetBlackBoxFrom()->bbGetFullName()
327 <<"."<<caller->GetBlackBoxFromOutput()<<"----"
328 <<caller->GetOriginalBlackBoxFrom()->bbGetFullName()
329 <<"."<<caller->GetOriginalBlackBoxFromOutput()<<std::endl;
334 // IOStatus s = UPTODATE;
335 const BlackBoxDescriptor::OutputDescriptorMapType& omap
336 = bbGetDescriptor()->GetOutputDescriptorMap();
337 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator i
338 = omap.find(caller->GetBlackBoxFromOutput());
341 // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
342 ComplexBlackBoxOutputDescriptor* d =
343 (ComplexBlackBoxOutputDescriptor*)i->second;
344 // Get the internal box
345 BlackBox::Pointer b = bbUnsafeGetBlackBox ( d->GetTarget() );
346 // Calls BackwardUpdate on it
347 bbtkDebugMessageInc("process",4,"Internal box connected to output : "<<d->GetTarget()<<std::endl);
348 // Because internal box can also be a complex box we have to
349 // temporarily change the connection BlackBoxFromOutput to the
352 // std::string oldout = caller->GetBlackBoxFromOutput();
353 // std::cout << "oldout = "<<oldout<<std::endl;
354 // std::cout << "tmpout = "<<d->GetOutput()<<std::endl;
355 // caller->SetBlackBoxFromOutput(d->GetOutput());
357 //Connection newcaller(*caller);
358 //newcaller.SetBlackBoxFromOutput(d->GetOutput());
359 //IOStatus s1 = b->bbBackwardUpdate(&newcaller);
361 b->bbBackwardUpdate(caller);
363 // restore old output
364 // caller->SetBlackBoxFromOutput(oldout);
366 // ??? STATUS OF CBBs ???
367 // ??? Here it is only the final status of the boxes connected to the output
368 // if (s1==MODIFIED) s=MODIFIED;
372 bbtkError("Connection '"<<caller->GetFullName()<<"' does not point to a valid output of the complex box !");
378 //==================================================================
381 //==================================================================
382 Data ComplexBlackBox::bbGetOutput( const std::string &name )
384 bbtkDebugMessageInc("Data",7,
385 "ComplexBlackBox::bbGetOutput(\""<<name<<"\") ["
386 <<bbGetFullName()<<"]"<<std::endl);
388 ComplexBlackBoxOutputDescriptor* d =
389 (ComplexBlackBoxOutputDescriptor*)
390 bbGetDescriptor()->GetOutputDescriptor(name);
392 Data p = bbGetBlackBox(d->GetTarget())->bbGetOutput(d->GetOutput());
395 bbtkDebugDecTab("Data",7);
398 //==================================================================
400 //==================================================================
401 /// Gets the input Data of a given name
402 Data ComplexBlackBox::bbGetInput( const std::string &name )
404 bbtkDebugMessageInc("Data",7,
405 "ComplexBlackBox::bbGetInput(\""<<name<<"\") ["
406 <<bbGetFullName()<<"]"<<std::endl);
408 ComplexBlackBoxInputDescriptor* d =
409 (ComplexBlackBoxInputDescriptor*)
410 bbGetDescriptor()->GetInputDescriptor(name);
412 Data p = bbGetBlackBox(d->GetTarget())->bbGetInput(d->GetInput());
414 bbtkDebugDecTab("Data",7);
417 //==================================================================
419 //==================================================================
420 /// Sets the data of the output called <name>
421 void ComplexBlackBox::bbSetOutput( const std::string &name, Data data)
423 bbtkDebugMessageInc("Data",7,
424 "ComplexBlackBox::bbSetOutput(\""<<name<<"\",data) ["
425 <<bbGetFullName()<<"]"<<std::endl);
427 ComplexBlackBoxOutputDescriptor* d =
428 (ComplexBlackBoxOutputDescriptor*)
429 bbGetDescriptor()->GetOutputDescriptor(name);
431 bbGetBlackBox(d->GetTarget())->bbSetOutput(d->GetOutput(),data);
433 bbtkDebugDecTab("Data",7);
435 //==================================================================
437 //==================================================================
438 /// Sets the data of the input called <name>
439 void ComplexBlackBox::bbSetInput( const std::string &name, Data data,
442 bbtkDebugMessageInc("Data",7,
443 "ComplexBlackBox::bbSetInput(\""<<name<<"\",data) ["
444 <<bbGetFullName()<<"]"<<std::endl);
446 ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
447 bbGetDescriptor()->GetInputDescriptor(name);
449 bbGetBlackBox(d->GetTarget())->bbSetInput(d->GetInput(),data,setModified);
451 bbtkDebugDecTab("Data",7);
453 //==================================================================
456 //==================================================================
457 /// Sets the data of the input called <name>
458 void ComplexBlackBox::bbBruteForceSetInputPointer( const std::string &name,
462 bbtkDebugMessageInc("Data",7,
463 "ComplexBlackBox::bbBruteForceSetInputPointer('"
464 <<name<<"',"<<data<<") ["
465 <<bbGetFullName()<<"]"<<std::endl);
467 ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
468 bbGetDescriptor()->GetInputDescriptor(name);
470 bbGetBlackBox(d->GetTarget())->bbBruteForceSetInputPointer(d->GetInput(),
474 bbtkDebugDecTab("Data",7);
476 //==================================================================
478 //=========================================================================
479 /// Connects the input <name> to the connection c
480 void ComplexBlackBox::bbConnectInput( const std::string& name, Connection* c)
482 bbtkDebugMessage("connection",2,
483 "==> ComplexBlackBox::bbConnectInput(\""
484 <<name<<"\","<<c->GetFullName()<<") ["
485 <<bbGetFullName()<<"]"
488 ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
489 bbGetDescriptor()->GetInputDescriptor(name);
492 BlackBox::Pointer t = bbGetBlackBox(d->GetTarget());
494 bbtkDebugMessage("connection",2," - Target = "<<d->GetTarget()<<" = "<<t->bbGetFullName()<<std::endl);
497 c->SetBlackBoxToInput(d->GetInput());
499 bbtkDebugMessage("connection",2," - New conn = "<<c->GetFullName()<<std::endl);
500 t->bbConnectInput(d->GetInput(),c);
502 bbtkDebugMessage("connection",2,
503 "<== ComplexBlackBox::bbConnectInput(\""
504 <<name<<"\","<<c->GetFullName()<<") ["
505 <<bbGetFullName()<<"]"
508 //=========================================================================
511 //=========================================================================
512 /// Connects the output <name> to the connection c
513 void ComplexBlackBox::bbConnectOutput( const std::string& name, Connection* c)
515 bbtkDebugMessage("connection",2,
516 "==> ComplexBlackBox::bbConnectOutput(\""
517 <<name<<"\","<<c->GetFullName()<<") ["
518 <<bbGetFullName()<<"]"<<std::endl);
520 ComplexBlackBoxOutputDescriptor* d = (ComplexBlackBoxOutputDescriptor*)
521 bbGetDescriptor()->GetOutputDescriptor(name);
523 BlackBox::Pointer t = bbGetBlackBox(d->GetTarget());
525 bbtkDebugMessage("connection",2," - Target = "<<d->GetTarget()<<" = "<<t->bbGetFullName()<<std::endl);
527 c->SetBlackBoxFrom(t);
528 c->SetBlackBoxFromOutput(d->GetOutput());
530 bbtkDebugMessage("connection",2," - New conn = "<<c->GetFullName()<<std::endl);
532 t->bbConnectOutput(d->GetOutput(),c);
534 bbtkDebugMessage("connection",2,
535 "<== ComplexBlackBox::bbConnectOutput(\""
536 <<name<<"\","<<c->GetFullName()<<") ["
537 <<bbGetFullName()<<"]"<<std::endl);
539 //=========================================================================
542 //==================================================================
543 /// Adds the black box to the complex box
544 void ComplexBlackBox::bbAddBlackBox( BlackBox::Pointer b)
546 bbtkDebugMessageInc("Kernel",7,
547 "ComplexBlackBox::AddBlackBox(\""<<b->bbGetName()
549 <<bbGetFullName()<<"]"<<std::endl);
551 if ( bbUnsafeGetBlackBox(b->bbGetName()) )
553 bbtkError("a black box called \""<<b->bbGetName()
554 <<"\" already exists");
556 b->bbSetParent(GetThisPointer<ComplexBlackBox>());
557 mBlackBoxMap[b->bbGetName()] = b;
559 bbtkDebugDecTab("Kernel",7);
561 //==================================================================
563 //==================================================================
564 /// Adds the black box to the complex box (unsafe)
565 void ComplexBlackBox::bbUnsafeAddBlackBox( BlackBox::Pointer b)
567 bbtkDebugMessageInc("Kernel",7,
568 "ComplexBlackBox::UnsafeAddBlackBox(\""<<b->bbGetName()
570 <<bbGetFullName()<<"]"<<std::endl);
572 b->bbSetParent(GetThisPointer<ComplexBlackBox>());
573 mBlackBoxMap[b->bbGetName()] = b;
575 bbtkDebugDecTab("Kernel",7);
577 //==================================================================
579 //==================================================================
580 /// Removes the black box from the complex box
581 void ComplexBlackBox::bbRemoveBlackBox( const std::string& name,
582 bool remove_connections )
584 bbtkDebugMessageInc("Kernel",7,
585 "ComplexBlackBox::RemoveBlackBox(\""<<name<<"\") ["
586 <<bbGetFullName()<<"]"<<std::endl);
588 BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
589 if ( i == mBlackBoxMap.end() )
591 bbtkError("the black box \""<<name<<"\" does not exist");
593 BlackBox::WeakPointer p = i->second;
595 if (remove_connections)
597 ConnectionListType::const_iterator j;
598 for ( j = mConnectionList.begin();
599 j != mConnectionList.end(); ++j )
604 if (p.use_count()!=1)
606 bbtkError("the black box \""<<name<<"\" is still connected");
609 mBlackBoxMap.erase(i);
612 // Unload orphan dl packages
613 Package::UnLoadReleasedDynamicallyLoadedPackages();
615 bbtkDebugDecTab("Kernel",7);
617 //==================================================================
619 //==================================================================
620 /// Adds the connection to the complex box
621 void ComplexBlackBox::bbAddConnection( Connection::Pointer c)
623 bbtkDebugMessageInc("Kernel",7,
624 "ComplexBlackBox::AddConnection(\""<<"..."<<"\") ["
625 <<bbGetFullName()<<"]"<<std::endl);
627 mConnectionList.push_back(c);
629 bbtkDebugDecTab("Kernel",7);
631 //==================================================================
632 // void RemoveConnection( );
634 //==================================================================
635 /// Returns the black box with name <name>
636 BlackBox::Pointer ComplexBlackBox::bbGetBlackBox( const std::string& name )
638 bbtkDebugMessageInc("Kernel",9,
639 "ComplexBlackBox::GetBlackBox(\""<<name<<"\") ["
640 <<bbGetFullName()<<"]"<<std::endl);
642 BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
643 if ( i == mBlackBoxMap.end() )
645 bbtkError("the black box \""<<name<<"\" does not exist");
648 bbtkDebugDecTab("Kernel",9);
651 //==================================================================
653 //==================================================================
654 /// Returns the black box with name <name> : does not throw an exception
655 /// if it does not exist but return a null pointer
656 BlackBox::Pointer ComplexBlackBox::bbUnsafeGetBlackBox( const std::string& name )
658 bbtkDebugMessageInc("Kernel",9,
659 "ComplexBlackBox::UnsafeGetBlackBox(\""<<name<<"\") ["
660 <<bbGetFullName()<<"]"
663 BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
664 if ( i == mBlackBoxMap.end() )
666 bbtkDebugDecTab("Kernel",9);
667 return BlackBox::Pointer();
670 bbtkDebugDecTab("Kernel",9);
674 //==================================================================
676 //==================================================================
677 void ComplexBlackBox::bbPrintBlackBoxes()
679 bbtkDebugMessageInc("Kernel",9,
680 "ComplexBlackBox::PrintBlackBoxes() ["
681 <<bbGetFullName()<<"]"
684 BlackBoxMapType::iterator i;
685 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
687 bbtkMessage("Help",1,i->second->bbGetFullName()<<std::endl);
690 bbtkDebugDecTab("Kernel",9);
692 //==================================================================
696 //=========================================================================
698 void ComplexBlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
702 fprintf(ff,"%s_IN_%p",bbGetTypeName().c_str(),this);
704 fprintf(ff,"%s_OUT_%p",bbGetTypeName().c_str(),this);
707 //=========================================================================
710 //=========================================================================
711 BlackBox::Pointer ComplexBlackBox::bbFindBlackBox(const std::string &blackboxname)
713 BlackBox::Pointer blackbox;
714 std::string subname="";
715 std::string restname="";
716 std::string delimiters(">");
717 // Skip delimiters at beginning.
718 std::string::size_type lastPos = blackboxname.find_first_not_of(delimiters, 0);
719 // Find first "non-delimiter".
720 std::string::size_type pos = blackboxname.find_first_of(delimiters, lastPos);
722 // Found a token, add it to the vector.
723 subname = blackboxname.substr(lastPos, pos - lastPos);
724 restname = blackboxname.substr(lastPos+pos - lastPos+1, 999);
726 if (restname==subname)
731 BlackBoxMapType::iterator i = mBlackBoxMap.find(subname);
732 if ( i != mBlackBoxMap.end() )
734 blackbox = i->second;
737 blackbox = blackbox->bbFindBlackBox(restname);
742 //=========================================================================
744 //=========================================================================
745 void ComplexBlackBox::bbInsertHTMLGraph( std::ofstream& s,
749 const std::string& output_dir,
753 std::string directory(output_dir);
755 if (output_dir.length() == 0)
757 // Don't pollute the file store with "temp_dir" directories ...
758 std::string default_temp_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
759 directory = default_temp_dir + "/" + "temp_dir";
762 std::string simplefilename (this->bbGetTypeName()+"_"+this->bbGetName());
763 std::string simplefilename_png (simplefilename+".png");
764 std::string filename (directory+"/"+simplefilename);
765 std::string filename_png (filename+".png");
766 std::string filename_cmap (filename+".cmap");
767 std::string filename_dot (filename+".dot");
769 std::string filename_png2 ("\"" + filename_png + "\"");
770 std::string filename_cmap2 ("\"" + filename_cmap + "\"");
771 std::string filename_dot2 ("\"" + filename_dot + "\"");
774 std::string command1 ("dot -T png -o "
775 + filename_png2 + " " + filename_dot2);
776 std::string command1a("dot -T cmap -o "
777 + filename_cmap2 + " " + filename_dot2);
779 // 1. Generating .dot file
781 ff = fopen(filename_dot.c_str(),"w");
782 fprintf(ff,"digraph bbtk_graph{\n");
783 fprintf(ff,"rankdir=LR%s\n",";");
784 fprintf(ff,"node [shape=record]%s\n",";");
786 this->bbWriteDotFileBlackBox(ff,
787 GetThisPointer<ComplexBlackBox>(),
795 // 2. Executing .dot file -> png
796 system( command1.c_str() );
797 // 3. Executing .dot file -> cmap
798 system( command1a.c_str() );
800 // 4. HTML code insertion
802 (s) << "<center><img src=\"" << simplefilename_png
803 << "\" border=\"0\" usemap=\"#map_"<< simplefilename
804 <<"\" alt=\"\"></center>\n";
807 (s) << "<map name=\"map_"<< simplefilename <<"\">\n";
810 ff2=fopen(filename_cmap.c_str(),"r");
823 //=========================================================================
826 //=========================================================================
827 /// Write Graphviz-dot description in file
828 void ComplexBlackBox::bbWriteDotFileBlackBox(FILE *ff,
829 BlackBox::Pointer parentblackbox,
830 int detail, int level,
835 std::string valueStr("");
836 Package::Pointer package = this->bbGetDescriptor()->GetPackage();
841 tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL();
843 tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocURL();
850 std::string tmp2=bbGetTypeName();
851 std::string url(tmp1 + "#" + tmp2 );
852 fprintf( ff , "subgraph cluster_%s_%p {\n",bbGetName().c_str(),this);
854 if (!( (bbGetTypeName()=="workspace") && (bbGetName()=="workspacePrototype")) )
856 fprintf( ff , " URL = \"%s\" %s",url.c_str(),";");
859 std::string boxname="["+bbGetTypeName()+"]";
860 if (GetThisPointer<ComplexBlackBox>()!=parentblackbox)
868 boxname = bbGetName();
869 boxname = boxname + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
873 fprintf( ff , " label = \"%s\"%s\n", boxname.c_str() ,";");
877 // fprintf( ff , " style=filled%s\n",";");
878 // fprintf( ff , " color=grey%s\n",";");
879 fprintf( ff , " node [style=filled]%s\n",";");
880 fprintf( ff , " fillcolor=grey%s\n",";");
881 fprintf( ff , " edge [color=blue]%s\n",";");
885 std::string labelStr1;
886 std::string labelStr2;
887 labelStr1 = boxname + "\\n(output)" ;
888 labelStr2 = " | {{ ";
891 OutputConnectorMapType::iterator i;
893 const BlackBoxDescriptor::OutputDescriptorMapType& omap = this->bbGetDescriptor()->GetOutputDescriptorMap();
894 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
895 for ( o = omap.begin(); o != omap.end(); ++o )
899 labelStr2=labelStr2+" | ";
902 if (instanceOrtype==true)
904 valueStr = this->bbGetOutputAsString(o->second->GetName()/*
907 labelStr2=labelStr2+"<"+o->second->GetName().c_str()+"> " + valueStr + o->second->GetName().c_str();
910 labelStr2 = labelStr2+ " } }";
916 labelStr1 = labelStr1 + labelStr2;
921 bbWriteDotInputOutputName(ff,false,detail,level);
922 fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
927 labelStr1 = boxname + "\\n(input)" ;
928 labelStr2 = " | {{ ";
930 InputConnectorMapType::iterator ii;
932 const BlackBoxDescriptor::InputDescriptorMapType& imap = this->bbGetDescriptor()->GetInputDescriptorMap();
933 BlackBoxDescriptor::InputDescriptorMapType::const_iterator iii;
934 for ( iii = imap.begin(); iii != imap.end(); ++iii )
938 labelStr2=labelStr2+" | ";
941 if (instanceOrtype==true)
943 valueStr = this->bbGetInputAsString(iii->second->GetName()/*,factory*/) + " = ";
945 labelStr2=labelStr2+"<"+iii->second->GetName().c_str()+"> " + valueStr + iii->second->GetName().c_str();
949 labelStr2 = labelStr2+ " } }";
952 labelStr1 = labelStr1 + labelStr2;
956 bbWriteDotInputOutputName(ff,true,detail,level);
957 fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
962 BlackBoxMapType::iterator j;
963 for ( j = mBlackBoxMap.begin(); j != mBlackBoxMap.end(); ++j )
967 j->second->bbWriteDotFileBlackBox(ff,
976 fprintf( ff , "}\n\n");
978 fprintf( ff , " edge[color=blue]%s\n",";");
982 // Relation Input with the inside BlackBox of the this ComplexBlackbox
983 ComplexBlackBoxDescriptor::InputDescriptorMapType::iterator xx;
984 ComplexBlackBoxDescriptor::InputDescriptorMapType idmt=bbGetDescriptor()->GetInputDescriptorMap();
985 for ( xx = idmt.begin(); xx != idmt.end(); ++xx )
987 ComplexBlackBoxInputDescriptor *cbbid = (ComplexBlackBoxInputDescriptor*)xx->second;
990 bbWriteDotInputOutputName(ff,true,detail,level);
993 fprintf(ff,":%s",cbbid->GetName().c_str() );
996 BlackBox::Pointer bb = bbGetBlackBox( cbbid->GetTarget() );
997 bb->bbWriteDotInputOutputName(ff,true,detail,level);
1000 fprintf(ff,":%s \n", cbbid->GetInput().c_str() );
1006 fprintf(ff,"\n \n");
1010 // Relation Output ComplexBlackBox
1011 ComplexBlackBoxDescriptor::OutputDescriptorMapType::iterator yy;
1012 ComplexBlackBoxDescriptor::OutputDescriptorMapType odmt=bbGetDescriptor()->GetOutputDescriptorMap();
1013 for ( yy = odmt.begin(); yy != odmt.end(); ++yy )
1015 ComplexBlackBoxOutputDescriptor *cbbod = (ComplexBlackBoxOutputDescriptor*)yy->second;
1017 BlackBox::Pointer bb = bbGetBlackBox( cbbod->GetTarget() );
1018 bb->bbWriteDotInputOutputName(ff,false,detail,level);
1021 fprintf(ff,":%s", cbbod->GetOutput().c_str() );
1024 bbWriteDotInputOutputName(ff,false,detail,level);
1027 fprintf(ff,":%s",cbbod->GetName().c_str() );
1036 // Relation from the out side of this ComplexBlackBox with its Inputs
1037 if (GetThisPointer<ComplexBlackBox>()!=parentblackbox) {
1038 for ( ii = bbGetInputConnectorMap().begin();
1039 ii != bbGetInputConnectorMap().end(); ++ii )
1043 Connection* con = ii->second->GetConnection();
1045 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1046 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1048 a->bbWriteDotInputOutputName(ff,false,detail,level);
1051 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1054 b->bbWriteDotInputOutputName(ff,true,detail,level);
1057 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1059 fprintf(ff,"%s\n",";");
1063 } // if parentblackbox
1065 //=========================================================================
1072 //=======================================================================
1073 /// Generates the list of the packages of which its depends
1074 /// (cause an internal box belongs to it)
1075 void ComplexBlackBox::GetPackagesDependencies(std::vector<Package*>& deps)
1078 BlackBoxMapType::iterator i;
1079 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
1081 deps.push_back(i->second->bbGetDescriptor()->GetPackage());
1085 //=======================================================================
1088 //=======================================================================
1089 void ComplexBlackBox::Check(bool recursive)
1091 bbtkMessage("debug",1,"**** Checking Complex Black Box "<<(void*)this
1092 <<" ["<<bbGetFullName()<<"]"<<std::endl);
1094 BlackBoxMapType::const_iterator i;
1095 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
1097 i->second->Check(recursive);
1099 ConnectionListType::const_iterator j;
1100 for ( j = mConnectionList.begin();
1101 j != mConnectionList.end(); ++j )
1105 bbtkMessage("debug",1,"**** Checking Complex Black Box "<<(void*)this
1106 <<" ["<<bbGetFullName()<<"] ... OK"<<std::endl);
1109 //=======================================================================
1111 //=========================================================================
1112 /// Returns the name with the name of the parent prepended if any
1113 std::string ComplexBlackBox::bbGetNameWithParent() const
1115 if (!IsAPrototype()) return BlackBox::bbGetNameWithParent();
1116 if (bbGetDescriptor())
1118 return bbGetDescriptor()->GetFullTypeName() + ":" + bbGetName();
1122 return std::string(":") + bbGetName();
1125 //=========================================================================
1127 //==========================================================================
1128 std::string ComplexBlackBox::GetObjectName() const
1130 return std::string("ComplexBlackBox '")+bbGetNameWithParent()
1133 //==========================================================================
1135 //==========================================================================
1136 std::string ComplexBlackBox::GetObjectInfo() const
1138 std::stringstream i;
1139 i << " - "<<mBlackBoxMap.size() << " boxes / "
1140 <<mConnectionList.size() << " connections" << std::endl;
1143 //==========================================================================
1145 //==========================================================================
1146 size_t ComplexBlackBox::GetObjectSize() const
1148 size_t s = Superclass::GetObjectSize();
1149 s += ComplexBlackBox::GetObjectInternalSize();
1152 //==========================================================================
1153 //==========================================================================
1154 size_t ComplexBlackBox::GetObjectInternalSize() const
1156 size_t s = sizeof(ComplexBlackBox);
1159 //==========================================================================
1160 //==========================================================================
1161 size_t ComplexBlackBox::GetObjectRecursiveSize() const
1163 size_t s = Superclass::GetObjectRecursiveSize();
1164 s += ComplexBlackBox::GetObjectInternalSize();
1165 BlackBoxMapType::const_iterator i;
1166 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
1168 s += i->second->GetObjectRecursiveSize();
1170 ConnectionListType::const_iterator j;
1171 for ( j = mConnectionList.begin();
1172 j != mConnectionList.end(); ++j )
1174 s += (*j)->GetObjectRecursiveSize();
1178 //==========================================================================