1 /*=========================================================================
4 Module: $RCSfile: bbtkComplexBlackBox.cxx,v $
6 Date: $Date: 2008/07/24 14:37:05 $
7 Version: $Revision: 1.20 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
22 * \brief class bbtk::ComplexBlackBox : user defined complex black boxes
24 #include "bbtkComplexBlackBox.h"
26 #include "bbtkBlackBoxDescriptor.h"
27 #include "bbtkFactory.h"
28 #include "bbtkConfigurationFile.h"
33 //==========================================================================
34 /// Creates a new complex black box
35 ComplexBlackBox::Pointer ComplexBlackBox::New(const std::string& name,
36 ComplexBlackBoxDescriptor::Pointer desc)
38 bbtkDebugMessage("object",1,"##> ComplexBlackBox::New('"<<name<<"','"<<
39 desc->GetTypeName()<<"')" <<bbtkendl);
40 ComplexBlackBox::Pointer p =
41 MakeBlackBoxPointer(new ComplexBlackBox(name,desc));
42 bbtkDebugMessage("object",2,"<## ComplexBlackBox::New('"<<name<<"','"<<
43 desc->GetTypeName()<<"')" <<bbtkendl);
46 //==========================================================================
48 //=======================================================================
49 /// Usefull constructor
50 ComplexBlackBox::ComplexBlackBox(const std::string &name,
51 ComplexBlackBoxDescriptor::Pointer desc)
54 mLockedDescriptor(desc),
57 bbtkDebugMessage("object",3,
58 "##> ComplexBlackBox::ComplexBlackBox(\""
59 <<name<<"\")"<<std::endl);
60 bbAllocateConnectors();
61 bbtkDebugMessage("object",3,
62 "<## ComplexBlackBox::ComplexBlackBox(\""
63 <<name<<"\")"<<std::endl);
65 //=======================================================================
67 //=======================================================================
68 /// Constructor from an existing box (copy) with a new name
69 ComplexBlackBox::ComplexBlackBox(ComplexBlackBox& from,
70 const std::string &name)
71 : BlackBox(from,name),
72 // The locked descriptor is copied from the unlocked one
73 // to make the box a non-prototype !!
74 mLockedDescriptor(from.mDescriptor),
75 mDescriptor(from.mDescriptor),
76 mExecutionList(from.mExecutionList)
78 bbtkDebugMessage("object",3,
79 "##> ComplexBlackBox::ComplexBlackBox(\""
80 <<from.bbGetName()<<"\",\""
81 <<name<<"\")"<<std::endl);
82 bbtkDebugMessage("object",4," * Cloning Black Boxes"<<std::endl);
84 // We have to make the shared_ptr on this because it is used
85 // in bbUnsafeAddBlackBox !
86 MakeBlackBoxPointer(this,true);
88 BlackBoxMapType::const_iterator i;
89 for ( i = from.mBlackBoxMap.begin(); i != from.mBlackBoxMap.end(); ++i )
91 bbtkDebugMessageInc("object",5," * Cloning \""<<i->first<<"\""<<std::endl);
92 BlackBox::Pointer B = i->second->bbClone(i->second->bbGetName());
93 bbUnsafeAddBlackBox(B);
96 bbtkDebugMessage("object",4," * Cloning Connections"<<std::endl);
97 ConnectionListType::const_iterator j;
98 for ( j = from.mConnectionList.begin(); j != from.mConnectionList.end(); ++j )
100 bbtkDebugMessage("object",5," * Cloning \""<<
101 (*j)->GetFullName()<<"\""<<std::endl);
103 BlackBox::Pointer bbfrom = bbGetBlackBox( (*j)->GetOriginalBlackBoxFrom()->bbGetName() );
104 BlackBox::Pointer bbto = bbGetBlackBox( (*j)->GetOriginalBlackBoxTo()->bbGetName() );
106 Connection::Pointer c = mDescriptor.lock()->GetFactory()->
107 NewConnection( bbfrom,
108 (*j)->GetOriginalBlackBoxFromOutput(),
110 (*j)->GetOriginalBlackBoxToInput() );
117 bbAllocateConnectors();
118 bbtkDebugMessage("object",3,
119 "<## ComplexBlackBox::ComplexBlackBox(\""
120 <<from.bbGetName()<<"\",\""
121 <<name<<"\")"<<std::endl);
123 //=======================================================================
125 //=======================================================================
127 ComplexBlackBox::~ComplexBlackBox()
129 bbtkDebugMessage("object",3,
130 "==> ComplexBlackBox::~ComplexBlackBox() ["
131 <<bbGetName()<<"]"<<std::endl);
133 bbtkDebugMessage("object",4,
134 " -> Releasing connections"<<std::endl);
135 mConnectionList.clear();
136 bbtkDebugMessage("object",4,
137 " -> Releasing boxes"<<std::endl);
138 mBlackBoxMap.clear();
141 this->bbDesallocateConnectors();
143 bbtkDebugMessage("object",3,
144 "<== ComplexBlackBox::~ComplexBlackBox() ["
145 <<bbGetName()<<"]"<<std::endl);
147 //=======================================================================
150 //=========================================================================
151 /// Allocates the i/o connectors of the black box
152 void ComplexBlackBox::bbAllocateConnectors()
154 bbtkDebugMessageInc("Kernel",8,
155 "ComplexBlackBox::bbAllocateConnectors() ["
156 <<bbGetFullName()<<"]"
160 const BlackBoxDescriptor::InputDescriptorMapType& imap
161 = bbGetDescriptor()->GetInputDescriptorMap();
162 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
163 for ( i = imap.begin(); i != imap.end(); ++i )
165 bbtkDebugMessage("Kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
166 // Redirect the connector to the internal box connector
167 // Cast the BBInputDescriptor into a ComplexBBInputDescriptor
168 ComplexBlackBoxInputDescriptor* d =
169 (ComplexBlackBoxInputDescriptor*)i->second;
170 // Get the internal box connector
171 BlackBoxInputConnector* c =
172 bbUnsafeGetBlackBox ( d->GetTarget() )
173 ->bbGetInputConnectorMap()[ d->GetInput() ];
175 bbGetInputConnectorMap()[i->second->GetName()] = c;
179 const BlackBoxDescriptor::OutputDescriptorMapType& omap
180 = bbGetDescriptor()->GetOutputDescriptorMap();
181 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
182 for ( o = omap.begin(); o != omap.end(); ++o )
184 bbtkDebugMessage("Kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
185 // Redirect the connector to the internal box connector
186 // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
187 ComplexBlackBoxOutputDescriptor* d =
188 (ComplexBlackBoxOutputDescriptor*)o->second;
189 // Get the internal box connector
190 BlackBoxOutputConnector* c =
191 bbUnsafeGetBlackBox ( d->GetTarget() )
192 ->bbGetOutputConnectorMap()[ d->GetOutput() ];
194 bbGetOutputConnectorMap()[o->second->GetName()] = c;
197 bbtkDebugDecTab("Kernel",8);
199 //=========================================================================
202 //=========================================================================
203 /// Desallocates the i/o connectors of the black box
204 void ComplexBlackBox::bbDesallocateConnectors()
206 bbtkDebugMessageInc("Kernel",8,
207 "ComplexBlackBox::DesallocateConnectors()"
210 // The connectors have not been allocated by the complex box
211 // but by the internal boxes. Hence **DO NOT** desallocate !
212 // just clear the maps to avoid that
213 // BlackBox::bbDesallocateConnectors delete the connectors
214 bbGetInputConnectorMap().clear();
215 bbGetOutputConnectorMap().clear();
217 bbtkDebugDecTab("Kernel",8);
220 //=========================================================================
222 //=======================================================================
223 BlackBox::Pointer ComplexBlackBox::bbClone(const std::string& name)
225 bbtkDebugMessageInc("Kernel",9,
226 "ComplexBlackBox::bbClone(\""<<name<<"\") ["
227 <<bbGetFullName()<<"]"<<std::endl);
229 ComplexBlackBox* CBB = new ComplexBlackBox(*this,name);
230 return MakeBlackBoxPointer(CBB);
232 //=======================================================================
234 //=======================================================================
235 /// Main processing method of the box.
236 /// Executes the box so that its outputs are up-to-date on exit
237 void ComplexBlackBox::bbExecute(bool force)
239 bbtkDebugMessageInc("process",2,
240 "=> ComplexBlackBox::bbExecute() ["
241 <<bbGetFullName()<<"]"<<std::endl);
246 if (mExecutionList.size() != 0)
249 std::vector<std::string>::const_iterator i;
250 for (i=mExecutionList.begin();
251 i!=mExecutionList.end();
254 bbtkDebugMessage("process",3," -> Executing '"<<*i<<"'"<<std::endl);
255 mBlackBoxMap[*i]->bbExecute(force);
260 std::map<std::string, BlackBox::Pointer>::iterator i;
261 for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i)
263 i->second->bbExecute(force);
268 //==================================================================
270 //==================================================================
271 void ComplexBlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
273 bbtkDebugMessage("modified",1,
274 "==> ComplexBlackBox::bbSetModifiedStatus("
275 <<c<<") ["<<bbGetFullName()<<"]"<<std::endl);
277 c->GetBlackBox()->bbSetModifiedStatus(c);
280 bbtkDebugMessage("modified",1,
281 "<== ComplexBlackBox::bbSetModifiedStatus("
282 <<c<<") ["<<bbGetFullName()<<"]"<<std::endl);
285 //==================================================================
287 //==================================================================
288 void ComplexBlackBox::bbAddToExecutionList( const std::string& name )
290 bbtkDebugMessageInc("Kernel",9,
291 "ComplexBlackBox::bbAddToExecutionList(\""
293 <<bbGetFullName()<<"]"<<std::endl);
295 mExecutionList.push_back( name );
297 bbtkDebugDecTab("Kernel",9);
300 //==================================================================
302 //==================================================================
303 IOStatus ComplexBlackBox::bbBackwardUpdate(Connection::Pointer caller)
305 bbtkDebugMessageInc("process",3,
306 "==> ComplexBlackBox::bbBackwardUpdate("
307 <<(caller?caller->GetFullName():"0")<<") ["
308 <<bbGetFullName()<<"]"<<std::endl);
309 // bbtkInternalError("ComplexBlackBox::bbBackwardUpdate should never be called !");
313 bbtkInternalError("ComplexBlackBox::bbBackwardUpdate called with caller=0");
317 std::cout << "CBB BUP : "<<caller->GetBlackBoxFrom()->bbGetFullName()
318 <<"."<<caller->GetBlackBoxFromOutput()<<"----"
319 <<caller->GetOriginalBlackBoxFrom()->bbGetFullName()
320 <<"."<<caller->GetOriginalBlackBoxFromOutput()<<std::endl;
325 IOStatus s = UPTODATE;
326 const BlackBoxDescriptor::OutputDescriptorMapType& omap
327 = bbGetDescriptor()->GetOutputDescriptorMap();
328 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator i
329 = omap.find(caller->GetBlackBoxFromOutput());
332 // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
333 ComplexBlackBoxOutputDescriptor* d =
334 (ComplexBlackBoxOutputDescriptor*)i->second;
335 // Get the internal box
336 BlackBox::Pointer b = bbUnsafeGetBlackBox ( d->GetTarget() );
337 // Calls BackwardUpdate on it
338 bbtkDebugMessageInc("process",4,"Internal box connected to output : "<<d->GetTarget()<<std::endl);
339 // Because internal box can also be a complex box we have to
340 // temporarily change the connection BlackBoxFromOutput to the
343 // std::string oldout = caller->GetBlackBoxFromOutput();
344 // std::cout << "oldout = "<<oldout<<std::endl;
345 // std::cout << "tmpout = "<<d->GetOutput()<<std::endl;
346 // caller->SetBlackBoxFromOutput(d->GetOutput());
348 //Connection newcaller(*caller);
349 //newcaller.SetBlackBoxFromOutput(d->GetOutput());
350 //IOStatus s1 = b->bbBackwardUpdate(&newcaller);
351 IOStatus s1 = b->bbBackwardUpdate(caller);
353 // restore old output
354 // caller->SetBlackBoxFromOutput(oldout);
356 // ??? STATUS OF CBBs ???
357 // ??? Here it is only the final status of the boxes connected to the output
358 if (s1==MODIFIED) s=MODIFIED;
362 bbtkError("Connection '"<<caller->GetFullName()<<"' does not point to a valid output of the complex box !");
368 //==================================================================
371 //==================================================================
372 Data ComplexBlackBox::bbGetOutput( const std::string &name )
374 bbtkDebugMessageInc("Data",7,
375 "ComplexBlackBox::bbGetOutput(\""<<name<<"\") ["
376 <<bbGetFullName()<<"]"<<std::endl);
378 ComplexBlackBoxOutputDescriptor* d =
379 (ComplexBlackBoxOutputDescriptor*)
380 bbGetDescriptor()->GetOutputDescriptor(name);
382 Data p = bbGetBlackBox(d->GetTarget())->bbGetOutput(d->GetOutput());
385 bbtkDebugDecTab("Data",7);
388 //==================================================================
390 //==================================================================
391 /// Gets the input Data of a given name
392 Data ComplexBlackBox::bbGetInput( const std::string &name )
394 bbtkDebugMessageInc("Data",7,
395 "ComplexBlackBox::bbGetInput(\""<<name<<"\") ["
396 <<bbGetFullName()<<"]"<<std::endl);
398 ComplexBlackBoxInputDescriptor* d =
399 (ComplexBlackBoxInputDescriptor*)
400 bbGetDescriptor()->GetInputDescriptor(name);
402 Data p = bbGetBlackBox(d->GetTarget())->bbGetInput(d->GetInput());
404 bbtkDebugDecTab("Data",7);
407 //==================================================================
409 //==================================================================
410 /// Sets the data of the output called <name>
411 void ComplexBlackBox::bbSetOutput( const std::string &name, Data data)
413 bbtkDebugMessageInc("Data",7,
414 "ComplexBlackBox::bbSetOutput(\""<<name<<"\",data) ["
415 <<bbGetFullName()<<"]"<<std::endl);
417 ComplexBlackBoxOutputDescriptor* d =
418 (ComplexBlackBoxOutputDescriptor*)
419 bbGetDescriptor()->GetOutputDescriptor(name);
421 bbGetBlackBox(d->GetTarget())->bbSetOutput(d->GetOutput(),data);
423 bbtkDebugDecTab("Data",7);
425 //==================================================================
427 //==================================================================
428 /// Sets the data of the input called <name>
429 void ComplexBlackBox::bbSetInput( const std::string &name, Data data,
432 bbtkDebugMessageInc("Data",7,
433 "ComplexBlackBox::bbSetInput(\""<<name<<"\",data) ["
434 <<bbGetFullName()<<"]"<<std::endl);
436 ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
437 bbGetDescriptor()->GetInputDescriptor(name);
439 bbGetBlackBox(d->GetTarget())->bbSetInput(d->GetInput(),data,setModified);
441 bbtkDebugDecTab("Data",7);
443 //==================================================================
446 //==================================================================
447 /// Sets the data of the input called <name>
448 void ComplexBlackBox::bbBruteForceSetInputPointer( const std::string &name,
452 bbtkDebugMessageInc("Data",7,
453 "ComplexBlackBox::bbBruteForceSetInputPointer('"
454 <<name<<"',"<<data<<") ["
455 <<bbGetFullName()<<"]"<<std::endl);
457 ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
458 bbGetDescriptor()->GetInputDescriptor(name);
460 bbGetBlackBox(d->GetTarget())->bbBruteForceSetInputPointer(d->GetInput(),
464 bbtkDebugDecTab("Data",7);
466 //==================================================================
468 //=========================================================================
469 /// Connects the input <name> to the connection c
470 void ComplexBlackBox::bbConnectInput( const std::string& name, Connection* c)
472 bbtkDebugMessage("connection",2,
473 "==> ComplexBlackBox::bbConnectInput(\""
474 <<name<<"\","<<c->GetFullName()<<") ["
475 <<bbGetFullName()<<"]"
478 ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
479 bbGetDescriptor()->GetInputDescriptor(name);
482 BlackBox::Pointer t = bbGetBlackBox(d->GetTarget());
484 bbtkDebugMessage("connection",2," - Target = "<<d->GetTarget()<<" = "<<t->bbGetFullName()<<std::endl);
487 c->SetBlackBoxToInput(d->GetInput());
489 bbtkDebugMessage("connection",2," - New conn = "<<c->GetFullName()<<std::endl);
490 t->bbConnectInput(d->GetInput(),c);
492 bbtkDebugMessage("connection",2,
493 "<== ComplexBlackBox::bbConnectInput(\""
494 <<name<<"\","<<c->GetFullName()<<") ["
495 <<bbGetFullName()<<"]"
498 //=========================================================================
501 //=========================================================================
502 /// Connects the output <name> to the connection c
503 void ComplexBlackBox::bbConnectOutput( const std::string& name, Connection* c)
505 bbtkDebugMessage("connection",2,
506 "==> ComplexBlackBox::bbConnectOutput(\""
507 <<name<<"\","<<c->GetFullName()<<") ["
508 <<bbGetFullName()<<"]"<<std::endl);
510 ComplexBlackBoxOutputDescriptor* d = (ComplexBlackBoxOutputDescriptor*)
511 bbGetDescriptor()->GetOutputDescriptor(name);
513 BlackBox::Pointer t = bbGetBlackBox(d->GetTarget());
515 bbtkDebugMessage("connection",2," - Target = "<<d->GetTarget()<<" = "<<t->bbGetFullName()<<std::endl);
517 c->SetBlackBoxFrom(t);
518 c->SetBlackBoxFromOutput(d->GetOutput());
520 bbtkDebugMessage("connection",2," - New conn = "<<c->GetFullName()<<std::endl);
522 t->bbConnectOutput(d->GetOutput(),c);
524 bbtkDebugMessage("connection",2,
525 "<== ComplexBlackBox::bbConnectOutput(\""
526 <<name<<"\","<<c->GetFullName()<<") ["
527 <<bbGetFullName()<<"]"<<std::endl);
529 //=========================================================================
532 //==================================================================
533 /// Adds the black box to the complex box
534 void ComplexBlackBox::bbAddBlackBox( BlackBox::Pointer b)
536 bbtkDebugMessageInc("Kernel",7,
537 "ComplexBlackBox::AddBlackBox(\""<<b->bbGetName()
539 <<bbGetFullName()<<"]"<<std::endl);
541 if ( bbUnsafeGetBlackBox(b->bbGetName()) )
543 bbtkError("a black box called \""<<b->bbGetName()
544 <<"\" already exists");
546 b->bbSetParent(GetThisPointer<ComplexBlackBox>());
547 mBlackBoxMap[b->bbGetName()] = b;
549 bbtkDebugDecTab("Kernel",7);
551 //==================================================================
553 //==================================================================
554 /// Adds the black box to the complex box (unsafe)
555 void ComplexBlackBox::bbUnsafeAddBlackBox( BlackBox::Pointer b)
557 bbtkDebugMessageInc("Kernel",7,
558 "ComplexBlackBox::UnsafeAddBlackBox(\""<<b->bbGetName()
560 <<bbGetFullName()<<"]"<<std::endl);
562 b->bbSetParent(GetThisPointer<ComplexBlackBox>());
563 mBlackBoxMap[b->bbGetName()] = b;
565 bbtkDebugDecTab("Kernel",7);
567 //==================================================================
569 //==================================================================
570 /// Removes the black box from the complex box
571 void ComplexBlackBox::bbRemoveBlackBox( const std::string& name,
572 bool remove_connections )
574 bbtkDebugMessageInc("Kernel",7,
575 "ComplexBlackBox::RemoveBlackBox(\""<<name<<"\") ["
576 <<bbGetFullName()<<"]"<<std::endl);
578 BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
579 if ( i == mBlackBoxMap.end() )
581 bbtkError("the black box \""<<name<<"\" does not exist");
583 BlackBox::WeakPointer p = i->second;
585 if (remove_connections)
587 ConnectionListType::const_iterator j;
588 for ( j = mConnectionList.begin();
589 j != mConnectionList.end(); ++j )
594 if (p.use_count()!=1)
596 bbtkError("the black box \""<<name<<"\" is still connected");
599 mBlackBoxMap.erase(i);
602 // Unload orphan dl packages
603 Package::UnLoadReleasedDynamicallyLoadedPackages();
605 bbtkDebugDecTab("Kernel",7);
607 //==================================================================
609 //==================================================================
610 /// Adds the connection to the complex box
611 void ComplexBlackBox::bbAddConnection( Connection::Pointer c)
613 bbtkDebugMessageInc("Kernel",7,
614 "ComplexBlackBox::AddConnection(\""<<"..."<<"\") ["
615 <<bbGetFullName()<<"]"<<std::endl);
617 mConnectionList.push_back(c);
619 bbtkDebugDecTab("Kernel",7);
621 //==================================================================
622 // void RemoveConnection( );
624 //==================================================================
625 /// Returns the black box with name <name>
626 BlackBox::Pointer ComplexBlackBox::bbGetBlackBox( const std::string& name )
628 bbtkDebugMessageInc("Kernel",9,
629 "ComplexBlackBox::GetBlackBox(\""<<name<<"\") ["
630 <<bbGetFullName()<<"]"<<std::endl);
632 BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
633 if ( i == mBlackBoxMap.end() )
635 bbtkError("the black box \""<<name<<"\" does not exist");
638 bbtkDebugDecTab("Kernel",9);
641 //==================================================================
643 //==================================================================
644 /// Returns the black box with name <name> : does not throw an exception
645 /// if it does not exist but return a null pointer
646 BlackBox::Pointer ComplexBlackBox::bbUnsafeGetBlackBox( const std::string& name )
648 bbtkDebugMessageInc("Kernel",9,
649 "ComplexBlackBox::UnsafeGetBlackBox(\""<<name<<"\") ["
650 <<bbGetFullName()<<"]"
653 BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
654 if ( i == mBlackBoxMap.end() )
656 bbtkDebugDecTab("Kernel",9);
657 return BlackBox::Pointer();
660 bbtkDebugDecTab("Kernel",9);
664 //==================================================================
666 //==================================================================
667 void ComplexBlackBox::bbPrintBlackBoxes()
669 bbtkDebugMessageInc("Kernel",9,
670 "ComplexBlackBox::PrintBlackBoxes() ["
671 <<bbGetFullName()<<"]"
674 BlackBoxMapType::iterator i;
675 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
677 bbtkMessage("Help",1,i->second->bbGetFullName()<<std::endl);
680 bbtkDebugDecTab("Kernel",9);
682 //==================================================================
686 //=========================================================================
688 void ComplexBlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
692 fprintf(ff,"%s_IN_%p",bbGetTypeName().c_str(),this);
694 fprintf(ff,"%s_OUT_%p",bbGetTypeName().c_str(),this);
697 //=========================================================================
700 //=========================================================================
701 BlackBox::Pointer ComplexBlackBox::bbFindBlackBox(const std::string &blackboxname)
703 BlackBox::Pointer blackbox;
704 std::string subname="";
705 std::string restname="";
706 std::string delimiters(">");
707 // Skip delimiters at beginning.
708 std::string::size_type lastPos = blackboxname.find_first_not_of(delimiters, 0);
709 // Find first "non-delimiter".
710 std::string::size_type pos = blackboxname.find_first_of(delimiters, lastPos);
712 // Found a token, add it to the vector.
713 subname = blackboxname.substr(lastPos, pos - lastPos);
714 restname = blackboxname.substr(lastPos+pos - lastPos+1, 999);
716 if (restname==subname)
721 BlackBoxMapType::iterator i = mBlackBoxMap.find(subname);
722 if ( i != mBlackBoxMap.end() )
724 blackbox = i->second;
727 blackbox = blackbox->bbFindBlackBox(restname);
732 //=========================================================================
734 //=========================================================================
735 void ComplexBlackBox::bbInsertHTMLGraph( std::ofstream& s,
739 const std::string& output_dir,
743 std::string directory(output_dir);
745 if (output_dir.length() == 0)
747 // Don't pollute the file store with "temp_dir" directories ...
748 std::string default_temp_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
749 directory = default_temp_dir + "/" + "temp_dir";
752 std::string simplefilename (this->bbGetTypeName()+"_"+this->bbGetName());
753 std::string simplefilename_png (simplefilename+".png");
754 std::string filename (directory+"/"+simplefilename);
755 std::string filename_png (filename+".png");
756 std::string filename_cmap (filename+".cmap");
757 std::string filename_dot (filename+".dot");
759 std::string filename_png2 ("\"" + filename_png + "\"");
760 std::string filename_cmap2 ("\"" + filename_cmap + "\"");
761 std::string filename_dot2 ("\"" + filename_dot + "\"");
764 std::string command1 ("dot -T png -o "
765 + filename_png2 + " " + filename_dot2);
766 std::string command1a("dot -T cmap -o "
767 + filename_cmap2 + " " + filename_dot2);
769 // 1. Generating .dot file
771 ff = fopen(filename_dot.c_str(),"w");
772 fprintf(ff,"digraph bbtk_graph{\n");
773 fprintf(ff,"rankdir=LR%s\n",";");
774 fprintf(ff,"node [shape=record]%s\n",";");
776 this->bbWriteDotFileBlackBox(ff,
777 GetThisPointer<ComplexBlackBox>(),
785 // 2. Executing .dot file -> png
786 system( command1.c_str() );
787 // 3. Executing .dot file -> cmap
788 system( command1a.c_str() );
790 // 4. HTML code insertion
792 (s) << "<center><img src=\"" << simplefilename_png
793 << "\" border=\"0\" usemap=\"#map_"<< simplefilename
794 <<"\" alt=\"\"></center>\n";
797 (s) << "<map name=\"map_"<< simplefilename <<"\">\n";
800 ff2=fopen(filename_cmap.c_str(),"r");
813 //=========================================================================
816 //=========================================================================
817 /// Write Graphviz-dot description in file
818 void ComplexBlackBox::bbWriteDotFileBlackBox(FILE *ff,
819 BlackBox::Pointer parentblackbox,
820 int detail, int level,
825 std::string valueStr("");
826 Package::Pointer package = this->bbGetDescriptor()->GetPackage();
831 tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL();
833 tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocURL();
840 std::string tmp2=bbGetTypeName();
841 std::string url(tmp1 + "#" + tmp2 );
842 fprintf( ff , "subgraph cluster_%s_%p {\n",bbGetName().c_str(),this);
844 if (!( (bbGetTypeName()=="workspace") && (bbGetName()=="workspacePrototype")) )
846 fprintf( ff , " URL = \"%s\" %s",url.c_str(),";");
849 std::string boxname="["+bbGetTypeName()+"]";
850 if (GetThisPointer<ComplexBlackBox>()!=parentblackbox)
858 boxname = bbGetName();
859 boxname = boxname + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
863 fprintf( ff , " label = \"%s\"%s\n", boxname.c_str() ,";");
867 // fprintf( ff , " style=filled%s\n",";");
868 // fprintf( ff , " color=grey%s\n",";");
869 fprintf( ff , " node [style=filled]%s\n",";");
870 fprintf( ff , " fillcolor=grey%s\n",";");
871 fprintf( ff , " edge [color=blue]%s\n",";");
875 std::string labelStr1;
876 std::string labelStr2;
877 labelStr1 = boxname + "\\n(output)" ;
878 labelStr2 = " | {{ ";
881 OutputConnectorMapType::iterator i;
883 const BlackBoxDescriptor::OutputDescriptorMapType& omap = this->bbGetDescriptor()->GetOutputDescriptorMap();
884 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
885 for ( o = omap.begin(); o != omap.end(); ++o )
889 labelStr2=labelStr2+" | ";
892 if (instanceOrtype==true)
894 valueStr = this->bbGetOutputAsString(o->second->GetName()/*
897 labelStr2=labelStr2+"<"+o->second->GetName().c_str()+"> " + valueStr + o->second->GetName().c_str();
900 labelStr2 = labelStr2+ " } }";
906 labelStr1 = labelStr1 + labelStr2;
911 bbWriteDotInputOutputName(ff,false,detail,level);
912 fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
917 labelStr1 = boxname + "\\n(input)" ;
918 labelStr2 = " | {{ ";
920 InputConnectorMapType::iterator ii;
922 const BlackBoxDescriptor::InputDescriptorMapType& imap = this->bbGetDescriptor()->GetInputDescriptorMap();
923 BlackBoxDescriptor::InputDescriptorMapType::const_iterator iii;
924 for ( iii = imap.begin(); iii != imap.end(); ++iii )
928 labelStr2=labelStr2+" | ";
931 if (instanceOrtype==true)
933 valueStr = this->bbGetInputAsString(iii->second->GetName()/*,factory*/) + " = ";
935 labelStr2=labelStr2+"<"+iii->second->GetName().c_str()+"> " + valueStr + iii->second->GetName().c_str();
939 labelStr2 = labelStr2+ " } }";
942 labelStr1 = labelStr1 + labelStr2;
946 bbWriteDotInputOutputName(ff,true,detail,level);
947 fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
952 BlackBoxMapType::iterator j;
953 for ( j = mBlackBoxMap.begin(); j != mBlackBoxMap.end(); ++j )
957 j->second->bbWriteDotFileBlackBox(ff,
966 fprintf( ff , "}\n\n");
968 fprintf( ff , " edge[color=blue]%s\n",";");
972 // Relation Input with the inside BlackBox of the this ComplexBlackbox
973 ComplexBlackBoxDescriptor::InputDescriptorMapType::iterator xx;
974 ComplexBlackBoxDescriptor::InputDescriptorMapType idmt=bbGetDescriptor()->GetInputDescriptorMap();
975 for ( xx = idmt.begin(); xx != idmt.end(); ++xx )
977 ComplexBlackBoxInputDescriptor *cbbid = (ComplexBlackBoxInputDescriptor*)xx->second;
980 bbWriteDotInputOutputName(ff,true,detail,level);
983 fprintf(ff,":%s",cbbid->GetName().c_str() );
986 BlackBox::Pointer bb = bbGetBlackBox( cbbid->GetTarget() );
987 bb->bbWriteDotInputOutputName(ff,true,detail,level);
990 fprintf(ff,":%s \n", cbbid->GetInput().c_str() );
1000 // Relation Output ComplexBlackBox
1001 ComplexBlackBoxDescriptor::OutputDescriptorMapType::iterator yy;
1002 ComplexBlackBoxDescriptor::OutputDescriptorMapType odmt=bbGetDescriptor()->GetOutputDescriptorMap();
1003 for ( yy = odmt.begin(); yy != odmt.end(); ++yy )
1005 ComplexBlackBoxOutputDescriptor *cbbod = (ComplexBlackBoxOutputDescriptor*)yy->second;
1007 BlackBox::Pointer bb = bbGetBlackBox( cbbod->GetTarget() );
1008 bb->bbWriteDotInputOutputName(ff,false,detail,level);
1011 fprintf(ff,":%s", cbbod->GetOutput().c_str() );
1014 bbWriteDotInputOutputName(ff,false,detail,level);
1017 fprintf(ff,":%s",cbbod->GetName().c_str() );
1026 // Relation from the out side of this ComplexBlackBox with its Inputs
1027 if (GetThisPointer<ComplexBlackBox>()!=parentblackbox) {
1028 for ( ii = bbGetInputConnectorMap().begin();
1029 ii != bbGetInputConnectorMap().end(); ++ii )
1033 Connection* con = ii->second->GetConnection();
1035 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1036 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1038 a->bbWriteDotInputOutputName(ff,false,detail,level);
1041 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1044 b->bbWriteDotInputOutputName(ff,true,detail,level);
1047 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1049 fprintf(ff,"%s\n",";");
1053 } // if parentblackbox
1055 //=========================================================================
1062 //=======================================================================
1063 /// Generates the list of the packages of which its depends
1064 /// (cause an internal box belongs to it)
1065 void ComplexBlackBox::GetPackagesDependencies(std::vector<Package*>& deps)
1068 BlackBoxMapType::iterator i;
1069 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
1071 deps.push_back(i->second->bbGetDescriptor()->GetPackage());
1075 //=======================================================================
1078 //=======================================================================
1079 void ComplexBlackBox::Check(bool recursive)
1081 bbtkMessage("debug",1,"**** Checking Complex Black Box "<<(void*)this
1082 <<" ["<<bbGetFullName()<<"]"<<std::endl);
1084 BlackBoxMapType::const_iterator i;
1085 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
1087 i->second->Check(recursive);
1089 ConnectionListType::const_iterator j;
1090 for ( j = mConnectionList.begin();
1091 j != mConnectionList.end(); ++j )
1095 bbtkMessage("debug",1,"**** Checking Complex Black Box "<<(void*)this
1096 <<" ["<<bbGetFullName()<<"] ... OK"<<std::endl);
1099 //=======================================================================
1101 //=========================================================================
1102 /// Returns the name with the name of the parent prepended if any
1103 std::string ComplexBlackBox::bbGetNameWithParent() const
1105 if (!IsAPrototype()) return BlackBox::bbGetNameWithParent();
1106 if (bbGetDescriptor())
1108 return bbGetDescriptor()->GetFullTypeName() + ":" + bbGetName();
1112 return std::string(":") + bbGetName();
1115 //=========================================================================
1117 //==========================================================================
1118 std::string ComplexBlackBox::GetObjectName() const
1120 return std::string("ComplexBlackBox '")+bbGetNameWithParent()
1123 //==========================================================================
1125 //==========================================================================
1126 std::string ComplexBlackBox::GetObjectInfo() const
1128 std::stringstream i;
1129 i << " - "<<mBlackBoxMap.size() << " boxes / "
1130 <<mConnectionList.size() << " connections" << std::endl;
1133 //==========================================================================
1135 //==========================================================================
1136 size_t ComplexBlackBox::GetObjectSize() const
1138 size_t s = Superclass::GetObjectSize();
1139 s += ComplexBlackBox::GetObjectInternalSize();
1142 //==========================================================================
1143 //==========================================================================
1144 size_t ComplexBlackBox::GetObjectInternalSize() const
1146 size_t s = sizeof(ComplexBlackBox);
1149 //==========================================================================
1150 //==========================================================================
1151 size_t ComplexBlackBox::GetObjectRecursiveSize() const
1153 size_t s = Superclass::GetObjectRecursiveSize();
1154 s += ComplexBlackBox::GetObjectInternalSize();
1155 BlackBoxMapType::const_iterator i;
1156 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
1158 s += i->second->GetObjectRecursiveSize();
1160 ConnectionListType::const_iterator j;
1161 for ( j = mConnectionList.begin();
1162 j != mConnectionList.end(); ++j )
1164 s += (*j)->GetObjectRecursiveSize();
1168 //==========================================================================