/* # --------------------------------------------------------------------- # # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image # pour la SantÈ) # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton # Previous Authors : Laurent Guigues, Jean-Pierre Roux # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil # # This software is governed by the CeCILL-B license under French law and # abiding by the rules of distribution of free software. You can use, # modify and/ or redistribute the software under the terms of the CeCILL-B # license as circulated by CEA, CNRS and INRIA at the following URL # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html # or in the file LICENSE.txt. # # As a counterpart to the access to the source code and rights to copy, # modify and redistribute granted by the license, users are provided only # with a limited warranty and the software's author, the holder of the # economic rights, and the successive licensors have only limited # liability. # # The fact that you are presently reading this means that you have had # knowledge of the CeCILL-B license and that you accept its terms. # ------------------------------------------------------------------------ */ /*========================================================================= Program: bbtk Module: $RCSfile: bbtkComplexBlackBox.cxx,v $ Language: C++ Date: $Date: 2012/11/16 08:49:01 $ Version: $Revision: 1.33 $ =========================================================================*/ /** * \file * \brief class bbtk::ComplexBlackBox : user defined complex black boxes */ #include "bbtkComplexBlackBox.h" #include "bbtkWx.h" //#include "bbtkBlackBoxDescriptor.h" //#include "bbtkFactory.h" #include "bbtkConfigurationFile.h" namespace bbtk { //========================================================================== /// Creates a new complex black box ComplexBlackBox::Pointer ComplexBlackBox::New(const std::string& name, ComplexBlackBoxDescriptor::Pointer desc) { bbtkDebugMessage("object",1,"##> ComplexBlackBox::New('"<GetTypeName()<<"')" <GetTypeName()<<"')" < ComplexBlackBox(\"" < ComplexBlackBox(\"" <first<<"\""<second->bbClone(i->second->bbGetName()); bbUnsafeAddBlackBox(B); } bbtkBlackBoxDebugMessage("object",4," * Cloning Connections"<GetFullName()<<"\""<GetOriginalBlackBoxFrom()->bbGetName() ); BlackBox::Pointer bbto = bbGetBlackBox( (*j)->GetOriginalBlackBoxTo()->bbGetName() ); Connection::Pointer c = mDescriptor.lock()->GetFactory()-> NewConnection( bbfrom, (*j)->GetOriginalBlackBoxFromOutput(), bbto, (*j)->GetOriginalBlackBoxToInput() ); //c->Check(); bbAddConnection(c); } bbAllocateConnectors(); bbtkBlackBoxDebugMessage("object",3, "<## ComplexBlackBox(\"" < ~ComplexBlackBox()" <bbDesallocateConnectors(); bbtkBlackBoxDebugMessage("object",3, "<== ~ComplexBlackBox()" < ComplexBlackBox::Clear()" < Releasing connections"< Releasing boxes"< ComplexBlackBox::bbAllocateConnectors()" <GetInputDescriptorMap(); BlackBoxDescriptor::InputDescriptorMapType::const_iterator i; for ( i = imap.begin(); i != imap.end(); ++i ) { bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<first<<"\""<second; // Get the internal box connector BlackBoxInputConnector* c = bbUnsafeGetBlackBox ( d->GetTarget() ) ->bbGetInputConnectorMap()[ d->GetInput() ]; bbGetInputConnectorMap()[i->second->GetName()] = c; } // Output connectors const BlackBoxDescriptor::OutputDescriptorMapType& omap = bbGetDescriptor()->GetOutputDescriptorMap(); BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; for ( o = omap.begin(); o != omap.end(); ++o ) { bbtkBlackBoxDebugMessage("kernel",8,"* Allocate \""<first<<"\""<second; // Get the internal box connector BlackBoxOutputConnector* c = bbUnsafeGetBlackBox ( d->GetTarget() ) ->bbGetOutputConnectorMap()[ d->GetOutput() ]; bbGetOutputConnectorMap()[o->second->GetName()] = c; } bbtkBlackBoxDebugMessage("kernel",8, "<== ComplexBlackBox::bbAllocateConnectors()" < ComplexBlackBox::DesallocateConnectors()" < ComplexBlackBox::bbClone(\""< ComplexBlackBox::bbExecute()" <::const_iterator i; for (i=mExecutionList.begin(); i!=mExecutionList.end(); ++i) { bbtkBlackBoxDebugMessage("process",3," -> Executing '"<<*i<<"'"<bbExecute(force); } } else { std::map::iterator i; for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i) { i->second->bbExecute(force); } } bbtkBlackBoxDebugMessage("process",2, "<** ComplexBlackBox::bbExecute()" <GetOutputDescriptor(name); Data p = bbGetBlackBox(d->GetTarget())->bbGetOutput(d->GetOutput()); return p; } //================================================================== //================================================================== /// Gets the input Data of a given name Data ComplexBlackBox::bbGetInput( const std::string &name ) { bbtkBlackBoxDebugMessage("data",7, "ComplexBlackBox::bbGetInput(\""<GetInputDescriptor(name); Data p = bbGetBlackBox(d->GetTarget())->bbGetInput(d->GetInput()); return p; } //================================================================== //================================================================== /// Sets the data of the output called void ComplexBlackBox::bbSetOutput( const std::string &name, Data data) { bbtkBlackBoxDebugMessage("data",7, "ComplexBlackBox::bbSetOutput(\""<GetOutputDescriptor(name); bbGetBlackBox(d->GetTarget())->bbSetOutput(d->GetOutput(),data); } //================================================================== //================================================================== /// Sets the data of the input called void ComplexBlackBox::bbSetInput( const std::string &name, Data data, bool setModified) { bbtkBlackBoxDebugMessage("data",7, "ComplexBlackBox::bbSetInput(\""<GetInputDescriptor(name); bbGetBlackBox(d->GetTarget())->bbSetInput(d->GetInput(),data,setModified); } //================================================================== //================================================================== /// Sets the data of the input called void ComplexBlackBox::bbBruteForceSetInputPointer( const std::string &name, void* data, bool setModified) { bbtkBlackBoxDebugMessage("data",7, "ComplexBlackBox::bbBruteForceSetInputPointer('" <GetInputDescriptor(name); bbGetBlackBox(d->GetTarget())->bbBruteForceSetInputPointer(d->GetInput(), data, setModified); } //================================================================== //========================================================================= /// Connects the input to the connection c void ComplexBlackBox::bbConnectInput( const std::string& name, Connection* c) { bbtkBlackBoxDebugMessage("connection",2, "==> ComplexBlackBox::bbConnectInput(\"" <GetFullName()<<")" <GetInputDescriptor(name); BlackBox::Pointer t = bbGetBlackBox(d->GetTarget()); bbtkBlackBoxDebugMessage("connection",2," - Target = "<GetTarget()<<" = "<bbGetFullName()<SetBlackBoxTo(t); c->SetBlackBoxToInput(d->GetInput()); bbtkBlackBoxDebugMessage("connection",2," - New conn = "<GetFullName()<bbConnectInput(d->GetInput(),c); bbtkBlackBoxDebugMessage("connection",2, "<== ComplexBlackBox::bbConnectInput(\"" <GetFullName()<<")" < to the connection c void ComplexBlackBox::bbConnectOutput( const std::string& name, Connection* c) { bbtkBlackBoxDebugMessage("connection",2, "==> ComplexBlackBox::bbConnectOutput(\"" <GetFullName()<<")" <GetOutputDescriptor(name); BlackBox::Pointer t = bbGetBlackBox(d->GetTarget()); bbtkBlackBoxDebugMessage("connection",2," - Target = "<GetTarget()<<" = "<bbGetFullName()<SetBlackBoxFrom(t); c->SetBlackBoxFromOutput(d->GetOutput()); bbtkBlackBoxDebugMessage("connection",2," - New conn = "<GetFullName()<bbConnectOutput(d->GetOutput(),c); bbtkBlackBoxDebugMessage("connection",2, "<== ComplexBlackBox::bbConnectOutput(\"" <GetFullName()<<")" <bbGetName() <<"\")" <bbGetName()) ) { bbtkError("a black box called \""<bbGetName() <<"\" already exists"); } b->bbSetParent(GetThisPointer()); mBlackBoxMap[b->bbGetName()] = b; } //================================================================== //================================================================== /// Adds the black box to the complex box (unsafe) void ComplexBlackBox::bbUnsafeAddBlackBox( BlackBox::Pointer b) { bbtkBlackBoxDebugMessage("kernel",7, "ComplexBlackBox::UnsafeAddBlackBox(\""<bbGetName() <<"\")" <bbSetParent(GetThisPointer()); mBlackBoxMap[b->bbGetName()] = b; } //================================================================== //================================================================== /// Removes the black box from the complex box void ComplexBlackBox::bbRemoveBlackBox( const std::string& name, bool remove_connections ) { bbtkBlackBoxDebugMessage("kernel",7, "ComplexBlackBox::RemoveBlackBox(\""<second; if (remove_connections) { ConnectionListType::const_iterator j; for ( j = mConnectionList.begin(); j != mConnectionList.end(); ++j ) { (*j)->Check(); } } if (p.use_count()!=1) { bbtkError("the black box \""< BlackBox::Pointer ComplexBlackBox::bbGetBlackBox( const std::string& name ) { bbtkBlackBoxDebugMessage("kernel",9, "ComplexBlackBox::GetBlackBox(\""<second; } //================================================================== //================================================================== /// Returns the black box with name : does not throw an exception /// if it does not exist but return a null pointer BlackBox::Pointer ComplexBlackBox::bbUnsafeGetBlackBox( const std::string& name ) { bbtkBlackBoxDebugMessage("kernel",9, "ComplexBlackBox::UnsafeGetBlackBox(\""<second; } //================================================================== //================================================================== void ComplexBlackBox::bbPrintBlackBoxes() { bbtkBlackBoxDebugMessage("kernel",9, "ComplexBlackBox::PrintBlackBoxes()" <second->bbGetFullName()<"); // Skip delimiters at beginning. std::string::size_type lastPos = blackboxname.find_first_not_of(delimiters, 0); // Find first "non-delimiter". std::string::size_type pos = blackboxname.find_first_of(delimiters, lastPos); // Found a token, add it to the vector. subname = blackboxname.substr(lastPos, pos - lastPos); restname = blackboxname.substr(lastPos+pos - lastPos+1, 999); if (restname==subname) { restname=""; } BlackBoxMapType::iterator i = mBlackBoxMap.find(subname); if ( i != mBlackBoxMap.end() ) { blackbox = i->second; if (restname!="") { blackbox = blackbox->bbFindBlackBox(restname); } } return blackbox; } //========================================================================= //========================================================================= void ComplexBlackBox::bbInsertHTMLGraph( std::ofstream& s, int detail, int level, bool instanceOrtype, const std::string& output_dir, bool relative_link ) { std::string directory(output_dir); if (output_dir.length() == 0) { // Don't pollute the file store with "temp_dir" directories ... std::string default_temp_dir = ConfigurationFile::GetInstance().Get_default_temp_dir(); directory = default_temp_dir + "/" + "temp_dir"; } std::string simplefilename (this->bbGetTypeName()+"_"+this->bbGetName()); std::string simplefilename_png (simplefilename+".png"); std::string filename (directory+"/"+simplefilename); std::string filename_png (filename+".png"); std::string filename_cmap (filename+".cmap"); std::string filename_dot (filename+".dot"); std::string filename_png2 ("\"" + filename_png + "\""); std::string filename_cmap2 ("\"" + filename_cmap + "\""); std::string filename_dot2 ("\"" + filename_dot + "\""); #ifdef WIN32 std::string currentexecpath("\"\"" + crea::System::GetDllAppPath("bbtk") +"\\dot_embedded\\dot\""); std::string command1 (currentexecpath + " -Tpng -o " + filename_png2 + " " + filename_dot2 + "\""); std::string command1a(currentexecpath + " -T cmap -o " + filename_cmap2 + " " + filename_dot2 + "\""); #else #ifdef APPLE std::string command1 ("dot -Tpng:quartz -o " + filename_png2 + " " + filename_dot2 ); std::string command1a("dot -T cmap -o " + filename_cmap2 + " " + filename_dot2 ); #else std::string command1 ("dot -Tpng:cairo -o " + filename_png2 + " " + filename_dot2 ); std::string command1a("dot -T cmap -o " + filename_cmap2 + " " + filename_dot2 ); #endif #endif // 1. Generating .dot file FILE *ff; ff = fopen(filename_dot.c_str(),"w"); fprintf(ff,"digraph bbtk_graph{\n"); fprintf(ff,"rankdir=LR%s\n",";"); fprintf(ff,"node [shape=record]%s\n",";"); this->bbWriteDotFileBlackBox(ff, GetThisPointer(), detail,level, instanceOrtype, relative_link ); fprintf(ff,"}\n"); fclose(ff); std::cout<<"JCP bbtkComplexBlackBox.cxx execute1="< png system( command1.c_str() ); // 3. Executing .dot file -> cmap std::cout<<"JCP bbtkComplexBlackBox.cxx execute2="<\"\"\n"; // 4.2 map (s) << "\n"; FILE *ff2; char c; ff2=fopen(filename_cmap.c_str(),"r"); if (ff2!=NULL){ while (!feof(ff2)) { c=fgetc(ff2); if (c!=-1) { (s) << c; } // if } // while } // if ff2 (s) << "\n\n"; // End } //========================================================================= //========================================================================= /// Write Graphviz-dot description in file void ComplexBlackBox::bbWriteDotFileBlackBox(FILE *ff, BlackBox::Pointer parentblackbox, int detail, int level, bool instanceOrtype, bool relative_link ) { std::string tmp1; std::string valueStr(""); Package::Pointer package = this->bbGetDescriptor()->GetPackage(); if (package!=NULL) { if (relative_link) tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL(); else tmp1 = this->bbGetDescriptor()->GetPackage()->GetDocURL(); } else { tmp1 = "Caspitas"; } std::string tmp2=bbGetTypeName(); std::string url(tmp1 + "#" + tmp2 ); fprintf( ff , "subgraph cluster_%s_%p {\n",bbGetName().c_str(),this); if (!( (bbGetTypeName()=="workspace") && (bbGetName()=="workspacePrototype")) ) { fprintf( ff , " URL = \"%s\" %s",url.c_str(),";"); } std::string boxname="["+bbGetTypeName()+"]"; if (GetThisPointer()!=parentblackbox) { if (detail==0) { boxname=bbGetName(); } else { boxname = bbGetName(); boxname = boxname + " [" +this->bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "]"; } } fprintf( ff , " label = \"%s\"%s\n", boxname.c_str() ,";"); // fprintf( ff , " style=filled%s\n",";"); // fprintf( ff , " color=grey%s\n",";"); fprintf( ff , " node [style=filled]%s\n",";"); fprintf( ff , " fillcolor=grey%s\n",";"); fprintf( ff , " edge [color=blue]%s\n",";"); // Labels Salida std::string labelStr1; std::string labelStr2; labelStr1 = boxname + "\\n(output)" ; labelStr2 = " | {{ "; bool tmp; tmp=false; OutputConnectorMapType::iterator i; const BlackBoxDescriptor::OutputDescriptorMapType& omap = this->bbGetDescriptor()->GetOutputDescriptorMap(); BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; for ( o = omap.begin(); o != omap.end(); ++o ) { if (tmp==true) { labelStr2=labelStr2+" | "; } tmp=true; if (instanceOrtype==true) { valueStr = this->bbGetOutputAsString(o->second->GetName()/* ,factory*/) + " = "; } labelStr2=labelStr2+"<"+o->second->GetName().c_str()+"> " + valueStr + o->second->GetName().c_str(); } labelStr2 = labelStr2+ " } }"; if (detail==1) { labelStr1 = labelStr1 + labelStr2; } if (tmp){ fprintf(ff," " ); bbWriteDotInputOutputName(ff,false,detail,level); fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" ); } // label Entrada labelStr1 = boxname + "\\n(input)" ; labelStr2 = " | {{ "; tmp=false; InputConnectorMapType::iterator ii; const BlackBoxDescriptor::InputDescriptorMapType& imap = this->bbGetDescriptor()->GetInputDescriptorMap(); BlackBoxDescriptor::InputDescriptorMapType::const_iterator iii; for ( iii = imap.begin(); iii != imap.end(); ++iii ) { if (tmp==true) { labelStr2=labelStr2+" | "; } tmp=true; if (instanceOrtype==true) { valueStr = this->bbGetInputAsString(iii->second->GetName()/*,factory*/) + " = "; } labelStr2=labelStr2+"<"+iii->second->GetName().c_str()+"> " + valueStr + iii->second->GetName().c_str(); } labelStr2 = labelStr2+ " } }"; if (detail==1) { labelStr1 = labelStr1 + labelStr2; } if (tmp){ fprintf(ff," " ); bbWriteDotInputOutputName(ff,true,detail,level); fprintf( ff , " [shape=record, style=filled,fillcolor=grey,color=red,label=\"%s\"]%s\n",labelStr1.c_str(),";" ); } // Body BlackBoxMapType::iterator j; for ( j = mBlackBoxMap.begin(); j != mBlackBoxMap.end(); ++j ) { if (level>-1) { j->second->bbWriteDotFileBlackBox(ff, parentblackbox, detail, level-1, instanceOrtype, relative_link); } } fprintf( ff , "}\n\n"); fprintf( ff , " edge[color=blue]%s\n",";"); if (level>-1) { // Relation Input with the inside BlackBox of the this ComplexBlackbox ComplexBlackBoxDescriptor::InputDescriptorMapType::iterator xx; ComplexBlackBoxDescriptor::InputDescriptorMapType idmt=bbGetDescriptor()->GetInputDescriptorMap(); for ( xx = idmt.begin(); xx != idmt.end(); ++xx ) { ComplexBlackBoxInputDescriptor *cbbid = (ComplexBlackBoxInputDescriptor*)xx->second; fprintf(ff," "); bbWriteDotInputOutputName(ff,true,detail,level); if (detail==1) { fprintf(ff,":%s",cbbid->GetName().c_str() ); } fprintf(ff,"->" ); BlackBox::Pointer bb = bbGetBlackBox( cbbid->GetTarget() ); bb->bbWriteDotInputOutputName(ff,true,detail,level); if (detail==1) { fprintf(ff,":%s \n", cbbid->GetInput().c_str() ); } }// for xx fprintf(ff,"\n \n"); // Relation Output ComplexBlackBox ComplexBlackBoxDescriptor::OutputDescriptorMapType::iterator yy; ComplexBlackBoxDescriptor::OutputDescriptorMapType odmt=bbGetDescriptor()->GetOutputDescriptorMap(); for ( yy = odmt.begin(); yy != odmt.end(); ++yy ) { ComplexBlackBoxOutputDescriptor *cbbod = (ComplexBlackBoxOutputDescriptor*)yy->second; fprintf(ff," "); BlackBox::Pointer bb = bbGetBlackBox( cbbod->GetTarget() ); bb->bbWriteDotInputOutputName(ff,false,detail,level); if (detail==1) { fprintf(ff,":%s", cbbod->GetOutput().c_str() ); } fprintf(ff,"->" ); bbWriteDotInputOutputName(ff,false,detail,level); if (detail==1) { fprintf(ff,":%s",cbbod->GetName().c_str() ); } fprintf(ff,"\n"); } // for yy } // if level // Relation from the out side of this ComplexBlackBox with its Inputs if (GetThisPointer()!=parentblackbox) { for ( ii = bbGetInputConnectorMap().begin(); ii != bbGetInputConnectorMap().end(); ++ii ) { if (ii->second) { Connection* con = ii->second->GetConnection(); if (con!=NULL){ BlackBox::Pointer a=con->GetOriginalBlackBoxFrom(); BlackBox::Pointer b=con->GetOriginalBlackBoxTo(); fprintf(ff," "); a->bbWriteDotInputOutputName(ff,false,detail,level); if (detail==1) { fprintf(ff,":%s",con->GetOriginalBlackBoxFromOutput().c_str()); } fprintf(ff,"->"); b->bbWriteDotInputOutputName(ff,true,detail,level); if (detail==1) { fprintf(ff,":%s",con->GetOriginalBlackBoxToInput().c_str()); } fprintf(ff,"%s\n",";"); } // if con } // if second } // for } // if parentblackbox } //========================================================================= /* //======================================================================= /// Generates the list of the packages of which its depends /// (cause an internal box belongs to it) void ComplexBlackBox::GetPackagesDependencies(std::vector& deps) { deps.clear; BlackBoxMapType::iterator i; for ( i = mBlackBoxMap.begin(); i != mBlackBoxMap.end(); ++i ) { deps.push_back(i->second->bbGetDescriptor()->GetPackage()); } } //======================================================================= */ //======================================================================= void ComplexBlackBox::Check(bool recursive) { bbtkMessage("debug",1,"**** Checking Complex Black Box "<<(void*)this <<" ["<second->Check(recursive); } ConnectionListType::const_iterator j; for ( j = mConnectionList.begin(); j != mConnectionList.end(); ++j ) { (*j)->Check(); } bbtkMessage("debug",1,"**** Checking Complex Black Box "<<(void*)this <<" ["<GetFullTypeName() + ":" + bbGetName(); } else { return std::string(":") + bbGetName(); } } //========================================================================= //========================================================================== std::string ComplexBlackBox::GetObjectName() const { return std::string("ComplexBlackBox '")+bbGetNameWithParent() +std::string("'"); } //========================================================================== //========================================================================== std::string ComplexBlackBox::GetObjectInfo() const { std::stringstream i; i << " - "<second->GetObjectRecursiveSize(); } ConnectionListType::const_iterator j; for ( j = mConnectionList.begin(); j != mConnectionList.end(); ++j ) { s += (*j)->GetObjectRecursiveSize(); } return s; } //========================================================================== }