#include #include // ------------------------------------------------------------------------- void cpPlugins::Interface::Workspace:: Load( const std::string& fname ) { this->Clear( ); // Read from disk tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( ); doc->LoadFile( fname.c_str( ) ); tinyxml2::XMLElement* root = doc->RootElement( ); if( root == NULL ) { delete doc; throw std::runtime_error( "cpPlugins::Workspace: No valid file" ); } // fi if( std::string( root->Value( ) ) != "cpPlugins_Workspace" ) { delete doc; throw std::runtime_error( "cpPlugins::Workspace: Not a valid workspace" ); } // fi // Read filters std::stringstream err; 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_execution = 0; filter->QueryIntAttribute( "ExplicitExecution", &explicit_execution ); if( class_value != NULL && name_value != NULL ) { auto new_filter = this->CreateFilter( category_value, class_value ); if( new_filter != NULL ) { this->RenameFilter( new_filter->GetName( ), name_value ); new_filter->SetViewCoords( viewX, viewY ); new_filter->SetExplicitExecution( explicit_execution == 1 ); new_filter->GetParameters( )->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 ) { try { this->Connect( orig_filter, orig_name, dest_filter, dest_name ); } catch( std::exception& exc ) { err << exc.what( ) << std::endl; } // yrt } // fi } // fi connection = connection->NextSiblingElement( "Connection" ); } // elihw // Read exposed inputs /* TODO 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 */ // 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; } // ------------------------------------------------------------------------- void cpPlugins::Interface::Workspace:: Save( const std::string& fname ) const { 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 /* TODO 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 ) { unsigned int nInputs = dest->GetInputSize( *iIt ); for( unsigned int k = 0; k < nInputs; ++k ) { auto id = dest->GetInput( *iIt, k ); 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 } // rof // Save exposed ports /* TODO 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$