X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FcpPlugins%2FWorkspaceIO.cxx;fp=lib%2FcpPlugins%2FWorkspaceIO.cxx;h=b9c15582f102c20f862eeaa6d6a823fe8ddf98dc;hb=201c5026430f9bcc33f9db6a39f5d03db096c860;hp=0000000000000000000000000000000000000000;hpb=aa77db36cc1d87ba014c982a235239c3c87224f3;p=cpPlugins.git diff --git a/lib/cpPlugins/WorkspaceIO.cxx b/lib/cpPlugins/WorkspaceIO.cxx new file mode 100644 index 0000000..b9c1558 --- /dev/null +++ b/lib/cpPlugins/WorkspaceIO.cxx @@ -0,0 +1,251 @@ +#include +#include + +// ------------------------------------------------------------------------- +std::string cpPlugins::Workspace:: +LoadWorkspace( const std::string& fname ) +{ + if( this->m_Interface == NULL ) + return( "cpPlugins::Workspace: No valid plugins interface" ); + tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( ); + doc->LoadFile( fname.c_str( ) ); + tinyxml2::XMLElement* root = doc->RootElement( ); + if( root == NULL ) + return( "cpPlugins::Workspace: No valid file" ); + if( std::string( root->Value( ) ) != "cpPlugins_Workspace" ) + return( "cpPlugins::Workspace: No valid workspace" ); + std::stringstream err; + + // Load plugins + auto loaded_plugins = this->m_Interface->GetPlugins( ); + tinyxml2::XMLElement* plugins = root->FirstChildElement( "plugins" ); + std::string plugins_errors = ""; + while( plugins != NULL ) + { + tinyxml2::XMLElement* plugin = plugins->FirstChildElement( "plugin" ); + while( plugin != NULL ) + { + std::string name = plugin->Attribute( "name" ); + if( loaded_plugins.find( name ) == loaded_plugins.end( ) ) + { + try + { + this->m_Interface->LoadPlugin( name ); + } + catch( std::exception& err ) + { + plugins_errors += err.what( ) + std::string( "\n" ); + + } // yrt + + } // fi + plugin = plugin->NextSiblingElement( "plugin" ); + + } // elihw + plugins = plugins->NextSiblingElement( "plugins" ); + + } // elihw + if( plugins_errors != "" ) + return( std::string( "cpPlugins::Workspace: " ) + plugins_errors ); + + // Read filters + tinyxml2::XMLElement* filter = root->FirstChildElement( "filter" ); + while( filter != NULL ) + { + 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_re_execution = 0; + filter->QueryIntAttribute( + "ExplicitReExecution", &explicit_re_execution + ); + if( class_value != NULL && name_value != NULL ) + { + if( this->CreateFilter( category_value, class_value, name_value ) ) + { + auto new_filter = this->GetFilter( name_value ); + new_filter->SetViewCoords( viewX, viewY ); + new_filter->SetExplicitReExecution( explicit_re_execution == 1 ); + + // Read parameters + auto parameters = new_filter->GetParameters( ); + parameters->FromXML( filter ); + } + else + err + << "No valid class \"" << class_value << "\" with name \"" + << name_value << "\"" << std::endl; + } + else + err << "Incomplete data." << std::endl; + filter = filter->NextSiblingElement( "filter" ); + + } // elihw + + // Read connections + tinyxml2::XMLElement* connection = root->FirstChildElement( "connection" ); + while( connection != NULL ) + { + 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" ); + if( + orig_filter != NULL && dest_filter != NULL && + orig_name != NULL && dest_name != NULL + ) + this->Connect( orig_filter, dest_filter, orig_name, dest_name ); + + } // fi + connection = connection->NextSiblingElement( "connection" ); + + } // elihw + + // Read exposed inputs + tinyxml2::XMLElement* port = root->FirstChildElement( "exposed_input_port" ); + while( port != NULL ) + { + this->ExposeInputPort( + port->Attribute( "port_name" ), + port->Attribute( "filter" ), + port->Attribute( "filter_port_name" ) + ); + port = port->NextSiblingElement( "exposed_input_port" ); + + } // elihw + + // Read exposed outputs + port = root->FirstChildElement( "exposed_output_port" ); + while( port != NULL ) + { + this->ExposeOutputPort( + port->Attribute( "port_name" ), + port->Attribute( "filter" ), + port->Attribute( "filter_port_name" ) + ); + port = port->NextSiblingElement( "exposed_output_port" ); + + } // elihw + + // Finish and return + delete doc; + return( err.str( ) ); +} + +// ------------------------------------------------------------------------- +std::string cpPlugins::Workspace:: +SaveWorkspace( const std::string& fname ) const +{ + std::stringstream err; + tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( ); + tinyxml2::XMLElement* root = doc->NewElement( "cpPlugins_Workspace" ); + std::set< std::string > used_plugins; + + // Save vertices + auto vIt = this->m_Graph->BeginVertices( ); + for( ; vIt != this->m_Graph->EndVertices( ); ++vIt ) + { + auto filter = dynamic_cast< ProcessObject* >( vIt->second.GetPointer( ) ); + auto data = dynamic_cast< DataObject* >( vIt->second.GetPointer( ) ); + if( filter != NULL ) + { + used_plugins.insert( filter->GetPluginName( ) ); + + tinyxml2::XMLElement* e = doc->NewElement( "filter" ); + e->SetAttribute( "category", filter->GetClassCategory( ) ); + e->SetAttribute( "class", filter->GetClassName( ) ); + e->SetAttribute( "name", vIt->first.c_str( ) ); + e->SetAttribute( "ViewX", filter->GetViewX( ) ); + e->SetAttribute( "ViewY", filter->GetViewY( ) ); + e->SetAttribute( + "ExplicitReExecution", ( filter->GetExplicitReExecution( ) )? 1: 0 + ); + + auto params = filter->GetParameters( ); + params->ToXML( doc, e ); + root->LinkEndChild( e ); + } + else if( data != NULL ) + { + // TODO + } // fi + + } // 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 + auto mIt = this->m_Graph->BeginEdgesRows( ); + for( ; mIt != this->m_Graph->EndEdgesRows( ); ++mIt ) + { + auto rIt = mIt->second.begin( ); + for( ; rIt != mIt->second.end( ); ++rIt ) + { + auto eIt = rIt->second.begin( ); + for( ; eIt != rIt->second.end( ); ++eIt ) + { + tinyxml2::XMLElement* conn = doc->NewElement( "connection" ); + tinyxml2::XMLElement* orig = doc->NewElement( "origin" ); + tinyxml2::XMLElement* dest = doc->NewElement( "destination" ); + orig->SetAttribute( "filter", mIt->first.c_str( ) ); + orig->SetAttribute( "name", eIt->first.c_str( ) ); + dest->SetAttribute( "filter", rIt->first.c_str( ) ); + dest->SetAttribute( "name", eIt->second.c_str( ) ); + + conn->LinkEndChild( orig ); + conn->LinkEndChild( dest ); + root->LinkEndChild( conn ); + + } // rof + + } // rof + + } // rof + + // Save exposed ports + auto eipIt = this->m_ExposedInputPorts.begin( ); + for( ; eipIt != this->m_ExposedInputPorts.end( ); ++eipIt ) + { + tinyxml2::XMLElement* port = doc->NewElement( "exposed_input_port" ); + port->SetAttribute( "port_name", eipIt->first.c_str( ) ); + port->SetAttribute( "filter", eipIt->second.first.c_str( ) ); + port->SetAttribute( "filter_port_name", eipIt->second.second.c_str( ) ); + root->LinkEndChild( port ); + + } // rof + + auto eopIt = this->m_ExposedOutputPorts.begin( ); + for( ; eopIt != this->m_ExposedOutputPorts.end( ); ++eopIt ) + { + tinyxml2::XMLElement* port = doc->NewElement( "exposed_output_port" ); + port->SetAttribute( "port_name", eopIt->first.c_str( ) ); + port->SetAttribute( "filter", eopIt->second.first.c_str( ) ); + port->SetAttribute( "filter_port_name", eopIt->second.second.c_str( ) ); + root->LinkEndChild( port ); + + } // rof + + // Physical write and return + doc->LinkEndChild( root ); + doc->SaveFile( fname.c_str( ) ); + delete doc; + return( err.str( ) ); +} + +// eof - $RCSfile$