#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 ); 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 ); // 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( this->m_Interface->GetPluginName( filter ) ); 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( ) ); 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$