/*========================================================================= Program: bbtk Module: $RCSfile: bbtkBlackBox.cxx,v $ Language: C++ Date: $Date: 2008/02/05 13:23:46 $ Version: $Revision: 1.2 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See doc/license.txt or http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /** * \file * \brief Class bbtk::BlackBox : abstract black-box interface. */ #include "bbtkBlackBox.h" #include "bbtkPackage.h" #include "bbtkMessageManager.h" #include "bbtkFactory.h" #include "bbtkConfigurationFile.h" #include "bbtkWxBlackBox.h" #include //#include namespace bbtk { //========================================================================= BlackBox::BlackBox(const std::string &name) : bbmName(name), bbmStatus(MODIFIED), bbmBoxProcessMode("Pipeline"),bbmParent(NULL) { bbtkDebugMessage("Kernel",7,"BlackBox::BlackBox(\"" <bbDesallocateConnectors(); //printf("EED BlackBox::~BlackBox 02 \n"); bbtkDebugDecTab("Kernel",7); } //========================================================================= //========================================================================= /// Destruction method of a black box void BlackBox::bbDelete() { bbtkDebugMessage("Kernel",5,"BlackBox::bbDelete() [" <bbUserDelete(); } //========================================================================= //========================================================================= /// Main processing method of the box. void BlackBox::bbExecute(bool force) { bbtkDebugMessageInc("Process",1, "=> BlackBox::bbExecute() [" < FreezeExecution global flag is 'true' : abort execution"<bbGetDescriptor()->GetTypeName()+">"; } //========================================================================= //========================================================================= /// Returns the name with the name of the parent prepended if any std::string BlackBox::bbGetNameWithParent() const { if (bbmParent) { return bbmParent->bbGetNameWithParent() + ":" + bbmName; } else { return bbmName; } } //========================================================================= //========================================================================= /// Prints the Help on the BlackBox type void BlackBox::bbGetHelp(bool full) const { bbGetDescriptor()->GetHelp(full); } //========================================================================= //========================================================================= /// Returns true if the UserBlackBox has an input of name name bool BlackBox::bbHasInput(const std::string& name) const { bbtkDebugMessageInc("Kernel",8, "BlackBox::bbHasInput(\"" <GetInputDescriptorMap().find(name) != bbGetDescriptor()->GetInputDescriptorMap().end()); bbtkDebugDecTab("Kernel",8); return r; } //========================================================================= //========================================================================= /// Returns true if the UserBlackBox has an output of name name bool BlackBox::bbHasOutput(const std::string& name) const { bbtkDebugMessageInc("Kernel",8,"BlackBox::bbHasOutput(\"" <GetOutputDescriptorMap().find(name) != bbGetDescriptor()->GetOutputDescriptorMap().end()); bbtkDebugDecTab("Kernel",8); return r; } //========================================================================= //========================================================================= /// Gets the output type of a given name TypeInfo BlackBox::bbGetOutputType( const std::string &name ) const { bbtkDebugMessageInc("Kernel",8, "BlackBox::bbGetOutputType(\"" <GetOutputDescriptor(name)->GetTypeInfo(); bbtkDebugDecTab("Kernel",8); return r; } //========================================================================= //========================================================================= /// Gets the input type of a given name TypeInfo BlackBox::bbGetInputType( const std::string &name ) const { bbtkDebugMessageInc("Kernel",8, "BlackBox::bbGetInputType(\"" <GetInputDescriptor(name)->GetTypeInfo(); bbtkDebugDecTab("Kernel",8); return r; } //========================================================================= //========================================================================= /// Allocates the i/o connectors of the black box void BlackBox::bbAllocateConnectors() { bbtkDebugMessageInc("Kernel",8, "BlackBox::bbAllocateConnectors() [" <GetInputDescriptorMap(); BlackBoxDescriptor::InputDescriptorMapType::const_iterator i; for ( i = imap.begin(); i != imap.end(); ++i ) { bbtkDebugMessage("Kernel",8,"* Allocate \""<first<<"\""<second->GetName()] = new BlackBoxInputConnector(this); } const BlackBoxDescriptor::OutputDescriptorMapType& omap = bbGetDescriptor()->GetOutputDescriptorMap(); BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; for ( o = omap.begin(); o != omap.end(); ++o ) { bbtkDebugMessage("Kernel",8,"* Allocate \""<first<<"\""<second->GetName()] = new BlackBoxOutputConnector(); } bbtkDebugDecTab("Kernel",8); } //========================================================================= //========================================================================= /// Desallocates the i/o connectors of the black box void BlackBox::bbDesallocateConnectors() { bbtkDebugMessageInc("Kernel",8, "BlackBox::bbDesallocateConnectors()" <first<<"\""<second); } OutputConnectorMapType::const_iterator o; for ( o = bbGetOutputConnectorMap().begin(); o != bbGetOutputConnectorMap().end(); ++o ) { bbtkDebugMessage("Kernel",8,"* Delete \""<first<<"\""<second); } bbtkDebugDecTab("Kernel",8); } //========================================================================= //========================================================================= /// Copies the input / output values from another box void BlackBox::bbCopyIOValues(BlackBox& from) { bbtkDebugMessageInc("Kernel",9, "BlackBox::bbCopyIOValues(" <GetInputDescriptorMap(); BlackBoxDescriptor::InputDescriptorMapType::const_iterator i; for ( i = imap.begin(); i != imap.end(); ++i ) { if (! i->second->GetCopyConstruct() ) continue; std::string input = i->second->GetName(); this->bbSetInput(input, from.bbGetInput(input) ); } // copies the output values const BlackBoxDescriptor::OutputDescriptorMapType& omap = bbGetDescriptor()->GetOutputDescriptorMap(); BlackBoxDescriptor::OutputDescriptorMapType::const_iterator o; for ( o = omap.begin(); o != omap.end(); ++o ) { if (! o->second->GetCopyConstruct() ) continue; std::string output = o->second->GetName(); this->bbSetOutput(output, from.bbGetOutput(output) ); } bbtkDebugDecTab("Kernel",9); } //========================================================================= //========================================================================= bool BlackBox::bbCanReact() const { return ( bbGlobalGetSomeBoxExecuting() #ifdef _USE_WXWIDGETS_ || WxBlackBox::bbGlobalIsSomeWindowAlive() #endif ); } //========================================================================= //========================================================================= /// User overloadable destruction method of a black box void BlackBox::bbUserDelete() { bbtkDebugMessage("Process",5, "=> BlackBox::bbUserDelete() [" < BlackBox::bbSetModifiedStatus("<second) ) // && (bbCanReact())) { bbtkDebugMessage("Process",9, "-> Hide triggered by WinHide input change" <bbHideWindow(); this->bbSetStatus(MODIFIED); return; } if ( ( bbBoxProcessModeIsReactive() || (c==bbGetInputConnectorMap().find("BoxExecute")->second)) && (bbCanReact() ) ) { bbtkDebugMessage("Process",9, "-> Execution triggered by Reactive mode or BoxExecute input change"<bbSetStatus(MODIFIED); bbGlobalAddToExecutionList( this ); } else if ( bbGetStatus() == MODIFIED ) //! this->bbIsUptodate()) { bbtkDebugMessage("Process",5,"-> Already modified"< Status set to modified"<bbSetStatus(MODIFIED); } this->bbSignalOutputModification(false); bbtkDebugMessageDec("Process",5, "<= BlackBox::bbSetModifiedStatus("< BlackBox::bbSignalOutputModification() [" <first == "BoxChange" ) { change = i; continue; } */ i->second->SetModifiedStatus(); } // if (change != bbGetOutputConnectorMap().end()) // change->second->SetModifiedStatus(); if (reaction) bbGlobalProcessExecutionList(); bbtkDebugMessageDec("Process",5, "<= BlackBox::bbSignalOutputModification() [" < BlackBox::bbSignalOutputModification(" <second->SetModifiedStatus(); // Has to notify the output "BoxChange" also if (output != "BoxChange") { i = bbGetOutputConnectorMap().find("BoxChange"); if ( i != bbGetOutputConnectorMap().end() ) { i->second->SetModifiedStatus(); } } if (reaction) bbGlobalProcessExecutionList(); bbtkDebugMessageDec("Process",5, "<= BlackBox::bbSignalOutputModification(" <& output, bool reaction) { bbtkDebugMessageInc("Process",5, "=> BlackBox::bbSignalOutputModification(vector of outputs) [" <::const_iterator o; for (o=output.begin();o!=output.end();++o) { // the output "BoxChange" must be signaled **AFTER** all others if (*o == "BoxChange") continue; // Look for the connector i = bbGetOutputConnectorMap().find(*o); if ( i == bbGetOutputConnectorMap().end() ) { bbtkError("BlackBox["<second->SetModifiedStatus(); } // Has to notify the output "BoxChange" also i = bbGetOutputConnectorMap().find("BoxChange"); if ( i != bbGetOutputConnectorMap().end() ) { i->second->SetModifiedStatus(); } if (reaction) bbGlobalProcessExecutionList(); bbtkDebugMessageDec("Process",5, "<= BlackBox::bbSignalOutputModification(vector of outputs) [" < BlackBox::bbUpdateInputs() [" <first=="WinParent")) continue; if (i->first=="WinHide") continue; // If input type is Void : no recurse //if ( bbGetDescriptor()->GetInputDescriptor(i->first)->GetTypeInfo() // == typeid(Void) ) // continue; IOStatus t = i->second->BackwardUpdate(); if (t==MODIFIED) s = MODIFIED; } bbtkDebugMessageDec("Process",4, "<= BlackBox::bbUpdateInputs() [" < to the connection c void BlackBox::bbConnectInput( const std::string& name, Connection* c) { bbtkDebugMessageInc("Kernel",7, "BlackBox::bbConnectInput(\""<second->SetConnection(c); // bbSetModifiedStatus(); bbtkDebugDecTab("Kernel",7); } //========================================================================= //========================================================================= /// Connects the output to the connection c void BlackBox::bbConnectOutput( const std::string& name, Connection* c) { bbtkDebugMessageInc("Kernel",7, "BlackBox::bbConnectOutput(\""<second->SetConnection(c); bbtkDebugDecTab("Kernel",7); } //========================================================================= //========================================================================= /// Disconnects the input from the connection c void BlackBox::bbDisconnectInput( const std::string& name, Connection* c) { bbtkDebugMessageInc("Kernel",7, "BlackBox::bbDisconnectInput(\""<second->UnsetConnection(c); bbtkDebugDecTab("Kernel",7); } //========================================================================= //========================================================================= /// Disconnects the output from the connection c void BlackBox::bbDisconnectOutput( const std::string& name, Connection* c) { bbtkDebugMessageInc("Kernel",7, "BlackBox::bbDisconnectOutput(\""<second->UnsetConnection(c); bbtkDebugDecTab("Kernel",7); } //========================================================================= //========================================================================= /// Virtual void BlackBox::bbWriteDotInputOutputName(FILE *ff,bool inputoutput,int detail, int level) { fprintf(ff,"%s%p",bbGetTypeName().c_str(),this); } //========================================================================= //========================================================================= std::string BlackBox::bbGetOutputAsString( const std::string &output ) { std::string v; // Looks for the adaptor if (bbGetOutputType(output).name() != typeid(std::string).name() ) { BlackBox* a = 0; try { a = NewAdaptor( bbGetOutputType(output), typeid(std::string), ""); } catch (bbtk::Exception e) { } if (a!=NULL){ // bbUpdate(); a->bbSetInput("In",bbGetOutput(output)); a->bbExecute(); v = a->bbGetOutput("Out").unsafe_get() ; } else { v="? (no adaptor found)"; } } else { // bbUpdate(); v = bbGetOutput(output).unsafe_get() ; } return v; } //========================================================================= //========================================================================= std::string BlackBox::bbGetInputAsString( const std::string &input ) { std::string v; // Looks for the adaptor if (bbGetInputType(input) != typeid(std::string)) { BlackBox* a = 0; try { a = NewAdaptor( bbGetInputType(input), typeid(std::string), ""); }catch (bbtk::Exception e) { } if (a!=NULL) { // bbUpdate(); a->bbSetInput("In",bbGetInput(input)); a->bbExecute(); v = a->bbGetOutput("Out").unsafe_get() ; } else { v="? (no adaptor found)"; } } else { v = bbGetInput(input).unsafe_get() ; } return v; } //======================================================================= //======================================================================= // Replaces substrings "<" by "[" void SubsBrackets ( std::string& s ) { // std::cout << "BEFORE=["<bbGetDescriptor()->GetPackage()->GetName()+"::"+ bbGetTypeName() + "] "; } SubsBrackets(labelStr); if (detail==1) { labelStr = labelStr + " | {{ "; std::string tempStrTypeName; bool tmp; tmp=false; for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) { if (tmp==true) { labelStr=labelStr+" | "; } tmp=true; if (instanceOrtype==true) { valueStr = this->bbGetInputAsString(i->first) + " = "; } const BlackBoxInputDescriptor* id = bbGetDescriptor()->GetInputDescriptor(i->first); tempStrTypeName=id->GetTypeName(); SubsBrackets(tempStrTypeName); std::string Name(i->first); SubsBrackets(Name); labelStr=labelStr + "<"+i->first.c_str()+"> " + valueStr + Name.c_str() + " [" + tempStrTypeName.c_str() + "]"; } labelStr=labelStr+ " } | {"; tmp = false; OutputConnectorMapType::iterator ii; for ( ii = mOutputConnectorMap.begin(); ii != mOutputConnectorMap.end(); ++ii ) { if (tmp==true) { labelStr=labelStr+" | "; } tmp = true; if (instanceOrtype==true) { valueStr = this->bbGetOutputAsString(ii->first) + " = "; } const BlackBoxOutputDescriptor* id = bbGetDescriptor()->GetOutputDescriptor(ii->first); tempStrTypeName=id->GetTypeName(); SubsBrackets(tempStrTypeName); std::string Name(ii->first); SubsBrackets(Name); labelStr=labelStr+"<"+ii->first.c_str()+"> " + valueStr + Name.c_str() + " ["+tempStrTypeName+"]"; } labelStr = labelStr+ " } }" ; } // detail fprintf(ff," " ); bbWriteDotInputOutputName(ff,true,detail,level); std::string tmp ( bbGetTypeName() ); SubsBrackets(tmp); std::string url; if (relative_link) url = this->bbGetDescriptor()->GetPackage()->GetDocRelativeURL() + "#" + tmp; else url = this->bbGetDescriptor()->GetPackage()->GetDocURL() + "#" + tmp; fprintf( ff , " [shape=record, URL=\"%s\",label=\"%s\"]%s\n",url.c_str(),labelStr.c_str(),";" ); // std::cout << labelStr << std::endl; // Relation Input if (this!=parentblackbox){ for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) { if (i->second) { Connection* con = i->second->GetConnection(); if (con!=NULL){ BlackBox *a=con->GetBlackBoxFrom(); BlackBox *b=con->GetBlackBoxTo(); fprintf(ff," "); a->bbWriteDotInputOutputName(ff,false,detail,level); if (detail==1) { fprintf(ff,":%s",con->GetBlackBoxFromOutput().c_str()); } fprintf(ff,"->"); b->bbWriteDotInputOutputName(ff,true,detail,level); if (detail==1) { fprintf(ff,":%s",con->GetBlackBoxToInput().c_str()); } fprintf(ff,"%s\n",";"); } // if con } // if second } // for } // if parentblackbox } //========================================================================= //========================================================================= void BlackBox::bbShowRelations(BlackBox *parentblackbox, int detail, int level /*,Factory *factory*/ ) { if (this->bbGetDescriptor()->GetPackage()) { bbtkMessage("Help",1,"Black Box '"<bbGetDescriptor()->GetPackage()->GetName() <<"::"<bbGetDescriptor()->GetTypeName()<<">"<bbGetDescriptor()->GetTypeName()<<">"< iname; std::vector ivalue; std::vector iconn; InputConnectorMapType::iterator i; unsigned int namelmax = 0; unsigned int valuelmax = 0; unsigned int connlmax = 0; for ( i = mInputConnectorMap.begin(); i != mInputConnectorMap.end(); ++i ) { iname.push_back(i->first); if (iname.back().size()>namelmax) namelmax = iname.back().size(); ivalue.push_back(bbGetInputAsString(i->first)); if (ivalue.back().size()>valuelmax) valuelmax = ivalue.back().size(); std::string s(""); Connection* con = i->second->GetConnection(); if (con!=0){ s = con->GetBlackBoxFrom()->bbGetName(); s += "."; s += con->GetBlackBoxFromOutput(); } // if con iconn.push_back(s); } OutputConnectorMapType::iterator o; std::vector oname; std::vector ovalue; std::vector > oconn; for ( o = mOutputConnectorMap.begin(); o != mOutputConnectorMap.end(); ++o ) { oname.push_back(o->first); if (oname.back().size()>namelmax) namelmax = oname.back().size(); ovalue.push_back(bbGetOutputAsString(o->first)); if (ovalue.back().size()>valuelmax) valuelmax = ovalue.back().size(); std::vector ss; const std::vector& con = o->second->GetConnectionVector(); std::vector::const_iterator c; for (c=con.begin();c!=con.end();++c) { std::string s; s = (*c)->GetBlackBoxTo()->bbGetName(); s += "."; s += (*c)->GetBlackBoxToInput(); ss.push_back(s); } // if con oconn.push_back(ss); } if (iname.size()) bbtkMessage("Help",1," * Inputs : "<::iterator i1,i2,i3; for (i1=iname.begin(),i2=ivalue.begin(),i3=iconn.begin(); i1!=iname.end(),i2!=ivalue.end(),i3!=iconn.end(); ++i1,++i2,++i3) { std::string name(*i1); name += "'"; name.append(1+namelmax-name.size(),' '); std::string value(*i2); value += "'"; value.append(1+valuelmax-value.size(),' '); if (i3->size()) bbtkMessage("Help",1," '"< BlackBox::bbGlobalProcessExecutionList()" <::iterator i; for (i=bbmgExecutionList.begin(); i!=bbmgExecutionList.end(); ++i) { bbtkDebugMessage("Process",2, " -> Executing "<<(*i)->bbGetFullName()<bbExecute(true); } bbmgExecutionList.clear(); bbtkDebugMessageDec("Process",1, "<= BlackBox::bbGlobalProcessExecutionList()" < BlackBox::bbmgExecutionList; //========================================================================= } // EO namespace bbtk // EOF