X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FcpPlugins%2FInterface%2FWorkspaceIO.cxx;h=029ade420b79aa60ce57a8ca49fc491d16a5783e;hb=bfc16201a35d40fb90f8a354307dca5942fc0fcd;hp=0651011389400e09b01604fc174c82d9275e1125;hpb=f654620df52b811be7bd263a1775c93d29c69a65;p=cpPlugins.git diff --git a/lib/cpPlugins/Interface/WorkspaceIO.cxx b/lib/cpPlugins/Interface/WorkspaceIO.cxx index 0651011..029ade4 100644 --- a/lib/cpPlugins/Interface/WorkspaceIO.cxx +++ b/lib/cpPlugins/Interface/WorkspaceIO.cxx @@ -1,194 +1,92 @@ #include -#include +#include // ------------------------------------------------------------------------- -std::string cpPlugins::Interface::Workspace:: -LoadWorkspace( const std::string& fname ) +void cpPlugins::Interface::Workspace:: +Load( const std::string& fname ) { - TiXmlDocument* doc = new TiXmlDocument( fname.c_str( ) ); - doc->LoadFile( ); - TiXmlElement* root = doc->RootElement( ); - if( std::string( root->Value( ) ) != "cpPlugins_Workspace" ) - return( "cpPlugins::Interface::Workspace: No valid workspace" ); - std::stringstream err; + this->Clear( ); + TInterface::Pointer interface = TInterface::New( ); - // Read plugins files - TiXmlElement* plugins = root->FirstChildElement( "plugins" ); - while( plugins != NULL ) + // Read from disk + tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( ); + doc->LoadFile( fname.c_str( ) ); + tinyxml2::XMLElement* root = doc->RootElement( ); + if( root == NULL ) { - const char* value = plugins->Attribute( "filename" ); - if( value != NULL ) - { - if( !( this->LoadPlugins( value ) ) ) - err << "no valid plugins file \"" << value << "\"" << std::endl; + delete doc; + throw std::runtime_error( "cpPlugins::Workspace: No valid file" ); - } // fi - plugins = plugins->NextSiblingElement( "plugins" ); + } // fi + if( std::string( root->Value( ) ) != "cpPlugins_Workspace" ) + { + delete doc; + throw std::runtime_error( "cpPlugins::Workspace: Not a valid workspace" ); - } // elihw + } // fi - // Read plugins paths - plugins = root->FirstChildElement( "plugins_dir" ); + // Load plugins + auto loaded_plugins = interface->GetPlugins( ); + tinyxml2::XMLElement* plugins = root->FirstChildElement( "Plugins" ); + std::string plugins_errors = ""; while( plugins != NULL ) { - const char* value = plugins->Attribute( "path" ); - if( value != NULL ) + tinyxml2::XMLElement* plugin = plugins->FirstChildElement( "Plugin" ); + while( plugin != NULL ) { - int recursive; - if( plugins->QueryIntAttribute( "recursive", &recursive ) != TIXML_SUCCESS ) - recursive = 0; - if( !( this->LoadPluginsPath( value, recursive == 1 ) ) ) - err << "No valid plugins path \"" << value << "\"" << std::endl; + std::string name = plugin->Attribute( "Name" ); + if( loaded_plugins.find( name ) == loaded_plugins.end( ) ) + { + try + { + interface->LoadPlugin( name ); + } + catch( std::exception& err ) + { + plugins_errors += err.what( ) + std::string( "\n" ); - } // fi - plugins = plugins->NextSiblingElement( "plugins_dir" ); + } // yrt + + } // fi + plugin = plugin->NextSiblingElement( "Plugin" ); + + } // elihw + plugins = plugins->NextSiblingElement( "Plugins" ); } // elihw + if( plugins_errors != "" ) + { + delete doc; + throw std::runtime_error( + std::string( "cpPlugins::Workspace: " ) + plugins_errors + ); + + } // fi // Read filters - TiXmlElement* filter = root->FirstChildElement( "filter" ); + std::stringstream err; + tinyxml2::XMLElement* filter = root->FirstChildElement( "Filter" ); while( filter != NULL ) { - const char* class_value = filter->Attribute( "class" ); - const char* name_value = filter->Attribute( "name" ); + const char* category_value = filter->Attribute( "Category" ); + const char* class_value = filter->Attribute( "Class" ); + const char* name_value = filter->Attribute( "Name" ); + float viewX = float( 0 ), viewY = float( 0 ); + filter->QueryFloatAttribute( "ViewX", &viewX ); + filter->QueryFloatAttribute( "ViewY", &viewY ); + int explicit_execution = 0; + filter->QueryIntAttribute( + "ExplicitExecution", &explicit_execution + ); if( class_value != NULL && name_value != NULL ) { - if( this->CreateFilter( class_value, name_value ) ) + auto new_filter = + this->CreateFilter( category_value, class_value, name_value ); + if( new_filter != NULL ) { - // Read parameters - TParameters* parameters = this->GetParameters( name_value ); - TiXmlElement* param = filter->FirstChildElement( "parameter" ); - while( param != NULL ) - { - const char* param_name = param->Attribute( "name" ); - const char* param_type = param->Attribute( "type" ); - if( param_name != NULL && param_type != NULL ) - { - std::string param_type_str( param_type ); - const char* value = param->Attribute( "value" ); - if( value != NULL ) - { - std::istringstream value_str( value ); - if( param_type_str == "String" ) - parameters->SetString( param_name, value ); - else if( param_type_str == "Bool" ) - parameters->SetBool( param_name, value[ 0 ] != '0' ); - else if( param_type_str == "Int" ) - { - TParameters::TInt v; - value_str >> v; - parameters->SetInt( param_name, v ); - } - else if( param_type_str == "Uint" ) - { - TParameters::TUint v; - value_str >> v; - parameters->SetUint( param_name, v ); - } - else if( param_type_str == "Real" ) - { - TParameters::TReal v; - value_str >> v; - parameters->SetReal( param_name, v ); - } - /* TODO - else if( param_type_str == "Index" ) - else if( param_type_str == "Point" ) - else if( param_type_str == "Vector" ) - */ - } - else - { - if( param_type_str == "StringList" ) - { - TiXmlElement* item = param->FirstChildElement( "item" ); - while( item != NULL ) - { - value = item->Attribute( "value" ); - if( value != NULL ) - parameters->AddToStringList( param_name, value ); - item = item->NextSiblingElement( "item" ); - - } // elihw - } - else if( param_type_str == "BoolList" ) - { - TiXmlElement* item = param->FirstChildElement( "item" ); - while( item != NULL ) - { - value = item->Attribute( "value" ); - if( value != NULL ) - parameters->AddToBoolList( param_name, value[ 0 ] != '0' ); - item = item->NextSiblingElement( "item" ); - - } // elihw - } - else if( param_type_str == "IntList" ) - { - TiXmlElement* item = param->FirstChildElement( "item" ); - while( item != NULL ) - { - value = item->Attribute( "value" ); - if( value != NULL ) - { - std::istringstream value_str( value ); - TParameters::TInt v; - value_str >> v; - parameters->AddToIntList( param_name, v ); - - } // fi - item = item->NextSiblingElement( "item" ); - - } // elihw - } - else if( param_type_str == "UintList" ) - { - TiXmlElement* item = param->FirstChildElement( "item" ); - while( item != NULL ) - { - value = item->Attribute( "value" ); - if( value != NULL ) - { - std::istringstream value_str( value ); - TParameters::TUint v; - value_str >> v; - parameters->AddToUintList( param_name, v ); - - } // fi - item = item->NextSiblingElement( "item" ); - - } // elihw - } - else if( param_type_str == "RealList" ) - { - TiXmlElement* item = param->FirstChildElement( "item" ); - while( item != NULL ) - { - value = item->Attribute( "value" ); - if( value != NULL ) - { - std::istringstream value_str( value ); - TParameters::TReal v; - value_str >> v; - parameters->AddToRealList( param_name, v ); - - } // fi - item = item->NextSiblingElement( "item" ); - - } // elihw - } - /* TODO - else if( param_type_str == "IndexList" ) - else if( param_type_str == "PointList" ) - else if( param_type_str == "VectorList" ) - else if( param_type_str == "Choices" ); - */ - } // fi - - } // fi - param = param->NextSiblingElement( "parameter" ); - - } // elihw + new_filter->SetViewCoords( viewX, viewY ); + new_filter->SetExplicitExecution( explicit_execution == 1 ); + new_filter->GetParameters( )->FromXML( filter ); } else err @@ -197,43 +95,250 @@ LoadWorkspace( const std::string& fname ) } else err << "Incomplete data." << std::endl; - filter = filter->NextSiblingElement( "filter" ); + filter = filter->NextSiblingElement( "Filter" ); } // elihw - // Read filters - TiXmlElement* connection = root->FirstChildElement( "connection" ); + // Read connections + tinyxml2::XMLElement* connection = root->FirstChildElement( "Connection" ); while( connection != NULL ) { - TiXmlElement* orig = connection->FirstChildElement( "origin" ); - TiXmlElement* dest = connection->FirstChildElement( "destination" ); + tinyxml2::XMLElement* orig = connection->FirstChildElement( "Origin" ); + tinyxml2::XMLElement* dest = connection->FirstChildElement( "Destination" ); if( orig != NULL && dest != NULL ) { - const char* orig_filter = orig->Attribute( "filter" ); - const char* dest_filter = dest->Attribute( "filter" ); - const char* orig_name = orig->Attribute( "name" ); - const char* dest_name = dest->Attribute( "name" ); + const char* orig_filter = orig->Attribute( "Filter" ); + const char* dest_filter = dest->Attribute( "Filter" ); + const char* orig_name = orig->Attribute( "Name" ); + const char* dest_name = dest->Attribute( "Name" ); if( orig_filter != NULL && dest_filter != NULL && orig_name != NULL && dest_name != NULL ) - this->Connect( orig_filter, dest_filter, orig_name, dest_name ); + { + try + { + this->Connect( orig_filter, dest_filter, orig_name, dest_name ); + } + catch( std::exception& exc ) + { + err << exc.what( ) << std::endl; + + } // yrt + + } // fi } // fi - connection = connection->NextSiblingElement( "connection" ); + connection = connection->NextSiblingElement( "Connection" ); + + } // elihw + + // Read exposed inputs + tinyxml2::XMLElement* port = root->FirstChildElement( "ExposedInput" ); + while( port != NULL ) + { + this->ExposeInput( + port->Attribute( "Name" ), + port->Attribute( "Filter" ), + port->Attribute( "Input" ) + ); + port = port->NextSiblingElement( "ExposedInput" ); + + } // elihw + + // Read exposed outputs + port = root->FirstChildElement( "ExposedOutput" ); + while( port != NULL ) + { + this->ExposeOutput( + port->Attribute( "Name" ), + port->Attribute( "Filter" ), + port->Attribute( "Output" ) + ); + port = port->NextSiblingElement( "ExposedOutput" ); } // elihw - // Finish and return + // Throw errors + std::string err_str = err.str( ); + if( err_str != "" ) + { + delete doc; + throw std::runtime_error( + std::string( "cpPlugins::Workspace " ) + err_str + ); + + } // fi + + // Finish delete doc; - return( err.str( ) ); } // ------------------------------------------------------------------------- -std::string cpPlugins::Interface::Workspace:: -SaveWorkspace( const std::string& fname ) const +void cpPlugins::Interface::Workspace:: +Save( const std::string& fname ) const { - return( "" ); + tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( ); + tinyxml2::XMLElement* root = doc->NewElement( "cpPlugins_Workspace" ); + std::set< std::string > used_plugins; + + // Save filter data + for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i ) + { + auto filter = i->second; + used_plugins.insert( filter->GetPluginName( ) ); + tinyxml2::XMLElement* e = doc->NewElement( "Filter" ); + e->SetAttribute( "Category", filter->GetClassCategory( ) ); + e->SetAttribute( "Class", filter->GetClassName( ) ); + e->SetAttribute( "Name", filter->GetName( ) ); + e->SetAttribute( "ViewX", filter->GetViewX( ) ); + e->SetAttribute( "ViewY", filter->GetViewY( ) ); + e->SetAttribute( + "ExplicitExecution", ( filter->GetExplicitExecution( ) )? 1: 0 + ); + + auto params = filter->GetParameters( ); + params->ToXML( doc, e ); + root->LinkEndChild( e ); + + } // rof + + // Save used plugins + tinyxml2::XMLElement* plugins = doc->NewElement( "Plugins" ); + for( auto pIt = used_plugins.begin( ); pIt != used_plugins.end( ); ++pIt ) + { + tinyxml2::XMLElement* e = doc->NewElement( "Plugin" ); + e->SetAttribute( "Name", pIt->c_str( ) ); + plugins->LinkEndChild( e ); + + } // rof + root->LinkEndChild( plugins ); + + // Save connections + for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i ) + { + auto orig = i->second; + auto outputs = orig->GetOutputsNames( ); + if( outputs.size( ) == 0 ) + continue; + for( auto j = this->m_Filters.begin( ); j != this->m_Filters.end( ); ++j ) + { + if( i == j ) + continue; + auto dest = j->second; + auto inputs = dest->GetInputsNames( ); + if( inputs.size( ) == 0 ) + continue; + + for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt ) + { + auto od = orig->GetOutput( *oIt ); + for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt ) + { + auto id = dest->GetInput( *iIt ); + if( od != NULL && od == id ) + { + tinyxml2::XMLElement* e_conn = doc->NewElement( "Connection" ); + tinyxml2::XMLElement* e_orig = doc->NewElement( "Origin" ); + tinyxml2::XMLElement* e_dest = doc->NewElement( "Destination" ); + e_orig->SetAttribute( "Filter", orig->GetName( ) ); + e_orig->SetAttribute( "Name", oIt->c_str( ) ); + e_dest->SetAttribute( "Filter", dest->GetName( ) ); + e_dest->SetAttribute( "Name", iIt->c_str( ) ); + e_conn->LinkEndChild( e_orig ); + e_conn->LinkEndChild( e_dest ); + root->LinkEndChild( e_conn ); + + } // fi + + } // rof + + } // rof + + } // rof + + } // rof + + + // Save exposed ports + auto eipIt = this->m_ExposedInputs.begin( ); + for( ; eipIt != this->m_ExposedInputs.end( ); ++eipIt ) + { + tinyxml2::XMLElement* port = doc->NewElement( "ExposedInput" ); + port->SetAttribute( "Name", eipIt->first.c_str( ) ); + port->SetAttribute( "Filter", eipIt->second.first.c_str( ) ); + port->SetAttribute( "Input", eipIt->second.second.c_str( ) ); + root->LinkEndChild( port ); + + } // rof + + auto eopIt = this->m_ExposedOutputs.begin( ); + for( ; eopIt != this->m_ExposedOutputs.end( ); ++eopIt ) + { + tinyxml2::XMLElement* port = doc->NewElement( "ExposedOutput" ); + port->SetAttribute( "Name", eopIt->first.c_str( ) ); + port->SetAttribute( "Filter", eopIt->second.first.c_str( ) ); + port->SetAttribute( "Output", eopIt->second.second.c_str( ) ); + root->LinkEndChild( port ); + + } // rof + + // Physical write and return + doc->LinkEndChild( root ); + auto error = doc->SaveFile( fname.c_str( ) ); + delete doc; + if( error != tinyxml2::XML_SUCCESS ) + { + std::string m; + switch( error ) + { + case tinyxml2::XML_NO_ATTRIBUTE: + m = "No attribute."; break; + case tinyxml2::XML_WRONG_ATTRIBUTE_TYPE: + m = "Wrong attribute."; break; + case tinyxml2::XML_ERROR_FILE_NOT_FOUND: + m = "File not found."; break; + case tinyxml2::XML_ERROR_FILE_COULD_NOT_BE_OPENED: + m = "File not opened."; break; + case tinyxml2::XML_ERROR_FILE_READ_ERROR: + m = "File not read."; break; + case tinyxml2::XML_ERROR_ELEMENT_MISMATCH: + m = "Element mismatch."; break; + case tinyxml2::XML_ERROR_PARSING_ELEMENT: + m = "Parsing element."; break; + case tinyxml2::XML_ERROR_PARSING_ATTRIBUTE: + m = "Parsing attribute."; break; + case tinyxml2::XML_ERROR_IDENTIFYING_TAG: + m = "Tag Id."; break; + case tinyxml2::XML_ERROR_PARSING_TEXT: + m = "Parsing text."; break; + case tinyxml2::XML_ERROR_PARSING_CDATA: + m = "Parsing cdata."; break; + case tinyxml2::XML_ERROR_PARSING_COMMENT: + m = "Parsing comment."; break; + case tinyxml2::XML_ERROR_PARSING_DECLARATION: + m = "Parsing declaration."; break; + case tinyxml2::XML_ERROR_PARSING_UNKNOWN: + m = "Parsing unknown."; break; + case tinyxml2::XML_ERROR_EMPTY_DOCUMENT: + m = "Empty document."; break; + case tinyxml2::XML_ERROR_MISMATCHED_ELEMENT: + m = "Mismatched element."; break; + case tinyxml2::XML_ERROR_PARSING: + m = "Parsing."; break; + case tinyxml2::XML_CAN_NOT_CONVERT_TEXT: + m = "Cannot convert."; break; + case tinyxml2::XML_NO_TEXT_NODE: + m = "No text."; break; + default: + m = "Unknown error."; break; + } // hctiws + throw std::runtime_error( + std::string( "cpPlugins::Workspace: Error while saving \"" ) + + fname + std::string( "\": " ) + m + ); + + } // fi } // eof - $RCSfile$