1 /*=========================================================================
4 Module: $RCSfile: bbtkComplexBlackBox.cxx,v $
6 Date: $Date: 2008/04/24 11:49:59 $
7 Version: $Revision: 1.19 $
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"
25 #include "bbtkBlackBoxDescriptor.h"
26 #include "bbtkFactory.h"
27 #include "bbtkConfigurationFile.h"
32 //==========================================================================
33 /// Creates a new complex black box
34 ComplexBlackBox::Pointer ComplexBlackBox::New(const std::string& name,
35 ComplexBlackBoxDescriptor::Pointer desc)
37 bbtkDebugMessage("object",1,"##> ComplexBlackBox::New('"<<name<<"','"<<
38 desc->GetTypeName()<<"')" <<bbtkendl);
39 ComplexBlackBox::Pointer p =
40 MakeBlackBoxPointer(new ComplexBlackBox(name,desc));
41 bbtkDebugMessage("object",2,"<## ComplexBlackBox::New('"<<name<<"','"<<
42 desc->GetTypeName()<<"')" <<bbtkendl);
45 //==========================================================================
47 //=======================================================================
48 /// Usefull constructor
49 ComplexBlackBox::ComplexBlackBox(const std::string &name,
50 ComplexBlackBoxDescriptor::Pointer desc)
53 mLockedDescriptor(desc),
56 bbtkDebugMessage("object",3,
57 "##> ComplexBlackBox::ComplexBlackBox(\""
58 <<name<<"\")"<<std::endl);
59 bbAllocateConnectors();
60 bbtkDebugMessage("object",3,
61 "<## ComplexBlackBox::ComplexBlackBox(\""
62 <<name<<"\")"<<std::endl);
64 //=======================================================================
66 //=======================================================================
67 /// Constructor from an existing box (copy) with a new name
68 ComplexBlackBox::ComplexBlackBox(ComplexBlackBox& from,
69 const std::string &name)
70 : BlackBox(from,name),
71 // The locked descriptor is copied from the unlocked one
72 // to make the box a non-prototype !!
73 mLockedDescriptor(from.mDescriptor),
74 mDescriptor(from.mDescriptor),
75 mExecutionList(from.mExecutionList)
77 bbtkDebugMessage("object",3,
78 "##> ComplexBlackBox::ComplexBlackBox(\""
79 <<from.bbGetName()<<"\",\""
80 <<name<<"\")"<<std::endl);
81 bbtkDebugMessage("object",4," * Cloning Black Boxes"<<std::endl);
83 // We have to make the shared_ptr on this because it is used
84 // in bbUnsafeAddBlackBox !
85 MakeBlackBoxPointer(this,true);
87 BlackBoxMapType::const_iterator i;
88 for ( i = from.mBlackBoxMap.begin(); i != from.mBlackBoxMap.end(); ++i )
90 bbtkDebugMessageInc("object",5," * Cloning \""<<i->first<<"\""<<std::endl);
91 BlackBox::Pointer B = i->second->bbClone(i->second->bbGetName());
92 bbUnsafeAddBlackBox(B);
95 bbtkDebugMessage("object",4," * Cloning Connections"<<std::endl);
96 ConnectionListType::const_iterator j;
97 for ( j = from.mConnectionList.begin(); j != from.mConnectionList.end(); ++j )
99 bbtkDebugMessage("object",5," * Cloning \""<<
100 (*j)->GetFullName()<<"\""<<std::endl);
102 BlackBox::Pointer bbfrom = bbGetBlackBox( (*j)->GetOriginalBlackBoxFrom()->bbGetName() );
103 BlackBox::Pointer bbto = bbGetBlackBox( (*j)->GetOriginalBlackBoxTo()->bbGetName() );
105 Connection::Pointer c = mDescriptor.lock()->GetFactory()->
106 NewConnection( bbfrom,
107 (*j)->GetOriginalBlackBoxFromOutput(),
109 (*j)->GetOriginalBlackBoxToInput() );
116 bbAllocateConnectors();
117 bbtkDebugMessage("object",3,
118 "<## ComplexBlackBox::ComplexBlackBox(\""
119 <<from.bbGetName()<<"\",\""
120 <<name<<"\")"<<std::endl);
122 //=======================================================================
124 //=======================================================================
126 ComplexBlackBox::~ComplexBlackBox()
128 bbtkDebugMessage("object",3,
129 "==> ComplexBlackBox::~ComplexBlackBox() ["
130 <<bbGetName()<<"]"<<std::endl);
132 bbtkDebugMessage("object",4,
133 " -> Releasing connections"<<std::endl);
134 mConnectionList.clear();
135 bbtkDebugMessage("object",4,
136 " -> Releasing boxes"<<std::endl);
137 mBlackBoxMap.clear();
140 this->bbDesallocateConnectors();
142 bbtkDebugMessage("object",3,
143 "<== ComplexBlackBox::~ComplexBlackBox() ["
144 <<bbGetName()<<"]"<<std::endl);
146 //=======================================================================
149 //=========================================================================
150 /// Allocates the i/o connectors of the black box
151 void ComplexBlackBox::bbAllocateConnectors()
153 bbtkDebugMessageInc("Kernel",8,
154 "ComplexBlackBox::bbAllocateConnectors() ["
155 <<bbGetFullName()<<"]"
159 const BlackBoxDescriptor::InputDescriptorMapType& imap
160 = bbGetDescriptor()->GetInputDescriptorMap();
161 BlackBoxDescriptor::InputDescriptorMapType::const_iterator i;
162 for ( i = imap.begin(); i != imap.end(); ++i )
164 bbtkDebugMessage("Kernel",8,"* Allocate \""<<i->first<<"\""<<std::endl);
165 // Redirect the connector to the internal box connector
166 // Cast the BBInputDescriptor into a ComplexBBInputDescriptor
167 ComplexBlackBoxInputDescriptor* d =
168 (ComplexBlackBoxInputDescriptor*)i->second;
169 // Get the internal box connector
170 BlackBoxInputConnector* c =
171 bbUnsafeGetBlackBox ( d->GetTarget() )
172 ->bbGetInputConnectorMap()[ d->GetInput() ];
174 bbGetInputConnectorMap()[i->second->GetName()] = c;
178 const BlackBoxDescriptor::OutputDescriptorMapType& omap
179 = bbGetDescriptor()->GetOutputDescriptorMap();
180 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
181 for ( o = omap.begin(); o != omap.end(); ++o )
183 bbtkDebugMessage("Kernel",8,"* Allocate \""<<o->first<<"\""<<std::endl);
184 // Redirect the connector to the internal box connector
185 // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
186 ComplexBlackBoxOutputDescriptor* d =
187 (ComplexBlackBoxOutputDescriptor*)o->second;
188 // Get the internal box connector
189 BlackBoxOutputConnector* c =
190 bbUnsafeGetBlackBox ( d->GetTarget() )
191 ->bbGetOutputConnectorMap()[ d->GetOutput() ];
193 bbGetOutputConnectorMap()[o->second->GetName()] = c;
196 bbtkDebugDecTab("Kernel",8);
198 //=========================================================================
201 //=========================================================================
202 /// Desallocates the i/o connectors of the black box
203 void ComplexBlackBox::bbDesallocateConnectors()
205 bbtkDebugMessageInc("Kernel",8,
206 "ComplexBlackBox::DesallocateConnectors()"
209 // The connectors have not been allocated by the complex box
210 // but by the internal boxes. Hence **DO NOT** desallocate !
211 // just clear the maps to avoid that
212 // BlackBox::bbDesallocateConnectors delete the connectors
213 bbGetInputConnectorMap().clear();
214 bbGetOutputConnectorMap().clear();
216 bbtkDebugDecTab("Kernel",8);
219 //=========================================================================
221 //=======================================================================
222 BlackBox::Pointer ComplexBlackBox::bbClone(const std::string& name)
224 bbtkDebugMessageInc("Kernel",9,
225 "ComplexBlackBox::bbClone(\""<<name<<"\") ["
226 <<bbGetFullName()<<"]"<<std::endl);
228 ComplexBlackBox* CBB = new ComplexBlackBox(*this,name);
229 return MakeBlackBoxPointer(CBB);
231 //=======================================================================
233 //=======================================================================
234 /// Main processing method of the box.
235 /// Executes the box so that its outputs are up-to-date on exit
236 void ComplexBlackBox::bbExecute(bool force)
238 bbtkDebugMessageInc("process",2,
239 "=> ComplexBlackBox::bbExecute() ["
240 <<bbGetFullName()<<"]"<<std::endl);
243 Wx::BeginBusyCursor();
245 if (mExecutionList.size() != 0)
248 std::vector<std::string>::const_iterator i;
249 for (i=mExecutionList.begin();
250 i!=mExecutionList.end();
253 bbtkDebugMessage("process",3," -> Executing '"<<*i<<"'"<<std::endl);
254 mBlackBoxMap[*i]->bbExecute(force);
259 std::map<std::string, BlackBox::Pointer>::iterator i;
260 for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i)
262 i->second->bbExecute(force);
270 //==================================================================
272 //==================================================================
273 void ComplexBlackBox::bbSetModifiedStatus(BlackBoxInputConnector* c)
275 bbtkDebugMessage("modified",1,
276 "==> ComplexBlackBox::bbSetModifiedStatus("
277 <<c<<") ["<<bbGetFullName()<<"]"<<std::endl);
279 c->GetBlackBox()->bbSetModifiedStatus(c);
282 bbtkDebugMessage("modified",1,
283 "<== ComplexBlackBox::bbSetModifiedStatus("
284 <<c<<") ["<<bbGetFullName()<<"]"<<std::endl);
287 //==================================================================
289 //==================================================================
290 void ComplexBlackBox::bbAddToExecutionList( const std::string& name )
292 bbtkDebugMessageInc("Kernel",9,
293 "ComplexBlackBox::bbAddToExecutionList(\""
295 <<bbGetFullName()<<"]"<<std::endl);
297 mExecutionList.push_back( name );
299 bbtkDebugDecTab("Kernel",9);
302 //==================================================================
304 //==================================================================
305 IOStatus ComplexBlackBox::bbBackwardUpdate(Connection::Pointer caller)
307 bbtkDebugMessageInc("process",3,
308 "==> ComplexBlackBox::bbBackwardUpdate("
309 <<(caller?caller->GetFullName():"0")<<") ["
310 <<bbGetFullName()<<"]"<<std::endl);
311 // bbtkInternalError("ComplexBlackBox::bbBackwardUpdate should never be called !");
315 bbtkInternalError("ComplexBlackBox::bbBackwardUpdate called with caller=0");
319 std::cout << "CBB BUP : "<<caller->GetBlackBoxFrom()->bbGetFullName()
320 <<"."<<caller->GetBlackBoxFromOutput()<<"----"
321 <<caller->GetOriginalBlackBoxFrom()->bbGetFullName()
322 <<"."<<caller->GetOriginalBlackBoxFromOutput()<<std::endl;
327 IOStatus s = UPTODATE;
328 const BlackBoxDescriptor::OutputDescriptorMapType& omap
329 = bbGetDescriptor()->GetOutputDescriptorMap();
330 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator i
331 = omap.find(caller->GetBlackBoxFromOutput());
334 // Cast the BBOutputDescriptor into a ComplexBBOutputDescriptor
335 ComplexBlackBoxOutputDescriptor* d =
336 (ComplexBlackBoxOutputDescriptor*)i->second;
337 // Get the internal box
338 BlackBox::Pointer b = bbUnsafeGetBlackBox ( d->GetTarget() );
339 // Calls BackwardUpdate on it
340 bbtkDebugMessageInc("process",4,"Internal box connected to output : "<<d->GetTarget()<<std::endl);
341 // Because internal box can also be a complex box we have to
342 // temporarily change the connection BlackBoxFromOutput to the
345 // std::string oldout = caller->GetBlackBoxFromOutput();
346 // std::cout << "oldout = "<<oldout<<std::endl;
347 // std::cout << "tmpout = "<<d->GetOutput()<<std::endl;
348 // caller->SetBlackBoxFromOutput(d->GetOutput());
350 //Connection newcaller(*caller);
351 //newcaller.SetBlackBoxFromOutput(d->GetOutput());
352 //IOStatus s1 = b->bbBackwardUpdate(&newcaller);
353 IOStatus s1 = b->bbBackwardUpdate(caller);
355 // restore old output
356 // caller->SetBlackBoxFromOutput(oldout);
358 // ??? STATUS OF CBBs ???
359 // ??? Here it is only the final status of the boxes connected to the output
360 if (s1==MODIFIED) s=MODIFIED;
364 bbtkError("Connection '"<<caller->GetFullName()<<"' does not point to a valid output of the complex box !");
370 //==================================================================
373 //==================================================================
374 Data ComplexBlackBox::bbGetOutput( const std::string &name )
376 bbtkDebugMessageInc("Data",7,
377 "ComplexBlackBox::bbGetOutput(\""<<name<<"\") ["
378 <<bbGetFullName()<<"]"<<std::endl);
380 ComplexBlackBoxOutputDescriptor* d =
381 (ComplexBlackBoxOutputDescriptor*)
382 bbGetDescriptor()->GetOutputDescriptor(name);
384 Data p = bbGetBlackBox(d->GetTarget())->bbGetOutput(d->GetOutput());
387 bbtkDebugDecTab("Data",7);
390 //==================================================================
392 //==================================================================
393 /// Gets the input Data of a given name
394 Data ComplexBlackBox::bbGetInput( const std::string &name )
396 bbtkDebugMessageInc("Data",7,
397 "ComplexBlackBox::bbGetInput(\""<<name<<"\") ["
398 <<bbGetFullName()<<"]"<<std::endl);
400 ComplexBlackBoxInputDescriptor* d =
401 (ComplexBlackBoxInputDescriptor*)
402 bbGetDescriptor()->GetInputDescriptor(name);
404 Data p = bbGetBlackBox(d->GetTarget())->bbGetInput(d->GetInput());
406 bbtkDebugDecTab("Data",7);
409 //==================================================================
411 //==================================================================
412 /// Sets the data of the output called <name>
413 void ComplexBlackBox::bbSetOutput( const std::string &name, Data data)
415 bbtkDebugMessageInc("Data",7,
416 "ComplexBlackBox::bbSetOutput(\""<<name<<"\",data) ["
417 <<bbGetFullName()<<"]"<<std::endl);
419 ComplexBlackBoxOutputDescriptor* d =
420 (ComplexBlackBoxOutputDescriptor*)
421 bbGetDescriptor()->GetOutputDescriptor(name);
423 bbGetBlackBox(d->GetTarget())->bbSetOutput(d->GetOutput(),data);
425 bbtkDebugDecTab("Data",7);
427 //==================================================================
429 //==================================================================
430 /// Sets the data of the input called <name>
431 void ComplexBlackBox::bbSetInput( const std::string &name, Data data,
434 bbtkDebugMessageInc("Data",7,
435 "ComplexBlackBox::bbSetInput(\""<<name<<"\",data) ["
436 <<bbGetFullName()<<"]"<<std::endl);
438 ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
439 bbGetDescriptor()->GetInputDescriptor(name);
441 bbGetBlackBox(d->GetTarget())->bbSetInput(d->GetInput(),data,setModified);
443 bbtkDebugDecTab("Data",7);
445 //==================================================================
448 //==================================================================
449 /// Sets the data of the input called <name>
450 void ComplexBlackBox::bbBruteForceSetInputPointer( const std::string &name,
454 bbtkDebugMessageInc("Data",7,
455 "ComplexBlackBox::bbBruteForceSetInputPointer('"
456 <<name<<"',"<<data<<") ["
457 <<bbGetFullName()<<"]"<<std::endl);
459 ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
460 bbGetDescriptor()->GetInputDescriptor(name);
462 bbGetBlackBox(d->GetTarget())->bbBruteForceSetInputPointer(d->GetInput(),
466 bbtkDebugDecTab("Data",7);
468 //==================================================================
470 //=========================================================================
471 /// Connects the input <name> to the connection c
472 void ComplexBlackBox::bbConnectInput( const std::string& name, Connection* c)
474 bbtkDebugMessage("connection",2,
475 "==> ComplexBlackBox::bbConnectInput(\""
476 <<name<<"\","<<c->GetFullName()<<") ["
477 <<bbGetFullName()<<"]"
480 ComplexBlackBoxInputDescriptor* d = (ComplexBlackBoxInputDescriptor*)
481 bbGetDescriptor()->GetInputDescriptor(name);
484 BlackBox::Pointer t = bbGetBlackBox(d->GetTarget());
486 bbtkDebugMessage("connection",2," - Target = "<<d->GetTarget()<<" = "<<t->bbGetFullName()<<std::endl);
489 c->SetBlackBoxToInput(d->GetInput());
491 bbtkDebugMessage("connection",2," - New conn = "<<c->GetFullName()<<std::endl);
492 t->bbConnectInput(d->GetInput(),c);
494 bbtkDebugMessage("connection",2,
495 "<== ComplexBlackBox::bbConnectInput(\""
496 <<name<<"\","<<c->GetFullName()<<") ["
497 <<bbGetFullName()<<"]"
500 //=========================================================================
503 //=========================================================================
504 /// Connects the output <name> to the connection c
505 void ComplexBlackBox::bbConnectOutput( const std::string& name, Connection* c)
507 bbtkDebugMessage("connection",2,
508 "==> ComplexBlackBox::bbConnectOutput(\""
509 <<name<<"\","<<c->GetFullName()<<") ["
510 <<bbGetFullName()<<"]"<<std::endl);
512 ComplexBlackBoxOutputDescriptor* d = (ComplexBlackBoxOutputDescriptor*)
513 bbGetDescriptor()->GetOutputDescriptor(name);
515 BlackBox::Pointer t = bbGetBlackBox(d->GetTarget());
517 bbtkDebugMessage("connection",2," - Target = "<<d->GetTarget()<<" = "<<t->bbGetFullName()<<std::endl);
519 c->SetBlackBoxFrom(t);
520 c->SetBlackBoxFromOutput(d->GetOutput());
522 bbtkDebugMessage("connection",2," - New conn = "<<c->GetFullName()<<std::endl);
524 t->bbConnectOutput(d->GetOutput(),c);
526 bbtkDebugMessage("connection",2,
527 "<== ComplexBlackBox::bbConnectOutput(\""
528 <<name<<"\","<<c->GetFullName()<<") ["
529 <<bbGetFullName()<<"]"<<std::endl);
531 //=========================================================================
534 //==================================================================
535 /// Adds the black box to the complex box
536 void ComplexBlackBox::bbAddBlackBox( BlackBox::Pointer b)
538 bbtkDebugMessageInc("Kernel",7,
539 "ComplexBlackBox::AddBlackBox(\""<<b->bbGetName()
541 <<bbGetFullName()<<"]"<<std::endl);
543 if ( bbUnsafeGetBlackBox(b->bbGetName()) )
545 bbtkError("a black box called \""<<b->bbGetName()
546 <<"\" already exists");
548 b->bbSetParent(GetThisPointer<ComplexBlackBox>());
549 mBlackBoxMap[b->bbGetName()] = b;
551 bbtkDebugDecTab("Kernel",7);
553 //==================================================================
555 //==================================================================
556 /// Adds the black box to the complex box (unsafe)
557 void ComplexBlackBox::bbUnsafeAddBlackBox( BlackBox::Pointer b)
559 bbtkDebugMessageInc("Kernel",7,
560 "ComplexBlackBox::UnsafeAddBlackBox(\""<<b->bbGetName()
562 <<bbGetFullName()<<"]"<<std::endl);
564 b->bbSetParent(GetThisPointer<ComplexBlackBox>());
565 mBlackBoxMap[b->bbGetName()] = b;
567 bbtkDebugDecTab("Kernel",7);
569 //==================================================================
571 //==================================================================
572 /// Removes the black box from the complex box
573 void ComplexBlackBox::bbRemoveBlackBox( const std::string& name,
574 bool remove_connections )
576 bbtkDebugMessageInc("Kernel",7,
577 "ComplexBlackBox::RemoveBlackBox(\""<<name<<"\") ["
578 <<bbGetFullName()<<"]"<<std::endl);
580 BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
581 if ( i == mBlackBoxMap.end() )
583 bbtkError("the black box \""<<name<<"\" does not exist");
585 BlackBox::WeakPointer p = i->second;
587 if (remove_connections)
589 ConnectionListType::const_iterator j;
590 for ( j = mConnectionList.begin();
591 j != mConnectionList.end(); ++j )
596 if (p.use_count()!=1)
598 bbtkError("the black box \""<<name<<"\" is still connected");
601 mBlackBoxMap.erase(i);
604 // Unload orphan dl packages
605 Package::UnLoadReleasedDynamicallyLoadedPackages();
607 bbtkDebugDecTab("Kernel",7);
609 //==================================================================
611 //==================================================================
612 /// Adds the connection to the complex box
613 void ComplexBlackBox::bbAddConnection( Connection::Pointer c)
615 bbtkDebugMessageInc("Kernel",7,
616 "ComplexBlackBox::AddConnection(\""<<"..."<<"\") ["
617 <<bbGetFullName()<<"]"<<std::endl);
619 mConnectionList.push_back(c);
621 bbtkDebugDecTab("Kernel",7);
623 //==================================================================
624 // void RemoveConnection( );
626 //==================================================================
627 /// Returns the black box with name <name>
628 BlackBox::Pointer ComplexBlackBox::bbGetBlackBox( const std::string& name )
630 bbtkDebugMessageInc("Kernel",9,
631 "ComplexBlackBox::GetBlackBox(\""<<name<<"\") ["
632 <<bbGetFullName()<<"]"<<std::endl);
634 BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
635 if ( i == mBlackBoxMap.end() )
637 bbtkError("the black box \""<<name<<"\" does not exist");
640 bbtkDebugDecTab("Kernel",9);
643 //==================================================================
645 //==================================================================
646 /// Returns the black box with name <name> : does not throw an exception
647 /// if it does not exist but return a null pointer
648 BlackBox::Pointer ComplexBlackBox::bbUnsafeGetBlackBox( const std::string& name )
650 bbtkDebugMessageInc("Kernel",9,
651 "ComplexBlackBox::UnsafeGetBlackBox(\""<<name<<"\") ["
652 <<bbGetFullName()<<"]"
655 BlackBoxMapType::iterator i = mBlackBoxMap.find(name);
656 if ( i == mBlackBoxMap.end() )
658 bbtkDebugDecTab("Kernel",9);
659 return BlackBox::Pointer();
662 bbtkDebugDecTab("Kernel",9);
666 //==================================================================
668 //==================================================================
669 void ComplexBlackBox::bbPrintBlackBoxes()
671 bbtkDebugMessageInc("Kernel",9,
672 "ComplexBlackBox::PrintBlackBoxes() ["
673 <<bbGetFullName()<<"]"
676 BlackBoxMapType::iterator i;
677 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
679 bbtkMessage("Help",1,i->second->bbGetFullName()<<std::endl);
682 bbtkDebugDecTab("Kernel",9);
684 //==================================================================
688 //=========================================================================
690 void ComplexBlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level)
694 fprintf(ff,"%s_IN_%p",bbGetTypeName().c_str(),this);
696 fprintf(ff,"%s_OUT_%p",bbGetTypeName().c_str(),this);
699 //=========================================================================
702 //=========================================================================
703 BlackBox::Pointer ComplexBlackBox::bbFindBlackBox(const std::string &blackboxname)
705 BlackBox::Pointer blackbox;
706 std::string subname="";
707 std::string restname="";
708 std::string delimiters(">");
709 // Skip delimiters at beginning.
710 std::string::size_type lastPos = blackboxname.find_first_not_of(delimiters, 0);
711 // Find first "non-delimiter".
712 std::string::size_type pos = blackboxname.find_first_of(delimiters, lastPos);
714 // Found a token, add it to the vector.
715 subname = blackboxname.substr(lastPos, pos - lastPos);
716 restname = blackboxname.substr(lastPos+pos - lastPos+1, 999);
718 if (restname==subname)
723 BlackBoxMapType::iterator i = mBlackBoxMap.find(subname);
724 if ( i != mBlackBoxMap.end() )
726 blackbox = i->second;
729 blackbox = blackbox->bbFindBlackBox(restname);
734 //=========================================================================
736 //=========================================================================
737 void ComplexBlackBox::bbInsertHTMLGraph( std::ofstream& s,
741 const std::string& output_dir,
745 std::string directory(output_dir);
747 if (output_dir.length() == 0)
749 // Don't pollute the file store with "temp_dir" directories ...
750 std::string default_temp_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
751 directory = default_temp_dir + "/" + "temp_dir";
754 std::string simplefilename (this->bbGetTypeName()+"_"+this->bbGetName());
755 std::string simplefilename_png (simplefilename+".png");
756 std::string filename (directory+"/"+simplefilename);
757 std::string filename_png (filename+".png");
758 std::string filename_cmap (filename+".cmap");
759 std::string filename_dot (filename+".dot");
761 std::string filename_png2 ("\"" + filename_png + "\"");
762 std::string filename_cmap2 ("\"" + filename_cmap + "\"");
763 std::string filename_dot2 ("\"" + filename_dot + "\"");
766 std::string command1 ("dot -T png -o "
767 + filename_png2 + " " + filename_dot2);
768 std::string command1a("dot -T cmap -o "
769 + filename_cmap2 + " " + filename_dot2);
771 // 1. Generating .dot file
773 ff = fopen(filename_dot.c_str(),"w");
774 fprintf(ff,"digraph bbtk_graph{\n");
775 fprintf(ff,"rankdir=LR%s\n",";");
776 fprintf(ff,"node [shape=record]%s\n",";");
778 this->bbWriteDotFileBlackBox(ff,
779 GetThisPointer<ComplexBlackBox>(),
787 // 2. Executing .dot file -> png
788 system( command1.c_str() );
789 // 3. Executing .dot file -> cmap
790 system( command1a.c_str() );
792 // 4. HTML code insertion
794 (s) << "<center><img src=\"" << simplefilename_png
795 << "\" border=\"0\" usemap=\"#map_"<< simplefilename
796 <<"\" alt=\"\"></center>\n";
799 (s) << "<map name=\"map_"<< simplefilename <<"\">\n";
802 ff2=fopen(filename_cmap.c_str(),"r");
815 //=========================================================================
818 //=========================================================================
819 /// Write Graphviz-dot description in file
820 void ComplexBlackBox::bbWriteDotFileBlackBox(FILE *ff,
821 BlackBox::Pointer parentblackbox,
822 int detail, int level,
827 std::string valueStr("");
828 Package::Pointer package = this->bbGetDescriptor()->GetPackage();
833 tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL();
835 tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocURL();
842 std::string tmp2=bbGetTypeName();
843 std::string url(tmp1 + "#" + tmp2 );
844 fprintf( ff , "subgraph cluster_%s_%p {\n",bbGetName().c_str(),this);
846 if (!( (bbGetTypeName()=="workspace") && (bbGetName()=="workspacePrototype")) )
848 fprintf( ff , " URL = \"%s\" %s",url.c_str(),";");
851 std::string boxname="["+bbGetTypeName()+"]";
852 if (GetThisPointer<ComplexBlackBox>()!=parentblackbox)
860 boxname = bbGetName();
861 boxname = boxname + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]";
865 fprintf( ff , " label = \"%s\"%s\n", boxname.c_str() ,";");
869 // fprintf( ff , " style=filled%s\n",";");
870 // fprintf( ff , " color=grey%s\n",";");
871 fprintf( ff , " node [style=filled]%s\n",";");
872 fprintf( ff , " fillcolor=grey%s\n",";");
873 fprintf( ff , " edge [color=blue]%s\n",";");
877 std::string labelStr1;
878 std::string labelStr2;
879 labelStr1 = boxname + "\\n(output)" ;
880 labelStr2 = " | {{ ";
883 OutputConnectorMapType::iterator i;
885 const BlackBoxDescriptor::OutputDescriptorMapType& omap = this->bbGetDescriptor()->GetOutputDescriptorMap();
886 BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o;
887 for ( o = omap.begin(); o != omap.end(); ++o )
891 labelStr2=labelStr2+" | ";
894 if (instanceOrtype==true)
896 valueStr = this->bbGetOutputAsString(o->second->GetName()/*
899 labelStr2=labelStr2+"<"+o->second->GetName().c_str()+"> " + valueStr + o->second->GetName().c_str();
902 labelStr2 = labelStr2+ " } }";
908 labelStr1 = labelStr1 + labelStr2;
913 bbWriteDotInputOutputName(ff,false,detail,level);
914 fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
919 labelStr1 = boxname + "\\n(input)" ;
920 labelStr2 = " | {{ ";
922 InputConnectorMapType::iterator ii;
924 const BlackBoxDescriptor::InputDescriptorMapType& imap = this->bbGetDescriptor()->GetInputDescriptorMap();
925 BlackBoxDescriptor::InputDescriptorMapType::const_iterator iii;
926 for ( iii = imap.begin(); iii != imap.end(); ++iii )
930 labelStr2=labelStr2+" | ";
933 if (instanceOrtype==true)
935 valueStr = this->bbGetInputAsString(iii->second->GetName()/*,factory*/) + " = ";
937 labelStr2=labelStr2+"<"+iii->second->GetName().c_str()+"> " + valueStr + iii->second->GetName().c_str();
941 labelStr2 = labelStr2+ " } }";
944 labelStr1 = labelStr1 + labelStr2;
948 bbWriteDotInputOutputName(ff,true,detail,level);
949 fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" );
954 BlackBoxMapType::iterator j;
955 for ( j = mBlackBoxMap.begin(); j != mBlackBoxMap.end(); ++j )
959 j->second->bbWriteDotFileBlackBox(ff,
968 fprintf( ff , "}\n\n");
970 fprintf( ff , " edge[color=blue]%s\n",";");
974 // Relation Input with the inside BlackBox of the this ComplexBlackbox
975 ComplexBlackBoxDescriptor::InputDescriptorMapType::iterator xx;
976 ComplexBlackBoxDescriptor::InputDescriptorMapType idmt=bbGetDescriptor()->GetInputDescriptorMap();
977 for ( xx = idmt.begin(); xx != idmt.end(); ++xx )
979 ComplexBlackBoxInputDescriptor *cbbid = (ComplexBlackBoxInputDescriptor*)xx->second;
982 bbWriteDotInputOutputName(ff,true,detail,level);
985 fprintf(ff,":%s",cbbid->GetName().c_str() );
988 BlackBox::Pointer bb = bbGetBlackBox( cbbid->GetTarget() );
989 bb->bbWriteDotInputOutputName(ff,true,detail,level);
992 fprintf(ff,":%s \n", cbbid->GetInput().c_str() );
1002 // Relation Output ComplexBlackBox
1003 ComplexBlackBoxDescriptor::OutputDescriptorMapType::iterator yy;
1004 ComplexBlackBoxDescriptor::OutputDescriptorMapType odmt=bbGetDescriptor()->GetOutputDescriptorMap();
1005 for ( yy = odmt.begin(); yy != odmt.end(); ++yy )
1007 ComplexBlackBoxOutputDescriptor *cbbod = (ComplexBlackBoxOutputDescriptor*)yy->second;
1009 BlackBox::Pointer bb = bbGetBlackBox( cbbod->GetTarget() );
1010 bb->bbWriteDotInputOutputName(ff,false,detail,level);
1013 fprintf(ff,":%s", cbbod->GetOutput().c_str() );
1016 bbWriteDotInputOutputName(ff,false,detail,level);
1019 fprintf(ff,":%s",cbbod->GetName().c_str() );
1028 // Relation from the out side of this ComplexBlackBox with its Inputs
1029 if (GetThisPointer<ComplexBlackBox>()!=parentblackbox) {
1030 for ( ii = bbGetInputConnectorMap().begin();
1031 ii != bbGetInputConnectorMap().end(); ++ii )
1035 Connection* con = ii->second->GetConnection();
1037 BlackBox::Pointer a=con->GetOriginalBlackBoxFrom();
1038 BlackBox::Pointer b=con->GetOriginalBlackBoxTo();
1040 a->bbWriteDotInputOutputName(ff,false,detail,level);
1043 fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str());
1046 b->bbWriteDotInputOutputName(ff,true,detail,level);
1049 fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str());
1051 fprintf(ff,"%s\n",";");
1055 } // if parentblackbox
1057 //=========================================================================
1064 //=======================================================================
1065 /// Generates the list of the packages of which its depends
1066 /// (cause an internal box belongs to it)
1067 void ComplexBlackBox::GetPackagesDependencies(std::vector<Package*>& deps)
1070 BlackBoxMapType::iterator i;
1071 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
1073 deps.push_back(i->second->bbGetDescriptor()->GetPackage());
1077 //=======================================================================
1080 //=======================================================================
1081 void ComplexBlackBox::Check(bool recursive)
1083 bbtkMessage("debug",1,"**** Checking Complex Black Box "<<(void*)this
1084 <<" ["<<bbGetFullName()<<"]"<<std::endl);
1086 BlackBoxMapType::const_iterator i;
1087 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
1089 i->second->Check(recursive);
1091 ConnectionListType::const_iterator j;
1092 for ( j = mConnectionList.begin();
1093 j != mConnectionList.end(); ++j )
1097 bbtkMessage("debug",1,"**** Checking Complex Black Box "<<(void*)this
1098 <<" ["<<bbGetFullName()<<"] ... OK"<<std::endl);
1101 //=======================================================================
1103 //=========================================================================
1104 /// Returns the name with the name of the parent prepended if any
1105 std::string ComplexBlackBox::bbGetNameWithParent() const
1107 if (!IsAPrototype()) return BlackBox::bbGetNameWithParent();
1108 if (bbGetDescriptor())
1110 return bbGetDescriptor()->GetFullTypeName() + ":" + bbGetName();
1114 return std::string(":") + bbGetName();
1117 //=========================================================================
1119 //==========================================================================
1120 std::string ComplexBlackBox::GetObjectName() const
1122 return std::string("ComplexBlackBox '")+bbGetNameWithParent()
1125 //==========================================================================
1127 //==========================================================================
1128 std::string ComplexBlackBox::GetObjectInfo() const
1130 std::stringstream i;
1131 i << " - "<<mBlackBoxMap.size() << " boxes / "
1132 <<mConnectionList.size() << " connections" << std::endl;
1135 //==========================================================================
1137 //==========================================================================
1138 size_t ComplexBlackBox::GetObjectSize() const
1140 size_t s = Superclass::GetObjectSize();
1141 s += ComplexBlackBox::GetObjectInternalSize();
1144 //==========================================================================
1145 //==========================================================================
1146 size_t ComplexBlackBox::GetObjectInternalSize() const
1148 size_t s = sizeof(ComplexBlackBox);
1151 //==========================================================================
1152 //==========================================================================
1153 size_t ComplexBlackBox::GetObjectRecursiveSize() const
1155 size_t s = Superclass::GetObjectRecursiveSize();
1156 s += ComplexBlackBox::GetObjectInternalSize();
1157 BlackBoxMapType::const_iterator i;
1158 for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i )
1160 s += i->second->GetObjectRecursiveSize();
1162 ConnectionListType::const_iterator j;
1163 for ( j = mConnectionList.begin();
1164 j != mConnectionList.end(); ++j )
1166 s += (*j)->GetObjectRecursiveSize();
1170 //==========================================================================