1 #include <cpPlugins/Interface/Workspace.h>
2 #include <tinyxml2/tinyxml2.h>
4 // -------------------------------------------------------------------------
5 void cpPlugins::Interface::Workspace::
6 Load( const std::string& fname )
9 TInterface::Pointer interface = TInterface::New( );
12 tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
13 doc->LoadFile( fname.c_str( ) );
14 tinyxml2::XMLElement* root = doc->RootElement( );
18 throw std::runtime_error( "cpPlugins::Workspace: No valid file" );
21 if( std::string( root->Value( ) ) != "cpPlugins_Workspace" )
24 throw std::runtime_error( "cpPlugins::Workspace: Not a valid workspace" );
29 auto loaded_plugins = interface->GetPlugins( );
30 tinyxml2::XMLElement* plugins = root->FirstChildElement( "Plugins" );
31 std::string plugins_errors = "";
32 while( plugins != NULL )
34 tinyxml2::XMLElement* plugin = plugins->FirstChildElement( "Plugin" );
35 while( plugin != NULL )
37 std::string name = plugin->Attribute( "Name" );
38 if( loaded_plugins.find( name ) == loaded_plugins.end( ) )
42 interface->LoadPlugin( name );
44 catch( std::exception& err )
46 plugins_errors += err.what( ) + std::string( "\n" );
51 plugin = plugin->NextSiblingElement( "Plugin" );
54 plugins = plugins->NextSiblingElement( "Plugins" );
57 if( plugins_errors != "" )
60 throw std::runtime_error(
61 std::string( "cpPlugins::Workspace: " ) + plugins_errors
67 std::stringstream err;
68 tinyxml2::XMLElement* filter = root->FirstChildElement( "Filter" );
69 while( filter != NULL )
71 const char* category_value = filter->Attribute( "Category" );
72 const char* class_value = filter->Attribute( "Class" );
73 const char* name_value = filter->Attribute( "Name" );
74 float viewX = float( 0 ), viewY = float( 0 );
75 filter->QueryFloatAttribute( "ViewX", &viewX );
76 filter->QueryFloatAttribute( "ViewY", &viewY );
77 int explicit_execution = 0;
78 filter->QueryIntAttribute(
79 "ExplicitExecution", &explicit_execution
81 if( class_value != NULL && name_value != NULL )
84 this->CreateFilter( category_value, class_value, name_value );
85 if( new_filter != NULL )
87 new_filter->SetViewCoords( viewX, viewY );
88 new_filter->SetExplicitExecution( explicit_execution == 1 );
89 new_filter->GetParameters( )->FromXML( filter );
93 << "No valid class \"" << class_value << "\" with name \""
94 << name_value << "\"" << std::endl;
97 err << "Incomplete data." << std::endl;
98 filter = filter->NextSiblingElement( "Filter" );
103 tinyxml2::XMLElement* connection = root->FirstChildElement( "Connection" );
104 while( connection != NULL )
106 tinyxml2::XMLElement* orig = connection->FirstChildElement( "Origin" );
107 tinyxml2::XMLElement* dest = connection->FirstChildElement( "Destination" );
108 if( orig != NULL && dest != NULL )
110 const char* orig_filter = orig->Attribute( "Filter" );
111 const char* dest_filter = dest->Attribute( "Filter" );
112 const char* orig_name = orig->Attribute( "Name" );
113 const char* dest_name = dest->Attribute( "Name" );
115 orig_filter != NULL && dest_filter != NULL &&
116 orig_name != NULL && dest_name != NULL
121 this->Connect( orig_filter, dest_filter, orig_name, dest_name );
123 catch( std::exception& exc )
125 err << exc.what( ) << std::endl;
132 connection = connection->NextSiblingElement( "Connection" );
136 // Read exposed inputs
137 tinyxml2::XMLElement* port = root->FirstChildElement( "ExposedInput" );
138 while( port != NULL )
141 port->Attribute( "Name" ),
142 port->Attribute( "Filter" ),
143 port->Attribute( "Input" )
145 port = port->NextSiblingElement( "ExposedInput" );
149 // Read exposed outputs
150 port = root->FirstChildElement( "ExposedOutput" );
151 while( port != NULL )
154 port->Attribute( "Name" ),
155 port->Attribute( "Filter" ),
156 port->Attribute( "Output" )
158 port = port->NextSiblingElement( "ExposedOutput" );
163 std::string err_str = err.str( );
167 throw std::runtime_error(
168 std::string( "cpPlugins::Workspace " ) + err_str
177 // -------------------------------------------------------------------------
178 void cpPlugins::Interface::Workspace::
179 Save( const std::string& fname ) const
181 tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
182 tinyxml2::XMLElement* root = doc->NewElement( "cpPlugins_Workspace" );
183 std::set< std::string > used_plugins;
186 for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i )
188 auto filter = i->second;
189 used_plugins.insert( filter->GetPluginName( ) );
190 tinyxml2::XMLElement* e = doc->NewElement( "Filter" );
191 e->SetAttribute( "Category", filter->GetClassCategory( ) );
192 e->SetAttribute( "Class", filter->GetClassName( ) );
193 e->SetAttribute( "Name", filter->GetName( ) );
194 e->SetAttribute( "ViewX", filter->GetViewX( ) );
195 e->SetAttribute( "ViewY", filter->GetViewY( ) );
197 "ExplicitExecution", ( filter->GetExplicitExecution( ) )? 1: 0
200 auto params = filter->GetParameters( );
201 params->ToXML( doc, e );
202 root->LinkEndChild( e );
207 tinyxml2::XMLElement* plugins = doc->NewElement( "Plugins" );
208 for( auto pIt = used_plugins.begin( ); pIt != used_plugins.end( ); ++pIt )
210 tinyxml2::XMLElement* e = doc->NewElement( "Plugin" );
211 e->SetAttribute( "Name", pIt->c_str( ) );
212 plugins->LinkEndChild( e );
215 root->LinkEndChild( plugins );
218 for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i )
220 auto orig = i->second;
221 auto outputs = orig->GetOutputsNames( );
222 if( outputs.size( ) == 0 )
224 for( auto j = this->m_Filters.begin( ); j != this->m_Filters.end( ); ++j )
228 auto dest = j->second;
229 auto inputs = dest->GetInputsNames( );
230 if( inputs.size( ) == 0 )
233 for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
235 auto od = orig->GetOutput( *oIt );
236 for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
238 auto id = dest->GetInput( *iIt );
239 if( od != NULL && od == id )
241 tinyxml2::XMLElement* e_conn = doc->NewElement( "Connection" );
242 tinyxml2::XMLElement* e_orig = doc->NewElement( "Origin" );
243 tinyxml2::XMLElement* e_dest = doc->NewElement( "Destination" );
244 e_orig->SetAttribute( "Filter", orig->GetName( ) );
245 e_orig->SetAttribute( "Name", oIt->c_str( ) );
246 e_dest->SetAttribute( "Filter", dest->GetName( ) );
247 e_dest->SetAttribute( "Name", iIt->c_str( ) );
248 e_conn->LinkEndChild( e_orig );
249 e_conn->LinkEndChild( e_dest );
250 root->LinkEndChild( e_conn );
263 // Save exposed ports
264 auto eipIt = this->m_ExposedInputs.begin( );
265 for( ; eipIt != this->m_ExposedInputs.end( ); ++eipIt )
267 tinyxml2::XMLElement* port = doc->NewElement( "ExposedInput" );
268 port->SetAttribute( "Name", eipIt->first.c_str( ) );
269 port->SetAttribute( "Filter", eipIt->second.first.c_str( ) );
270 port->SetAttribute( "Input", eipIt->second.second.c_str( ) );
271 root->LinkEndChild( port );
275 auto eopIt = this->m_ExposedOutputs.begin( );
276 for( ; eopIt != this->m_ExposedOutputs.end( ); ++eopIt )
278 tinyxml2::XMLElement* port = doc->NewElement( "ExposedOutput" );
279 port->SetAttribute( "Name", eopIt->first.c_str( ) );
280 port->SetAttribute( "Filter", eopIt->second.first.c_str( ) );
281 port->SetAttribute( "Output", eopIt->second.second.c_str( ) );
282 root->LinkEndChild( port );
286 // Physical write and return
287 doc->LinkEndChild( root );
288 auto error = doc->SaveFile( fname.c_str( ) );
290 if( error != tinyxml2::XML_SUCCESS )
295 case tinyxml2::XML_NO_ATTRIBUTE:
296 m = "No attribute."; break;
297 case tinyxml2::XML_WRONG_ATTRIBUTE_TYPE:
298 m = "Wrong attribute."; break;
299 case tinyxml2::XML_ERROR_FILE_NOT_FOUND:
300 m = "File not found."; break;
301 case tinyxml2::XML_ERROR_FILE_COULD_NOT_BE_OPENED:
302 m = "File not opened."; break;
303 case tinyxml2::XML_ERROR_FILE_READ_ERROR:
304 m = "File not read."; break;
305 case tinyxml2::XML_ERROR_ELEMENT_MISMATCH:
306 m = "Element mismatch."; break;
307 case tinyxml2::XML_ERROR_PARSING_ELEMENT:
308 m = "Parsing element."; break;
309 case tinyxml2::XML_ERROR_PARSING_ATTRIBUTE:
310 m = "Parsing attribute."; break;
311 case tinyxml2::XML_ERROR_IDENTIFYING_TAG:
312 m = "Tag Id."; break;
313 case tinyxml2::XML_ERROR_PARSING_TEXT:
314 m = "Parsing text."; break;
315 case tinyxml2::XML_ERROR_PARSING_CDATA:
316 m = "Parsing cdata."; break;
317 case tinyxml2::XML_ERROR_PARSING_COMMENT:
318 m = "Parsing comment."; break;
319 case tinyxml2::XML_ERROR_PARSING_DECLARATION:
320 m = "Parsing declaration."; break;
321 case tinyxml2::XML_ERROR_PARSING_UNKNOWN:
322 m = "Parsing unknown."; break;
323 case tinyxml2::XML_ERROR_EMPTY_DOCUMENT:
324 m = "Empty document."; break;
325 case tinyxml2::XML_ERROR_MISMATCHED_ELEMENT:
326 m = "Mismatched element."; break;
327 case tinyxml2::XML_ERROR_PARSING:
328 m = "Parsing."; break;
329 case tinyxml2::XML_CAN_NOT_CONVERT_TEXT:
330 m = "Cannot convert."; break;
331 case tinyxml2::XML_NO_TEXT_NODE:
332 m = "No text."; break;
334 m = "Unknown error."; break;
336 throw std::runtime_error(
337 std::string( "cpPlugins::Workspace: Error while saving \"" ) +
338 fname + std::string( "\": " ) + m