1 #include <cpPlugins/Interface/Workspace.h>
2 #include <tinyxml2/tinyxml2.h>
4 // -------------------------------------------------------------------------
5 void cpPlugins::Interface::Workspace::
6 Load( const std::string& fname )
11 tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
12 doc->LoadFile( fname.c_str( ) );
13 tinyxml2::XMLElement* root = doc->RootElement( );
17 throw std::runtime_error( "cpPlugins::Workspace: No valid file" );
20 if( std::string( root->Value( ) ) != "cpPlugins_Workspace" )
23 throw std::runtime_error( "cpPlugins::Workspace: Not a valid workspace" );
28 std::stringstream err;
29 tinyxml2::XMLElement* filter = root->FirstChildElement( "Filter" );
30 while( filter != NULL )
32 const char* category_value = filter->Attribute( "Category" );
33 const char* class_value = filter->Attribute( "Class" );
34 const char* name_value = filter->Attribute( "Name" );
35 float viewX = float( 0 ), viewY = float( 0 );
36 filter->QueryFloatAttribute( "ViewX", &viewX );
37 filter->QueryFloatAttribute( "ViewY", &viewY );
38 int explicit_execution = 0;
39 filter->QueryIntAttribute(
40 "ExplicitExecution", &explicit_execution
42 if( class_value != NULL && name_value != NULL )
44 auto new_filter = this->CreateFilter( category_value, class_value );
45 if( new_filter != NULL )
47 this->RenameFilter( new_filter->GetName( ), name_value );
48 new_filter->SetViewCoords( viewX, viewY );
49 new_filter->SetExplicitExecution( explicit_execution == 1 );
50 new_filter->GetParameters( )->FromXML( filter );
54 << "No valid class \"" << class_value << "\" with name \""
55 << name_value << "\"" << std::endl;
58 err << "Incomplete data." << std::endl;
59 filter = filter->NextSiblingElement( "Filter" );
64 tinyxml2::XMLElement* connection = root->FirstChildElement( "Connection" );
65 while( connection != NULL )
67 tinyxml2::XMLElement* orig = connection->FirstChildElement( "Origin" );
68 tinyxml2::XMLElement* dest = connection->FirstChildElement( "Destination" );
69 if( orig != NULL && dest != NULL )
71 const char* orig_filter = orig->Attribute( "Filter" );
72 const char* dest_filter = dest->Attribute( "Filter" );
73 const char* orig_name = orig->Attribute( "Name" );
74 const char* dest_name = dest->Attribute( "Name" );
76 orig_filter != NULL && dest_filter != NULL &&
77 orig_name != NULL && dest_name != NULL
82 this->Connect( orig_filter, orig_name, dest_filter, dest_name );
84 catch( std::exception& exc )
86 err << exc.what( ) << std::endl;
93 connection = connection->NextSiblingElement( "Connection" );
97 // Read exposed inputs
99 tinyxml2::XMLElement* port = root->FirstChildElement( "ExposedInput" );
100 while( port != NULL )
103 port->Attribute( "Name" ),
104 port->Attribute( "Filter" ),
105 port->Attribute( "Input" )
107 port = port->NextSiblingElement( "ExposedInput" );
111 // Read exposed outputs
112 port = root->FirstChildElement( "ExposedOutput" );
113 while( port != NULL )
116 port->Attribute( "Name" ),
117 port->Attribute( "Filter" ),
118 port->Attribute( "Output" )
120 port = port->NextSiblingElement( "ExposedOutput" );
126 std::string err_str = err.str( );
130 throw std::runtime_error(
131 std::string( "cpPlugins::Workspace " ) + err_str
140 // -------------------------------------------------------------------------
141 void cpPlugins::Interface::Workspace::
142 Save( const std::string& fname ) const
144 tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
145 tinyxml2::XMLElement* root = doc->NewElement( "cpPlugins_Workspace" );
146 std::set< std::string > used_plugins;
149 for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i )
151 auto filter = i->second;
152 used_plugins.insert( filter->GetPluginName( ) );
153 tinyxml2::XMLElement* e = doc->NewElement( "Filter" );
154 e->SetAttribute( "Category", filter->GetClassCategory( ) );
155 e->SetAttribute( "Class", filter->GetClassName( ) );
156 e->SetAttribute( "Name", filter->GetName( ) );
157 e->SetAttribute( "ViewX", filter->GetViewX( ) );
158 e->SetAttribute( "ViewY", filter->GetViewY( ) );
160 "ExplicitExecution", ( filter->GetExplicitExecution( ) )? 1: 0
163 auto params = filter->GetParameters( );
164 params->ToXML( doc, e );
165 root->LinkEndChild( e );
171 tinyxml2::XMLElement* plugins = doc->NewElement( "Plugins" );
172 for( auto pIt = used_plugins.begin( ); pIt != used_plugins.end( ); ++pIt )
174 tinyxml2::XMLElement* e = doc->NewElement( "Plugin" );
175 e->SetAttribute( "Name", pIt->c_str( ) );
176 plugins->LinkEndChild( e );
179 root->LinkEndChild( plugins );
183 for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i )
185 auto orig = i->second;
186 auto outputs = orig->GetOutputsNames( );
187 if( outputs.size( ) == 0 )
189 for( auto j = this->m_Filters.begin( ); j != this->m_Filters.end( ); ++j )
193 auto dest = j->second;
194 auto inputs = dest->GetInputsNames( );
195 if( inputs.size( ) == 0 )
198 for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
200 auto od = orig->GetOutput( *oIt );
201 for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
203 unsigned int nInputs = dest->GetInputSize( *iIt );
204 for( unsigned int k = 0; k < nInputs; ++k )
206 auto id = dest->GetInput( *iIt, k );
207 if( od != NULL && od == id )
209 tinyxml2::XMLElement* e_conn = doc->NewElement( "Connection" );
210 tinyxml2::XMLElement* e_orig = doc->NewElement( "Origin" );
211 tinyxml2::XMLElement* e_dest = doc->NewElement( "Destination" );
212 e_orig->SetAttribute( "Filter", orig->GetName( ) );
213 e_orig->SetAttribute( "Name", oIt->c_str( ) );
214 e_dest->SetAttribute( "Filter", dest->GetName( ) );
215 e_dest->SetAttribute( "Name", iIt->c_str( ) );
216 e_conn->LinkEndChild( e_orig );
217 e_conn->LinkEndChild( e_dest );
218 root->LinkEndChild( e_conn );
232 // Save exposed ports
234 auto eipIt = this->m_ExposedInputs.begin( );
235 for( ; eipIt != this->m_ExposedInputs.end( ); ++eipIt )
237 tinyxml2::XMLElement* port = doc->NewElement( "ExposedInput" );
238 port->SetAttribute( "Name", eipIt->first.c_str( ) );
239 port->SetAttribute( "Filter", eipIt->second.first.c_str( ) );
240 port->SetAttribute( "Input", eipIt->second.second.c_str( ) );
241 root->LinkEndChild( port );
245 auto eopIt = this->m_ExposedOutputs.begin( );
246 for( ; eopIt != this->m_ExposedOutputs.end( ); ++eopIt )
248 tinyxml2::XMLElement* port = doc->NewElement( "ExposedOutput" );
249 port->SetAttribute( "Name", eopIt->first.c_str( ) );
250 port->SetAttribute( "Filter", eopIt->second.first.c_str( ) );
251 port->SetAttribute( "Output", eopIt->second.second.c_str( ) );
252 root->LinkEndChild( port );
257 // Physical write and return
258 doc->LinkEndChild( root );
259 auto error = doc->SaveFile( fname.c_str( ) );
261 if( error != tinyxml2::XML_SUCCESS )
266 case tinyxml2::XML_NO_ATTRIBUTE:
267 m = "No attribute."; break;
268 case tinyxml2::XML_WRONG_ATTRIBUTE_TYPE:
269 m = "Wrong attribute."; break;
270 case tinyxml2::XML_ERROR_FILE_NOT_FOUND:
271 m = "File not found."; break;
272 case tinyxml2::XML_ERROR_FILE_COULD_NOT_BE_OPENED:
273 m = "File not opened."; break;
274 case tinyxml2::XML_ERROR_FILE_READ_ERROR:
275 m = "File not read."; break;
276 case tinyxml2::XML_ERROR_ELEMENT_MISMATCH:
277 m = "Element mismatch."; break;
278 case tinyxml2::XML_ERROR_PARSING_ELEMENT:
279 m = "Parsing element."; break;
280 case tinyxml2::XML_ERROR_PARSING_ATTRIBUTE:
281 m = "Parsing attribute."; break;
282 case tinyxml2::XML_ERROR_IDENTIFYING_TAG:
283 m = "Tag Id."; break;
284 case tinyxml2::XML_ERROR_PARSING_TEXT:
285 m = "Parsing text."; break;
286 case tinyxml2::XML_ERROR_PARSING_CDATA:
287 m = "Parsing cdata."; break;
288 case tinyxml2::XML_ERROR_PARSING_COMMENT:
289 m = "Parsing comment."; break;
290 case tinyxml2::XML_ERROR_PARSING_DECLARATION:
291 m = "Parsing declaration."; break;
292 case tinyxml2::XML_ERROR_PARSING_UNKNOWN:
293 m = "Parsing unknown."; break;
294 case tinyxml2::XML_ERROR_EMPTY_DOCUMENT:
295 m = "Empty document."; break;
296 case tinyxml2::XML_ERROR_MISMATCHED_ELEMENT:
297 m = "Mismatched element."; break;
298 case tinyxml2::XML_ERROR_PARSING:
299 m = "Parsing."; break;
300 case tinyxml2::XML_CAN_NOT_CONVERT_TEXT:
301 m = "Cannot convert."; break;
302 case tinyxml2::XML_NO_TEXT_NODE:
303 m = "No text."; break;
305 m = "Unknown error."; break;
307 throw std::runtime_error(
308 std::string( "cpPlugins::Workspace: Error while saving \"" ) +
309 fname + std::string( "\": " ) + m